|
Groovy example source code file (AstAssert.groovy)
The Groovy AstAssert.groovy source codepackage org.codehaus.groovy.ast.builder import org.codehaus.groovy.ast.ASTNode import org.codehaus.groovy.ast.ClassNode import org.junit.Assert import org.codehaus.groovy.ast.stmt.BlockStatement import org.codehaus.groovy.ast.stmt.ExpressionStatement import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.ast.expr.DeclarationExpression import org.codehaus.groovy.ast.expr.VariableExpression import org.codehaus.groovy.ast.stmt.ReturnStatement import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.expr.ArgumentListExpression import org.codehaus.groovy.ast.expr.AnnotationConstantExpression import org.codehaus.groovy.ast.AnnotationNode import org.codehaus.groovy.ast.expr.AttributeExpression /** * * Some useful AST assertion methods. * @author Hamlet D'Arcy */ public class AstAssert { /** * Support for new assertion types can be added by adding a Map<String, Closure> entry. */ private static Map<Object, Closure> ASSERTION_MAP = [ BlockStatement : { expected, actual -> assertSyntaxTree(expected.statements, actual.statements) }, AttributeExpression : { expected, actual -> assertSyntaxTree([expected.objectExpression], [actual.objectExpression]) assertSyntaxTree([expected.property], [actual.property]) }, ExpressionStatement : { expected, actual -> assertSyntaxTree([expected.expression], [actual.expression]) }, BitwiseNegationExpression : { expected, actual -> assertSyntaxTree([expected.expression], [actual.expression]) }, CastExpression : { expected, actual -> assertSyntaxTree([expected.expression], [actual.expression]) Assert.assertEquals("Wrong type", expected.type, actual.type) }, ClosureExpression : { expected, actual -> assertSyntaxTree([expected.parameters], [actual.parameters]) assertSyntaxTree([expected.code], [actual.code]) }, ConstantExpression : { expected, actual -> Assert.assertEquals("Wrong constant", expected.value, actual.value) }, ArrayExpression : { expected, actual -> Assert.assertEquals("Wrong array type", expected.elementType, actual.elementType) Assert.assertEquals("Wrong # ast nodes", expected.expressions.size(), actual.expressions.size()) expected.expressions.eachWithIndex { element, index -> assertSyntaxTree([element], [actual.expressions[index]]) } }, ListExpression : { expected, actual -> Assert.assertEquals("Wrong # ast nodes", expected.expressions.size(), actual.expressions.size()) expected.expressions.eachWithIndex { element, index -> assertSyntaxTree([element], [actual.expressions[index]]) } }, DeclarationExpression : { expected, actual -> Assert.assertEquals("Wrong token", expected.operation.text, actual.operation.text) assertSyntaxTree([expected.leftExpression], [actual.leftExpression]) assertSyntaxTree([expected.rightExpression], [actual.rightExpression]) }, VariableExpression : { expected, actual -> Assert.assertEquals("Wrong variable", expected.variable, actual.variable) }, ReturnStatement : { expected, actual -> assertSyntaxTree([expected.expression], [actual.expression]) }, ArgumentListExpression : { expected, actual -> assertSyntaxTree(expected.expressions, actual.expressions) }, AnnotationConstantExpression : { expected, actual -> assertSyntaxTree([expected.value], [actual.value]) }, MethodCallExpression : { expected, actual -> assertSyntaxTree([expected.objectExpression], [actual.objectExpression]) assertSyntaxTree([expected.method], [actual.method]) assertSyntaxTree([expected.arguments], [actual.arguments]) }, AnnotationNode : { expected, actual -> assertSyntaxTree([expected.classNode], [actual.classNode]) // Map<String, Expression> Assert.assertEquals("Wrong keyset", expected.members.keySet(), actual.members.keySet()) Assert.assertEquals("Wrong # members", expected.members.size(), actual.members.size()) expected.members.each { key, value -> Assert.assertTrue("Missing key $key", actual.members.containsKey(key)) assertSyntaxTree([expected.members[key]], [actual.members[key]]) } }, ClassNode : { expected, actual -> if (expected.superClass) { Assert.assertEquals("Wrong superClass type", expected.superClass.getName(), actual.superClass.getName()) } else { Assert.assertEquals("Wrong class type", expected.class.getName(), actual.class.getName()) } assertSyntaxTree([expected.mixins], [actual.mixins]) // do NOT assert module property b/c it is a circular reference, causes stack overflow //assertSyntaxTree([expected.module], [actual.module]) assertSyntaxTree(expected.genericsTypes, actual.genericsTypes) }, IfStatement : { expected, actual -> assertSyntaxTree([expected.booleanExpression], [actual.booleanExpression]) assertSyntaxTree([expected.ifBlock], [actual.ifBlock]) assertSyntaxTree([expected.elseBlock], [actual.elseBlock]) }, BooleanExpression : { expected, actual -> assertSyntaxTree([expected.expression], [actual.expression]) }, BinaryExpression : { expected, actual -> assertSyntaxTree([expected.leftExpression], [actual.leftExpression]) assertSyntaxTree([expected.rightExpression], [actual.rightExpression]) assertSyntaxTree([expected.operation], [actual.operation]) }, Token : { expected, actual -> Assert.assertEquals("Wrong token type", expected.type, actual.type) Assert.assertEquals("Wrong token text", expected.text, actual.text) }, Parameter : { expected, actual -> assertSyntaxTree([expected.type], [actual.type]) assertSyntaxTree([expected.defaultValue], [actual.defaultValue]) Assert.assertEquals("Wrong parameter name", expected.name, actual.name) Assert.assertEquals("Wrong 'hasDefaultValue'", expected.hasDefaultValue, actual.hasDefaultValue) }, ConstructorCallExpression : { expected, actual -> assertSyntaxTree([expected.arguments], [actual.arguments]) }, NotExpression : { expected, actual -> assertSyntaxTree([expected.expression], [actual.expression]) }, PostfixExpression : { expected, actual -> assertSyntaxTree([expected.expression], [actual.expression]) assertSyntaxTree([expected.operation], [actual.operation]) }, PrefixExpression : { expected, actual -> assertSyntaxTree([expected.expression], [actual.expression]) assertSyntaxTree([expected.operation], [actual.operation]) }, UnaryPlusExpression : { expected, actual -> assertSyntaxTree([expected.expression], [actual.expression]) }, UnaryMinusExpression : { expected, actual -> assertSyntaxTree([expected.expression], [actual.expression]) }, ClassExpression : { expected, actual -> assertSyntaxTree([expected.type], [actual.type]) }, TupleExpression : { expected, actual -> assertSyntaxTree([expected.type], [actual.type]) assertSyntaxTree(expected.expressions, actual.expressions) }, FieldExpression : { expected, actual -> assertSyntaxTree([expected.field], [actual.field]) }, FieldNode : { expected, actual -> Assert.assertEquals("Wrong name", expected.name, actual.name) Assert.assertEquals("Wrong modifiers", expected.modifiers, actual.modifiers) assertSyntaxTree([expected.type], [actual.type]) assertSyntaxTree([expected.owner], [actual.owner]) assertSyntaxTree([expected.initialValueExpression], [actual.initialValueExpression]) }, MapExpression : { expected, actual -> assertSyntaxTree(expected.mapEntryExpressions, actual.mapEntryExpressions) }, MapEntryExpression : { expected, actual -> assertSyntaxTree([expected.keyExpression], [actual.keyExpression]) assertSyntaxTree([expected.valueExpression], [actual.valueExpression]) }, GStringExpression : { expected, actual -> Assert.assertEquals("Wrong text", expected.verbatimText, actual.verbatimText) assertSyntaxTree(expected.strings, actual.strings) assertSyntaxTree(expected.values, actual.values) }, MethodPointerExpression : { expected, actual -> assertSyntaxTree([expected.expression], [actual.expression]) assertSyntaxTree([expected.methodName], [actual.methodName]) }, RangeExpression : { expected, actual -> assertSyntaxTree([expected.from], [actual.from]) assertSyntaxTree([expected.to], [actual.to]) Assert.assertEquals("Wrong inclusive", expected.inclusive, actual.inclusive) }, PropertyExpression : { expected, actual -> assertSyntaxTree([expected.objectExpression], [actual.objectExpression]) assertSyntaxTree([expected.property], [actual.property]) }, SwitchStatement : { expected, actual -> assertSyntaxTree([expected.expression], [actual.expression]) assertSyntaxTree([expected.defaultStatement], [actual.defaultStatement]) assertSyntaxTree(expected.caseStatements, actual.caseStatements) }, CaseStatement : { expected, actual -> assertSyntaxTree([expected.expression], [actual.expression]) assertSyntaxTree([expected.code], [actual.code]) }, EmptyStatement : { expected, actual -> // always successful }, BreakStatement : { expected, actual -> Assert.assertEquals("Wrong label", expected.label, actual.label) }, AssertStatement : { expected, actual -> assertSyntaxTree([expected.booleanExpression], [actual.booleanExpression]) assertSyntaxTree([expected.messageExpression], [actual.messageExpression]) }, SynchronizedStatement : { expected, actual -> assertSyntaxTree([expected.expression], [actual.expression]) assertSyntaxTree([expected.code], [actual.code]) }, TryCatchStatement : { expected, actual -> assertSyntaxTree([expected.tryStatement], [actual.tryStatement]) assertSyntaxTree([expected.finallyStatement], [actual.finallyStatement]) assertSyntaxTree(expected.catchStatements, actual.catchStatements) }, CatchStatement : { expected, actual -> assertSyntaxTree([expected.variable], [actual.variable]) assertSyntaxTree([expected.code], [actual.code]) }, ThrowStatement : { expected, actual -> assertSyntaxTree([expected.expression], [actual.expression]) }, StaticMethodCallExpression : { expected, actual -> Assert.assertEquals("Wrong method", expected.method, actual.method) assertSyntaxTree([expected.ownerType], [actual.ownerType]) assertSyntaxTree([expected.arguments], [actual.arguments]) }, ForStatement : { expected, actual -> assertSyntaxTree([expected.variable], [actual.variable]) assertSyntaxTree([expected.collectionExpression], [actual.collectionExpression]) assertSyntaxTree([expected.loopBlock], [actual.loopBlock]) }, ClosureListExpression : { expected, actual -> assertSyntaxTree(expected.expressions, actual.expressions) }, WhileStatement : { expected, actual -> assertSyntaxTree([expected.booleanExpression], [actual.booleanExpression]) assertSyntaxTree([expected.loopBlock], [actual.loopBlock]) }, ContinueStatement : { expected, actual -> Assert.assertEquals("Wrong label", expected.label, actual.label) }, TernaryExpression : { expected, actual -> assertSyntaxTree([expected.booleanExpression], [actual.booleanExpression]) assertSyntaxTree([expected.trueExpression], [actual.trueExpression]) assertSyntaxTree([expected.falseExpression], [actual.falseExpression]) }, ElvisOperatorExpression : { expected, actual -> assertSyntaxTree([expected.booleanExpression], [actual.booleanExpression]) assertSyntaxTree([expected.trueExpression], [actual.trueExpression]) assertSyntaxTree([expected.falseExpression], [actual.falseExpression]) }, PropertyNode : { expected, actual -> Assert.assertEquals("Wrong name", expected.name, actual.name) Assert.assertEquals("Wrong modifiers", expected.modifiers, actual.modifiers) assertSyntaxTree(expected.annotations, actual.annotations) assertSyntaxTree([expected.field], [actual.field]) assertSyntaxTree([expected.getterBlock], [actual.getterBlock]) assertSyntaxTree([expected.setterBlock], [actual.setterBlock]) }, NullObject : { expected, actual -> Assert.assertNull(expected) Assert.assertNull(actual) }, MethodNode : { expected, actual -> assertSyntaxTree(expected.annotations, actual.annotations) assertSyntaxTree([expected.returnType], [actual.returnType]) assertSyntaxTree([expected.code], [actual.code]) assertSyntaxTree(expected.parameters, actual.parameters) assertSyntaxTree(expected.exceptions, actual.exceptions) Assert.assertEquals("Wrong name", expected.name, actual.name) Assert.assertEquals("Wrong modifiers", expected.modifiers, actual.modifiers) }, ConstructorNode : { expected, actual -> assertSyntaxTree(expected.annotations, actual.annotations) assertSyntaxTree([expected.returnType], [actual.returnType]) assertSyntaxTree([expected.code], [actual.code]) assertSyntaxTree(expected.parameters, actual.parameters) assertSyntaxTree(expected.exceptions, actual.exceptions) Assert.assertEquals("Wrong name", expected.name, actual.name) Assert.assertEquals("Wrong modifiers", expected.modifiers, actual.modifiers) }, ImportNode : { expected, actual -> assertSyntaxTree(expected.annotations, actual.annotations) assertSyntaxTree([expected.type], [actual.type]) Assert.assertEquals("Wrong alias", expected.alias, actual.alias) }, RegexExpression : { expected, actual -> assertSyntaxTree([expected.type], [actual.type]) assertSyntaxTree([expected.string], [actual.string]) }, SpreadExpression : { expected, actual -> assertSyntaxTree([expected.type], [actual.type]) assertSyntaxTree([expected.expression], [actual.expression]) }, SpreadMapExpression : { expected, actual -> assertSyntaxTree([expected.type], [actual.type]) assertSyntaxTree([expected.expression], [actual.expression]) }, GenericsType : { expected, actual -> assertSyntaxTree([expected.type], [actual.type]) assertSyntaxTree([expected.lowerBound], [actual.lowerBound]) assertSyntaxTree(expected.upperBounds, actual.upperBounds) Assert.assertEquals("Wrong wildcard", expected.name, actual.name) Assert.assertEquals("Wrong wildcard", expected.wildcard, actual.wildcard) }, NamedArgumentListExpression : { expected, actual -> assertSyntaxTree(expected.mapEntryExpressions, actual.mapEntryExpressions) }, MixinNode : { expected, actual -> assertSyntaxTree([expected.superClass], [actual.superClass]) assertSyntaxTree([expected.interfaces], [actual.interfaces]) assertSyntaxTree([expected.mixins], [actual.mixins]) assertSyntaxTree([expected.module], [actual.module]) assertSyntaxTree(expected.annotations, actual.annotations) assertSyntaxTree(expected.genericsTypes, actual.genericsTypes) Assert.assertEquals("Wrong name", expected.name, actual.name) Assert.assertEquals("Wrong modifiers", expected.modifiers, actual.modifiers) }, InnerClassNode : { expected, actual -> assertSyntaxTree([expected.outerClass], [actual.outerClass]) assertSyntaxTree([expected.superClass], [actual.superClass]) assertSyntaxTree([expected.interfaces], [actual.interfaces]) assertSyntaxTree([expected.mixins], [actual.mixins]) assertSyntaxTree([expected.module], [actual.module]) assertSyntaxTree(expected.annotations, actual.annotations) assertSyntaxTree(expected.genericsTypes, actual.genericsTypes) Assert.assertEquals("Wrong name", expected.name, actual.name) Assert.assertEquals("Wrong modifiers", expected.modifiers, actual.modifiers) }, ] /** * Assertion statement to compare abstract syntax trees. * @param expected * the list or array of ASTNodes expected to be present * @param actual * the actual list or array of ASTNodes received */ static void assertSyntaxTree(expected, actual) { if (expected == null && actual == null) return if (actual == null || expected == null || expected.size() != actual?.size()) { Assert.fail("AST comparison failure. \nExpected $expected \nReceived $actual") } expected.eachWithIndex { item, index -> if (item.getClass().isArray() && actual[index].getClass().isArray()) { assertSyntaxTree(item, actual[index]) } else { Assert.assertEquals("Wrong type in AST Node", item.getClass(), actual[index].getClass()) if (ASSERTION_MAP.containsKey(item.getClass().getSimpleName())) { Closure assertion = ASSERTION_MAP.get(item.getClass().getSimpleName()) assertion(item, actual[index]) } else { Assert.fail("Unexpected type: ${item.getClass()} Update the unit test!") } } } } } Other Groovy examples (source code examples)Here is a short list of links related to this Groovy AstAssert.groovy source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.