protected MethodNode addClassUnderTestMethod( ClassNode classNode, ClassExpression targetClass, String type) { String methodName = "setup" + type + "UnderTest"; String fieldName = GrailsNameUtils.getPropertyName(type); String getterName = GrailsNameUtils.getGetterName(fieldName); fieldName = '$' + fieldName; if (classNode.getField(fieldName) == null) { classNode.addField(fieldName, Modifier.PRIVATE, targetClass.getType(), null); } MethodNode methodNode = classNode.getMethod(methodName, GrailsArtefactClassInjector.ZERO_PARAMETERS); VariableExpression fieldExpression = new VariableExpression(fieldName); if (methodNode == null) { BlockStatement setupMethodBody = new BlockStatement(); addMockCollaborator(type, targetClass, setupMethodBody); methodNode = new MethodNode( methodName, Modifier.PUBLIC, ClassHelper.VOID_TYPE, GrailsArtefactClassInjector.ZERO_PARAMETERS, null, setupMethodBody); methodNode.addAnnotation(BEFORE_ANNOTATION); methodNode.addAnnotation(MIXIN_METHOD_ANNOTATION); classNode.addMethod(methodNode); } MethodNode getter = classNode.getMethod(getterName, GrailsArtefactClassInjector.ZERO_PARAMETERS); if (getter == null) { BlockStatement getterBody = new BlockStatement(); getter = new MethodNode( getterName, Modifier.PUBLIC, targetClass.getType().getPlainNodeReference(), GrailsArtefactClassInjector.ZERO_PARAMETERS, null, getterBody); BinaryExpression testTargetAssignment = new BinaryExpression( fieldExpression, ASSIGN, new ConstructorCallExpression( targetClass.getType(), GrailsArtefactClassInjector.ZERO_ARGS)); IfStatement autowiringIfStatement = getAutowiringIfStatement(targetClass, fieldExpression, testTargetAssignment); getterBody.addStatement(autowiringIfStatement); getterBody.addStatement(new ReturnStatement(fieldExpression)); classNode.addMethod(getter); } return methodNode; }
private Set<String> getPropertyNamesToIncludeInWhiteList( final SourceUnit sourceUnit, final ClassNode classNode) { if (CLASS_NAME_TO_WHITE_LIST_PROPERTY_NAMES.containsKey(classNode)) { return CLASS_NAME_TO_WHITE_LIST_PROPERTY_NAMES.get(classNode); } final Set<String> propertyNamesToIncludeInWhiteList = new HashSet<String>(); final Set<String> unbindablePropertyNames = new HashSet<String>(); final Set<String> bindablePropertyNames = new HashSet<String>(); if (!classNode.getSuperClass().equals(new ClassNode(Object.class))) { final Set<String> parentClassPropertyNames = getPropertyNamesToIncludeInWhiteList(sourceUnit, classNode.getSuperClass()); bindablePropertyNames.addAll(parentClassPropertyNames); } final FieldNode constraintsFieldNode = classNode.getDeclaredField(CONSTRAINTS_FIELD_NAME); if (constraintsFieldNode != null && constraintsFieldNode.hasInitialExpression()) { final Expression constraintsInitialExpression = constraintsFieldNode.getInitialExpression(); if (constraintsInitialExpression instanceof ClosureExpression) { final Map<String, Map<String, Expression>> constraintsInfo = GrailsASTUtils.getConstraintMetadata((ClosureExpression) constraintsInitialExpression); for (Entry<String, Map<String, Expression>> constraintConfig : constraintsInfo.entrySet()) { final String propertyName = constraintConfig.getKey(); final Map<String, Expression> mapEntryExpressions = constraintConfig.getValue(); for (Entry<String, Expression> entry : mapEntryExpressions.entrySet()) { final String constraintName = entry.getKey(); if (BINDABLE_CONSTRAINT_NAME.equals(constraintName)) { final Expression valueExpression = entry.getValue(); Boolean bindableValue = null; if (valueExpression instanceof ConstantExpression) { final Object constantValue = ((ConstantExpression) valueExpression).getValue(); if (constantValue instanceof Boolean) { bindableValue = (Boolean) constantValue; } } if (bindableValue != null) { if (Boolean.TRUE.equals(bindableValue)) { unbindablePropertyNames.remove(propertyName); bindablePropertyNames.add(propertyName); } else { bindablePropertyNames.remove(propertyName); unbindablePropertyNames.add(propertyName); } } else { final String message = "The bindable constraint for property [" + propertyName + "] in class [" + classNode.getName() + "] has a value which is not a boolean literal and will be ignored."; GrailsASTUtils.warning(sourceUnit, valueExpression, message); } } } } } } final Set<String> fieldsInTransientsList = getPropertyNamesExpressedInTransientsList(classNode); propertyNamesToIncludeInWhiteList.addAll(bindablePropertyNames); final List<FieldNode> fields = classNode.getFields(); for (FieldNode fieldNode : fields) { final String fieldName = fieldNode.getName(); if ((!unbindablePropertyNames.contains(fieldName)) && (bindablePropertyNames.contains(fieldName) || shouldFieldBeInWhiteList(fieldNode, fieldsInTransientsList))) { propertyNamesToIncludeInWhiteList.add(fieldName); } } final Map<String, MethodNode> declaredMethodsMap = classNode.getDeclaredMethodsMap(); for (Entry<String, MethodNode> methodEntry : declaredMethodsMap.entrySet()) { final MethodNode value = methodEntry.getValue(); if (value.getDeclaringClass() == classNode) { Parameter[] parameters = value.getParameters(); if (parameters != null && parameters.length == 1) { final String methodName = value.getName(); if (methodName.startsWith("set")) { final Parameter parameter = parameters[0]; final ClassNode paramType = parameter.getType(); if (!paramType.equals(new ClassNode(Object.class))) { final String restOfMethodName = methodName.substring(3); final String propertyName = GrailsNameUtils.getPropertyName(restOfMethodName); if (!unbindablePropertyNames.contains(propertyName)) { propertyNamesToIncludeInWhiteList.add(propertyName); } } } } } } CLASS_NAME_TO_WHITE_LIST_PROPERTY_NAMES.put(classNode, propertyNamesToIncludeInWhiteList); Map<String, ClassNode> allAssociationMap = GrailsASTUtils.getAllAssociationMap(classNode); for (String associationName : allAssociationMap.keySet()) { if (!propertyNamesToIncludeInWhiteList.contains(associationName)) { propertyNamesToIncludeInWhiteList.add(associationName); } } return propertyNamesToIncludeInWhiteList; }