private void autoAnnotateSetupTeardown(ClassNode classNode) { MethodNode setupMethod = classNode.getMethod(SET_UP_METHOD, GrailsArtefactClassInjector.ZERO_PARAMETERS); if (setupMethod != null && setupMethod.getAnnotations(BEFORE_CLASS_NODE).size() == 0) { setupMethod.addAnnotation(BEFORE_ANNOTATION); } MethodNode tearDown = classNode.getMethod(TEAR_DOWN_METHOD, GrailsArtefactClassInjector.ZERO_PARAMETERS); if (tearDown != null && tearDown.getAnnotations(AFTER_CLASS_NODE).size() == 0) { tearDown.addAnnotation(AFTER_ANNOTATION); } }
/** * Main entry point for the calling the TestForTransformation programmatically. * * @param classNode The class node that represents th test * @param ce The class expression that represents the class to test */ public void testFor(ClassNode classNode, ClassExpression ce) { boolean junit3Test = isJunit3Test(classNode); // make sure the 'log' property is not the one from GroovyTestCase FieldNode log = classNode.getField("log"); if (log == null || log.getDeclaringClass().equals(GROOVY_TEST_CASE_CLASS)) { LoggingTransformer.addLogField(classNode, classNode.getName()); } boolean isSpockTest = isSpockTest(classNode); if (!isSpockTest && !junit3Test) { // assume JUnit 4 Map<String, MethodNode> declaredMethodsMap = classNode.getDeclaredMethodsMap(); for (String methodName : declaredMethodsMap.keySet()) { MethodNode methodNode = declaredMethodsMap.get(methodName); if (isCandidateMethod(methodNode) && methodNode.getName().startsWith("test")) { if (methodNode.getAnnotations().size() == 0) { methodNode.addAnnotation(TEST_ANNOTATION); } } } } final MethodNode methodToAdd = weaveMock(classNode, ce, true); if (methodToAdd != null && junit3Test) { addMethodCallsToMethod(classNode, SET_UP_METHOD, Arrays.asList(methodToAdd)); } }
/** * Adds a delegate method to the target class node where the first argument is to the delegate * method is 'this'. In other words a method such as foo(Object instance, String bar) would be * added with a signature of foo(String) and 'this' is passed to the delegate instance * * @param classNode The class node * @param delegate The expression that looks up the delegate * @param declaredMethod The declared method * @param thisAsFirstArgument Whether 'this' should be passed as the first argument to the method * @return The added method node or null if it couldn't be added */ public static MethodNode addDelegateInstanceMethod( ClassNode classNode, Expression delegate, MethodNode declaredMethod, boolean thisAsFirstArgument) { Parameter[] parameterTypes = thisAsFirstArgument ? getRemainingParameterTypes(declaredMethod.getParameters()) : declaredMethod.getParameters(); String methodName = declaredMethod.getName(); if (classNode.hasDeclaredMethod(methodName, parameterTypes)) { return null; } String propertyName = GrailsClassUtils.getPropertyForGetter(methodName); if (propertyName != null && parameterTypes.length == 0 && classNode.hasProperty(propertyName)) { return null; } propertyName = GrailsClassUtils.getPropertyForSetter(methodName); if (propertyName != null && parameterTypes.length == 1 && classNode.hasProperty(propertyName)) { return null; } BlockStatement methodBody = new BlockStatement(); ArgumentListExpression arguments = createArgumentListFromParameters(parameterTypes, thisAsFirstArgument); ClassNode returnType = nonGeneric(declaredMethod.getReturnType()); MethodCallExpression methodCallExpression = new MethodCallExpression(delegate, methodName, arguments); methodCallExpression.setMethodTarget(declaredMethod); ThrowStatement missingMethodException = createMissingMethodThrowable(classNode, declaredMethod); VariableExpression apiVar = addApiVariableDeclaration(delegate, declaredMethod, methodBody); IfStatement ifStatement = createIfElseStatementForApiMethodCall(methodCallExpression, apiVar, missingMethodException); methodBody.addStatement(ifStatement); MethodNode methodNode = new MethodNode( methodName, Modifier.PUBLIC, returnType, copyParameters(parameterTypes), GrailsArtefactClassInjector.EMPTY_CLASS_ARRAY, methodBody); methodNode.addAnnotations(declaredMethod.getAnnotations()); classNode.addMethod(methodNode); return methodNode; }
/** * Adds a static method to the given class node that delegates to the given method and resolves * the object to invoke the method on from the given expression. * * @param expression The expression * @param classNode The class node * @param delegateMethod The delegate method * @return The added method node or null if it couldn't be added */ public static MethodNode addDelegateStaticMethod( Expression expression, ClassNode classNode, MethodNode delegateMethod) { Parameter[] parameterTypes = delegateMethod.getParameters(); String declaredMethodName = delegateMethod.getName(); if (classNode.hasDeclaredMethod(declaredMethodName, parameterTypes)) { return null; } BlockStatement methodBody = new BlockStatement(); ArgumentListExpression arguments = new ArgumentListExpression(); for (Parameter parameterType : parameterTypes) { arguments.addExpression(new VariableExpression(parameterType.getName())); } MethodCallExpression methodCallExpression = new MethodCallExpression(expression, declaredMethodName, arguments); methodCallExpression.setMethodTarget(delegateMethod); ThrowStatement missingMethodException = createMissingMethodThrowable(classNode, delegateMethod); VariableExpression apiVar = addApiVariableDeclaration(expression, delegateMethod, methodBody); IfStatement ifStatement = createIfElseStatementForApiMethodCall(methodCallExpression, apiVar, missingMethodException); methodBody.addStatement(ifStatement); ClassNode returnType = nonGeneric(delegateMethod.getReturnType()); if (METHOD_MISSING_METHOD_NAME.equals(declaredMethodName)) { declaredMethodName = STATIC_METHOD_MISSING_METHOD_NAME; } MethodNode methodNode = classNode.getDeclaredMethod(declaredMethodName, parameterTypes); if (methodNode == null) { methodNode = new MethodNode( declaredMethodName, Modifier.PUBLIC | Modifier.STATIC, returnType, copyParameters(parameterTypes), GrailsArtefactClassInjector.EMPTY_CLASS_ARRAY, methodBody); methodNode.addAnnotations(delegateMethod.getAnnotations()); classNode.addMethod(methodNode); } return methodNode; }
private BlockStatement getJunit4Setup(ClassNode classNode) { MethodNode setupMethod = classNode.getMethod(SET_UP_METHOD, GrailsArtefactClassInjector.ZERO_PARAMETERS); if (setupMethod == null) { setupMethod = new MethodNode( SET_UP_METHOD, Modifier.PUBLIC, ClassHelper.VOID_TYPE, GrailsArtefactClassInjector.ZERO_PARAMETERS, null, new BlockStatement()); setupMethod.addAnnotation(MIXIN_METHOD_ANNOTATION); classNode.addMethod(setupMethod); } if (setupMethod.getAnnotations(BEFORE_CLASS_NODE).size() == 0) { setupMethod.addAnnotation(BEFORE_ANNOTATION); } return getOrCreateMethodBody(classNode, setupMethod, SET_UP_METHOD); }