Index: pkg/kernel/test/verify_test.dart |
diff --git a/pkg/kernel/test/verify_test.dart b/pkg/kernel/test/verify_test.dart |
index 11f54f97ac38ab2d4d5f41ad7823dc44016797ce..610111cf3656f66499b676c0f4d8b926e2cf4c87 100644 |
--- a/pkg/kernel/test/verify_test.dart |
+++ b/pkg/kernel/test/verify_test.dart |
@@ -14,81 +14,83 @@ import 'package:test/test.dart'; |
/// We mostly test negative cases here, as we get plenty of positive cases by |
/// compiling the Dart test suite with the verifier enabled. |
main() { |
- positiveTest('Test harness has no errors', () { |
+ positiveTest('Test harness has no errors', (TestHarness test) { |
return new NullLiteral(); |
}); |
- negativeTest('VariableGet out of scope', () { |
- return new VariableGet(makeVariable()); |
+ negativeTest('VariableGet out of scope', (TestHarness test) { |
+ return new VariableGet(test.makeVariable()); |
}); |
- negativeTest('VariableSet out of scope', () { |
- return new VariableSet(makeVariable(), new NullLiteral()); |
+ negativeTest('VariableSet out of scope', (TestHarness test) { |
+ return new VariableSet(test.makeVariable(), new NullLiteral()); |
}); |
- negativeTest('Variable block scope', () { |
- VariableDeclaration variable = makeVariable(); |
+ negativeTest('Variable block scope', (TestHarness test) { |
+ VariableDeclaration variable = test.makeVariable(); |
return new Block([ |
new Block([variable]), |
new ReturnStatement(new VariableGet(variable)) |
]); |
}); |
- negativeTest('Variable let scope', () { |
- VariableDeclaration variable = makeVariable(); |
+ negativeTest('Variable let scope', (TestHarness test) { |
+ VariableDeclaration variable = test.makeVariable(); |
return new LogicalExpression(new Let(variable, new VariableGet(variable)), |
'&&', new VariableGet(variable)); |
}); |
- negativeTest('Variable redeclared', () { |
- VariableDeclaration variable = makeVariable(); |
+ negativeTest('Variable redeclared', (TestHarness test) { |
+ VariableDeclaration variable = test.makeVariable(); |
return new Block([variable, variable]); |
}); |
- negativeTest('Member redeclared', () { |
+ negativeTest('Member redeclared', (TestHarness test) { |
Field field = new Field(new Name('field'), initializer: new NullLiteral()); |
return new Class( |
name: 'Test', |
- supertype: objectClass.asRawSupertype, |
+ supertype: test.objectClass.asRawSupertype, |
fields: [field, field]); |
}); |
- negativeTest('Class redeclared', () { |
- return otherClass; // Test harness also adds otherClass to program. |
+ negativeTest('Class redeclared', (TestHarness test) { |
+ return test.otherClass; // Test harness also adds otherClass to program. |
}); |
- negativeTest('Class type parameter redeclared', () { |
- var parameter = makeTypeParameter(); |
+ negativeTest('Class type parameter redeclared', (TestHarness test) { |
+ var parameter = test.makeTypeParameter(); |
return new Class( |
name: 'Test', |
- supertype: objectClass.asRawSupertype, |
+ supertype: test.objectClass.asRawSupertype, |
typeParameters: [parameter, parameter]); |
}); |
- negativeTest('Member type parameter redeclared', () { |
- var parameter = makeTypeParameter(); |
+ negativeTest('Member type parameter redeclared', (TestHarness test) { |
+ var parameter = test.makeTypeParameter(); |
return new Procedure( |
- new Name('test'), |
+ new Name('bar'), |
ProcedureKind.Method, |
new FunctionNode(new ReturnStatement(new NullLiteral()), |
typeParameters: [parameter, parameter])); |
}); |
- negativeTest('Type parameter out of scope', () { |
- var parameter = makeTypeParameter(); |
+ negativeTest('Type parameter out of scope', (TestHarness test) { |
+ var parameter = test.makeTypeParameter(); |
return new ListLiteral([], typeArgument: new TypeParameterType(parameter)); |
}); |
- negativeTest('Class type parameter from another class', () { |
- return new TypeLiteral(new TypeParameterType(otherClass.typeParameters[0])); |
+ negativeTest('Class type parameter from another class', (TestHarness test) { |
+ return new TypeLiteral( |
+ new TypeParameterType(test.otherClass.typeParameters[0])); |
}); |
- negativeTest('Class type parameter in static method', () { |
+ negativeTest('Class type parameter in static method', (TestHarness test) { |
return new Procedure( |
- new Name('test'), |
+ new Name('bar'), |
ProcedureKind.Method, |
new FunctionNode(new ReturnStatement( |
- new TypeLiteral(new TypeParameterType(classTypeParameter)))), |
+ new TypeLiteral(new TypeParameterType(test.classTypeParameter)))), |
isStatic: true); |
}); |
- negativeTest('Class type parameter in static field', () { |
+ negativeTest('Class type parameter in static field', (TestHarness test) { |
return new Field(new Name('field'), |
- initializer: new TypeLiteral(new TypeParameterType(classTypeParameter)), |
+ initializer: |
+ new TypeLiteral(new TypeParameterType(test.classTypeParameter)), |
isStatic: true); |
}); |
- negativeTest('Method type parameter out of scope', () { |
- var parameter = makeTypeParameter(); |
+ negativeTest('Method type parameter out of scope', (TestHarness test) { |
+ var parameter = test.makeTypeParameter(); |
return new Class( |
name: 'Test', |
- supertype: objectClass.asRawSupertype, |
+ supertype: test.objectClass.asRawSupertype, |
procedures: [ |
new Procedure( |
new Name('generic'), |
@@ -102,108 +104,100 @@ main() { |
new TypeLiteral(new TypeParameterType(parameter))))) |
]); |
}); |
- negativeTest('Interface type arity too low', () { |
- return new TypeLiteral(new InterfaceType(otherClass, [])); |
+ negativeTest('Interface type arity too low', (TestHarness test) { |
+ return new TypeLiteral(new InterfaceType(test.otherClass, [])); |
}); |
- negativeTest('Interface type arity too high', () { |
- return new TypeLiteral( |
- new InterfaceType(otherClass, [new DynamicType(), new DynamicType()])); |
+ negativeTest('Interface type arity too high', (TestHarness test) { |
+ return new TypeLiteral(new InterfaceType( |
+ test.otherClass, [new DynamicType(), new DynamicType()])); |
}); |
- negativeTest('Dangling interface type', () { |
- return new TypeLiteral(new InterfaceType(new Class())); |
+ negativeTest('Dangling interface type', (TestHarness test) { |
+ var orphan = new Class(); |
+ return new TypeLiteral(new InterfaceType(orphan)); |
}); |
- negativeTest('Dangling field get', () { |
- return new DirectPropertyGet(new NullLiteral(), new Field(new Name('foo'))); |
+ negativeTest('Dangling field get', (TestHarness test) { |
+ var orphan = new Field(new Name('foo')); |
+ return new DirectPropertyGet(new NullLiteral(), orphan); |
}); |
- negativeTest('Missing block parent pointer', () { |
+ negativeTest('Missing block parent pointer', (TestHarness test) { |
var block = new Block([]); |
block.statements.add(new ReturnStatement()); |
return block; |
}); |
- negativeTest('Missing function parent pointer', () { |
- var procedure = new Procedure(new Name('test'), ProcedureKind.Method, null); |
+ negativeTest('Missing function parent pointer', (TestHarness test) { |
+ var procedure = new Procedure(new Name('bar'), ProcedureKind.Method, null); |
procedure.function = new FunctionNode(new EmptyStatement()); |
return procedure; |
}); |
- negativeTest('StaticGet without target', () { |
+ negativeTest('StaticGet without target', (TestHarness test) { |
return new StaticGet(null); |
}); |
- negativeTest('StaticSet without target', () { |
+ negativeTest('StaticSet without target', (TestHarness test) { |
return new StaticSet(null, new NullLiteral()); |
}); |
- negativeTest('StaticInvocation without target', () { |
+ negativeTest('StaticInvocation without target', (TestHarness test) { |
return new StaticInvocation(null, new Arguments.empty()); |
}); |
- positiveTest('Correct StaticInvocation', () { |
- var method = new Procedure(new Name('test'), ProcedureKind.Method, null, |
+ positiveTest('Correct StaticInvocation', (TestHarness test) { |
+ var method = new Procedure( |
+ new Name('foo'), |
+ ProcedureKind.Method, |
+ new FunctionNode(new EmptyStatement(), |
+ positionalParameters: [new VariableDeclaration('p')]), |
isStatic: true); |
- method.function = new FunctionNode( |
- new ReturnStatement( |
- new StaticInvocation(method, new Arguments([new NullLiteral()]))), |
- positionalParameters: [new VariableDeclaration('p')])..parent = method; |
- return new Class( |
- name: 'Test', |
- supertype: objectClass.asRawSupertype, |
- procedures: [method]); |
+ test.enclosingClass.addMember(method); |
+ return new StaticInvocation(method, new Arguments([new NullLiteral()])); |
}); |
- negativeTest('StaticInvocation with too many parameters', () { |
- var method = new Procedure(new Name('test'), ProcedureKind.Method, null, |
+ negativeTest('StaticInvocation with too many parameters', (TestHarness test) { |
+ var method = new Procedure(new Name('bar'), ProcedureKind.Method, |
+ new FunctionNode(new EmptyStatement()), |
isStatic: true); |
- method.function = new FunctionNode(new ReturnStatement( |
- new StaticInvocation(method, new Arguments([new NullLiteral()])))) |
- ..parent = method; |
- return new Class( |
- name: 'Test', |
- supertype: objectClass.asRawSupertype, |
- procedures: [method]); |
+ test.enclosingClass.addMember(method); |
+ return new StaticInvocation(method, new Arguments([new NullLiteral()])); |
}); |
- negativeTest('StaticInvocation with too few parameters', () { |
- var method = new Procedure(new Name('test'), ProcedureKind.Method, null, |
+ negativeTest('StaticInvocation with too few parameters', (TestHarness test) { |
+ var method = new Procedure( |
+ new Name('bar'), |
+ ProcedureKind.Method, |
+ new FunctionNode(new EmptyStatement(), |
+ positionalParameters: [new VariableDeclaration('p')]), |
isStatic: true); |
- method.function = new FunctionNode( |
- new ReturnStatement( |
- new StaticInvocation(method, new Arguments.empty())), |
- positionalParameters: [new VariableDeclaration('p')])..parent = method; |
- return new Class( |
- name: 'Test', |
- supertype: objectClass.asRawSupertype, |
- procedures: [method]); |
+ test.enclosingClass.addMember(method); |
+ return new StaticInvocation(method, new Arguments.empty()); |
}); |
- negativeTest('StaticInvocation with unmatched named parameter', () { |
- var method = new Procedure(new Name('test'), ProcedureKind.Method, null, |
+ negativeTest('StaticInvocation with unmatched named parameter', |
+ (TestHarness test) { |
+ var method = new Procedure(new Name('bar'), ProcedureKind.Method, |
+ new FunctionNode(new EmptyStatement()), |
isStatic: true); |
- method.function = new FunctionNode(new ReturnStatement(new StaticInvocation( |
+ test.enclosingClass.addMember(method); |
+ return new StaticInvocation( |
method, |
new Arguments([], |
- named: [new NamedExpression('p', new NullLiteral())])))) |
- ..parent = method; |
- return new Class( |
- name: 'Test', |
- supertype: objectClass.asRawSupertype, |
- procedures: [method]); |
+ named: [new NamedExpression('p', new NullLiteral())])); |
}); |
- negativeTest('StaticInvocation with missing type argument', () { |
- var method = new Procedure(new Name('test'), ProcedureKind.Method, null, |
+ negativeTest('StaticInvocation with missing type argument', |
+ (TestHarness test) { |
+ var method = new Procedure( |
+ new Name('bar'), |
+ ProcedureKind.Method, |
+ new FunctionNode(new EmptyStatement(), |
+ typeParameters: [test.makeTypeParameter()]), |
isStatic: true); |
- method.function = new FunctionNode( |
- new ReturnStatement( |
- new StaticInvocation(method, new Arguments.empty())), |
- typeParameters: [makeTypeParameter()])..parent = method; |
- return new Class( |
- name: 'Test', |
- supertype: objectClass.asRawSupertype, |
- procedures: [method]); |
- }); |
- negativeTest('ConstructorInvocation with missing type argument', () { |
- var constructor = new Constructor(null); |
- constructor.function = new FunctionNode(new ReturnStatement( |
- new ConstructorInvocation(constructor, new Arguments.empty()))) |
- ..parent = constructor; |
- return new Class( |
+ test.enclosingClass.addMember(method); |
+ return new StaticInvocation(method, new Arguments.empty()); |
+ }); |
+ negativeTest('ConstructorInvocation with missing type argument', |
+ (TestHarness test) { |
+ var class_ = new Class( |
name: 'Test', |
- typeParameters: [makeTypeParameter()], |
- supertype: objectClass.asRawSupertype, |
- constructors: [constructor]); |
+ typeParameters: [test.makeTypeParameter()], |
+ supertype: test.objectClass.asRawSupertype); |
+ test.enclosingLibrary.addClass(class_); |
+ var constructor = new Constructor(new FunctionNode(new EmptyStatement()), |
+ name: new Name('foo')); |
+ test.enclosingClass.addMember(constructor); |
+ return new ConstructorInvocation(constructor, new Arguments.empty()); |
}); |
} |
@@ -218,60 +212,101 @@ checkHasError(Program program) { |
} |
} |
-Class objectClass = new Class(name: 'Object'); |
+class TestHarness { |
+ Program program; |
+ Class objectClass; |
+ Library stubLibrary; |
-Library stubLibrary = new Library(Uri.parse('dart:core')) |
- ..addClass(objectClass); |
+ TypeParameter classTypeParameter; |
-TypeParameter classTypeParameter = makeTypeParameter('T'); |
+ Library enclosingLibrary; |
+ Class enclosingClass; |
+ Procedure enclosingMember; |
-Class otherClass = new Class( |
- name: 'OtherClass', |
- typeParameters: [makeTypeParameter('OtherT')], |
- supertype: objectClass.asRawSupertype); |
+ Class otherClass; |
-Program makeProgram(TreeNode makeBody()) { |
- var node = makeBody(); |
- if (node is Expression) { |
- node = new ReturnStatement(node); |
+ void addNode(TreeNode node) { |
+ if (node is Expression) { |
+ addExpression(node); |
+ } else if (node is Statement) { |
+ addStatement(node); |
+ } else if (node is Member) { |
+ addClassMember(node); |
+ } else if (node is Class) { |
+ addClass(node); |
+ } |
} |
- if (node is Statement) { |
- node = new FunctionNode(node); |
+ |
+ void addExpression(Expression node) { |
+ addStatement(new ReturnStatement(node)); |
} |
- if (node is FunctionNode) { |
- node = new Procedure(new Name('test'), ProcedureKind.Method, node); |
+ |
+ void addStatement(Statement node) { |
+ var function = enclosingMember.function; |
+ function.body = node..parent = function; |
} |
- if (node is Member) { |
- node = new Class( |
- name: 'Test', |
- typeParameters: [classTypeParameter], |
- supertype: objectClass.asRawSupertype)..addMember(node); |
+ |
+ void addClassMember(Member node) { |
+ enclosingClass.addMember(node); |
} |
- if (node is Class) { |
- node = |
- new Library(Uri.parse('test.dart'), classes: <Class>[node, otherClass]); |
+ |
+ void addTopLevelMember(Member node) { |
+ enclosingLibrary.addMember(node); |
} |
- if (node is Library) { |
- node = new Program(<Library>[node, stubLibrary]); |
+ |
+ void addClass(Class node) { |
+ enclosingLibrary.addClass(node); |
+ } |
+ |
+ VariableDeclaration makeVariable() => new VariableDeclaration(null); |
+ |
+ TypeParameter makeTypeParameter([String name]) { |
+ return new TypeParameter(name, new InterfaceType(objectClass)); |
+ } |
+ |
+ TestHarness() { |
+ setupProgram(); |
+ } |
+ |
+ void setupProgram() { |
+ program = new Program(); |
+ stubLibrary = new Library(Uri.parse('dart:core')); |
+ program.libraries.add(stubLibrary..parent = program); |
+ stubLibrary.name = 'dart.core'; |
+ objectClass = new Class(name: 'Object'); |
+ stubLibrary.addClass(objectClass); |
+ enclosingLibrary = new Library(Uri.parse('file://test.dart')); |
+ program.libraries.add(enclosingLibrary..parent = program); |
+ enclosingLibrary.name = 'test_lib'; |
+ classTypeParameter = makeTypeParameter('T'); |
+ enclosingClass = new Class( |
+ name: 'TestClass', |
+ typeParameters: [classTypeParameter], |
+ supertype: objectClass.asRawSupertype); |
+ enclosingLibrary.addClass(enclosingClass); |
+ enclosingMember = new Procedure(new Name('test'), ProcedureKind.Method, |
+ new FunctionNode(new EmptyStatement())); |
+ enclosingClass.addMember(enclosingMember); |
+ otherClass = new Class( |
+ name: 'OtherClass', |
+ typeParameters: [makeTypeParameter('OtherT')], |
+ supertype: objectClass.asRawSupertype); |
+ enclosingLibrary.addClass(otherClass); |
} |
- assert(node is Program); |
- return node; |
} |
-negativeTest(String name, TreeNode makeBody()) { |
+negativeTest(String name, TreeNode makeTestCase(TestHarness test)) { |
test(name, () { |
- checkHasError(makeProgram(makeBody)); |
+ var test = new TestHarness(); |
+ test.addNode(makeTestCase(test)); |
+ checkHasError(test.program); |
}); |
} |
-positiveTest(String name, TreeNode makeBody()) { |
+positiveTest(String name, TreeNode makeTestCase(TestHarness test)) { |
test(name, () { |
- verifyProgram(makeProgram(makeBody)); |
+ var test = new TestHarness(); |
+ test.addNode(makeTestCase(test)); |
+ verifyProgram(test.program); |
}); |
} |
- |
-VariableDeclaration makeVariable() => new VariableDeclaration(null); |
- |
-TypeParameter makeTypeParameter([String name]) { |
- return new TypeParameter(name, new InterfaceType(objectClass)); |
-} |