/* * Copyright 2012-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.boot.cli.compiler; import java.util.Arrays; import groovy.lang.Grab; import org.codehaus.groovy.ast.ASTNode; import org.codehaus.groovy.ast.AnnotationNode; import org.codehaus.groovy.ast.ClassNode; import org.codehaus.groovy.ast.ConstructorNode; import org.codehaus.groovy.ast.FieldNode; import org.codehaus.groovy.ast.MethodNode; import org.codehaus.groovy.ast.ModuleNode; import org.codehaus.groovy.ast.PackageNode; import org.codehaus.groovy.ast.Parameter; import org.codehaus.groovy.ast.VariableScope; import org.codehaus.groovy.ast.expr.ConstantExpression; import org.codehaus.groovy.ast.expr.DeclarationExpression; import org.codehaus.groovy.ast.expr.Expression; import org.codehaus.groovy.ast.expr.VariableExpression; import org.codehaus.groovy.ast.stmt.BlockStatement; import org.codehaus.groovy.ast.stmt.ExpressionStatement; import org.codehaus.groovy.ast.stmt.Statement; import org.codehaus.groovy.control.SourceUnit; import org.codehaus.groovy.control.io.ReaderSource; import org.codehaus.groovy.transform.ASTTransformation; import org.junit.Before; import org.junit.Test; import org.springframework.boot.cli.compiler.dependencies.ArtifactCoordinatesResolver; import org.springframework.boot.cli.compiler.dependencies.SpringBootDependenciesDependencyManagement; import org.springframework.boot.cli.compiler.grape.DependencyResolutionContext; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; /** * Tests for {@link ResolveDependencyCoordinatesTransformation} * * @author Andy Wilkinson */ public final class ResolveDependencyCoordinatesTransformationTests { private final SourceUnit sourceUnit = new SourceUnit((String) null, (ReaderSource) null, null, null, null); private final ModuleNode moduleNode = new ModuleNode(this.sourceUnit); private final AnnotationNode grabAnnotation = createGrabAnnotation(); private final ArtifactCoordinatesResolver coordinatesResolver = mock( ArtifactCoordinatesResolver.class); private final DependencyResolutionContext resolutionContext = new DependencyResolutionContext() { { addDependencyManagement(new SpringBootDependenciesDependencyManagement()); } @Override public ArtifactCoordinatesResolver getArtifactCoordinatesResolver() { return ResolveDependencyCoordinatesTransformationTests.this.coordinatesResolver; } }; private final ASTTransformation transformation = new ResolveDependencyCoordinatesTransformation( this.resolutionContext); @Before public void setupExpectations() { given(this.coordinatesResolver.getGroupId("spring-core")) .willReturn("org.springframework"); } @Test public void transformationOfAnnotationOnImport() { this.moduleNode.addImport(null, null, Arrays.asList(this.grabAnnotation)); assertGrabAnnotationHasBeenTransformed(); } @Test public void transformationOfAnnotationOnStarImport() { this.moduleNode.addStarImport("org.springframework.util", Arrays.asList(this.grabAnnotation)); assertGrabAnnotationHasBeenTransformed(); } @Test public void transformationOfAnnotationOnStaticImport() { this.moduleNode.addStaticImport(null, null, null, Arrays.asList(this.grabAnnotation)); assertGrabAnnotationHasBeenTransformed(); } @Test public void transformationOfAnnotationOnStaticStarImport() { this.moduleNode.addStaticStarImport(null, null, Arrays.asList(this.grabAnnotation)); assertGrabAnnotationHasBeenTransformed(); } @Test public void transformationOfAnnotationOnPackage() { PackageNode packageNode = new PackageNode("test"); packageNode.addAnnotation(this.grabAnnotation); this.moduleNode.setPackage(packageNode); assertGrabAnnotationHasBeenTransformed(); } @Test public void transformationOfAnnotationOnClass() { ClassNode classNode = new ClassNode("Test", 0, new ClassNode(Object.class)); classNode.addAnnotation(this.grabAnnotation); this.moduleNode.addClass(classNode); assertGrabAnnotationHasBeenTransformed(); } @Test public void transformationOfAnnotationOnAnnotation() { } @Test public void transformationOfAnnotationOnField() { ClassNode classNode = new ClassNode("Test", 0, new ClassNode(Object.class)); this.moduleNode.addClass(classNode); FieldNode fieldNode = new FieldNode("test", 0, new ClassNode(Object.class), classNode, null); classNode.addField(fieldNode); fieldNode.addAnnotation(this.grabAnnotation); assertGrabAnnotationHasBeenTransformed(); } @Test public void transformationOfAnnotationOnConstructor() { ClassNode classNode = new ClassNode("Test", 0, new ClassNode(Object.class)); this.moduleNode.addClass(classNode); ConstructorNode constructorNode = new ConstructorNode(0, null); constructorNode.addAnnotation(this.grabAnnotation); classNode.addMethod(constructorNode); assertGrabAnnotationHasBeenTransformed(); } @Test public void transformationOfAnnotationOnMethod() { ClassNode classNode = new ClassNode("Test", 0, new ClassNode(Object.class)); this.moduleNode.addClass(classNode); MethodNode methodNode = new MethodNode("test", 0, new ClassNode(Void.class), new Parameter[0], new ClassNode[0], null); methodNode.addAnnotation(this.grabAnnotation); classNode.addMethod(methodNode); assertGrabAnnotationHasBeenTransformed(); } @Test public void transformationOfAnnotationOnMethodParameter() { ClassNode classNode = new ClassNode("Test", 0, new ClassNode(Object.class)); this.moduleNode.addClass(classNode); Parameter parameter = new Parameter(new ClassNode(Object.class), "test"); parameter.addAnnotation(this.grabAnnotation); MethodNode methodNode = new MethodNode("test", 0, new ClassNode(Void.class), new Parameter[] { parameter }, new ClassNode[0], null); classNode.addMethod(methodNode); assertGrabAnnotationHasBeenTransformed(); } @Test public void transformationOfAnnotationOnLocalVariable() { ClassNode classNode = new ClassNode("Test", 0, new ClassNode(Object.class)); this.moduleNode.addClass(classNode); DeclarationExpression declarationExpression = new DeclarationExpression( new VariableExpression("test"), null, new ConstantExpression("test")); declarationExpression.addAnnotation(this.grabAnnotation); BlockStatement code = new BlockStatement( Arrays.asList((Statement) new ExpressionStatement(declarationExpression)), new VariableScope()); MethodNode methodNode = new MethodNode("test", 0, new ClassNode(Void.class), new Parameter[0], new ClassNode[0], code); classNode.addMethod(methodNode); assertGrabAnnotationHasBeenTransformed(); } private AnnotationNode createGrabAnnotation() { ClassNode classNode = new ClassNode(Grab.class); AnnotationNode annotationNode = new AnnotationNode(classNode); annotationNode.addMember("value", new ConstantExpression("spring-core")); return annotationNode; } private void assertGrabAnnotationHasBeenTransformed() { this.transformation.visit(new ASTNode[] { this.moduleNode }, this.sourceUnit); assertThat(getGrabAnnotationMemberAsString("group")) .isEqualTo("org.springframework"); assertThat(getGrabAnnotationMemberAsString("module")).isEqualTo("spring-core"); } private Object getGrabAnnotationMemberAsString(String memberName) { Expression expression = this.grabAnnotation.getMember(memberName); if (expression instanceof ConstantExpression) { return ((ConstantExpression) expression).getValue(); } else if (expression == null) { return null; } else { throw new IllegalStateException( "Member '" + memberName + "' is not a ConstantExpression"); } } }