OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library analyzer.test.utils; | 5 library analyzer.test.utils; |
6 | 6 |
7 import 'package:analyzer/src/generated/ast.dart'; | |
8 import 'package:analyzer/src/generated/element.dart'; | |
7 import 'package:analyzer/src/generated/java_io.dart'; | 9 import 'package:analyzer/src/generated/java_io.dart'; |
10 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider; | |
8 import 'package:path/path.dart' as path; | 11 import 'package:path/path.dart' as path; |
9 import 'package:unittest/unittest.dart'; | 12 import 'package:unittest/unittest.dart'; |
10 | 13 |
11 void initializeTestEnvironment() { | 14 void initializeTestEnvironment() { |
12 groupSep = ' | '; | 15 groupSep = ' | '; |
13 JavaFile.pathContext = path.posix; | 16 JavaFile.pathContext = path.posix; |
14 } | 17 } |
18 | |
19 /** The type of an assertion which asserts properties of [T]s. | |
20 */ | |
21 typedef void Asserter<T>(T type); | |
22 | |
23 /** The type of a function which given an [S], builds an assertion over [T]s. | |
24 */ | |
25 typedef Asserter<T> AsserterBuilder<S, T>(S arg); | |
26 | |
27 /** The type of a function which given an [S0] and an S1, builds an assertion ov er [T]s. | |
Jennifer Messerly
2015/11/23 22:11:58
long line (& a few below)
unfortunately dartfmt w
Leaf
2015/12/01 21:49:12
Done.
| |
28 */ | |
29 typedef Asserter<T> AsserterBuilder2<S0, S1, T>(S0 arg0, S1 arg1); | |
30 | |
31 /** The type of a function which given an [R] returns an [AsserterBuilder] over | |
32 * [S]s and [T]s. That is, it returns a function which given an [S], returns | |
33 * a function over [T]s. | |
34 */ | |
35 typedef AsserterBuilder<S, T> AsserterBuilderBuilder<R, S, T>(R arg); | |
36 | |
37 class AstFinder { | |
scheglov
2015/11/21 06:31:35
Could you please move the methods of AstFinder int
Brian Wilkerson
2015/11/21 16:12:22
I'm not a fan of top-level functions; I'd actually
Leaf
2015/11/24 19:32:12
Hmm, I was really annoyed that moving these from l
Brian Wilkerson
2015/11/24 21:17:57
It isn't my favorite solution, but I'm not going t
Leaf
2015/12/01 21:49:12
Ok, leaving as is for now.
| |
38 /** | |
39 * Return the declaration of the class with the given [className] in the given | |
40 * compilation [unit]. | |
41 */ | |
42 static ClassDeclaration getClass(CompilationUnit unit, String className) { | |
43 NodeList<CompilationUnitMember> unitMembers = unit.declarations; | |
44 for (CompilationUnitMember unitMember in unitMembers) { | |
45 if (unitMember is ClassDeclaration && unitMember.name.name == className) { | |
46 return unitMember; | |
47 } | |
48 } | |
49 fail('No class named $className in ${unit.element.source}'); | |
50 return null; | |
51 } | |
52 | |
53 /** | |
54 * Return the declaration of the constructor with the given [constructorName] in | |
55 * the class with the given [className] in the given compilation [unit]. If | |
56 * constructorName is null, return the default constructor; | |
57 */ | |
58 static ConstructorDeclaration getConstructorInClass( | |
59 CompilationUnit unit, String className, String constructorName) { | |
60 ClassDeclaration unitMember = getClass(unit, className); | |
61 NodeList<ClassMember> classMembers = unitMember.members; | |
62 for (ClassMember classMember in classMembers) { | |
63 if (classMember is ConstructorDeclaration) { | |
64 if (classMember.name?.name == constructorName) { | |
65 return classMember; | |
66 } | |
67 } | |
68 } | |
69 fail('No constructor named $constructorName in $className'); | |
70 return null; | |
71 } | |
72 | |
73 /** | |
74 * Return the declaration of the field with the given [fieldName] in the class | |
75 * with the given [className] in the given compilation [unit]. | |
76 */ | |
77 static VariableDeclaration getFieldInClass( | |
78 CompilationUnit unit, String className, String fieldName) { | |
79 ClassDeclaration unitMember = getClass(unit, className); | |
80 NodeList<ClassMember> classMembers = unitMember.members; | |
81 for (ClassMember classMember in classMembers) { | |
82 if (classMember is FieldDeclaration) { | |
83 NodeList<VariableDeclaration> fields = classMember.fields.variables; | |
84 for (VariableDeclaration field in fields) { | |
85 if (field.name.name == fieldName) { | |
86 return field; | |
87 } | |
88 } | |
89 } | |
90 } | |
91 fail('No field named $fieldName in $className'); | |
92 return null; | |
93 } | |
94 | |
95 /** | |
96 * Return the declaration of the method with the given [methodName] in the | |
97 * class with the given [className] in the given compilation [unit]. | |
98 */ | |
99 static MethodDeclaration getMethodInClass( | |
100 CompilationUnit unit, String className, String methodName) { | |
101 ClassDeclaration unitMember = getClass(unit, className); | |
102 NodeList<ClassMember> classMembers = unitMember.members; | |
103 for (ClassMember classMember in classMembers) { | |
104 if (classMember is MethodDeclaration) { | |
105 if (classMember.name.name == methodName) { | |
106 return classMember; | |
107 } | |
108 } | |
109 } | |
110 fail('No method named $methodName in $className'); | |
111 return null; | |
112 } | |
113 | |
114 /** | |
115 * Return the statements in the body of a the method with the given | |
116 * [methodName] in the class with the given [className] in the given | |
117 * compilation [unit]. | |
118 */ | |
119 static List<Statement> getStatementsInMethod( | |
120 CompilationUnit unit, String className, String methodName) { | |
121 MethodDeclaration method = getMethodInClass(unit, className, methodName); | |
122 BlockFunctionBody body = method.body; | |
123 return body.block.statements; | |
124 } | |
125 | |
126 /** | |
127 * Return the statements in the body of the top-level function with the given | |
128 * [functionName] in the given compilation [unit]. | |
129 */ | |
130 static List<Statement> getStatementsInTopLevelFunction( | |
131 CompilationUnit unit, String functionName) { | |
132 FunctionDeclaration function = getTopLevelFunction(unit, functionName); | |
133 BlockFunctionBody body = function.functionExpression.body; | |
134 return body.block.statements; | |
135 } | |
136 | |
137 /** | |
138 * Return the declaration of the top-level function with the given | |
139 * [functionName] in the given compilation [unit]. | |
140 */ | |
141 static FunctionDeclaration getTopLevelFunction( | |
142 CompilationUnit unit, String functionName) { | |
143 NodeList<CompilationUnitMember> unitMembers = unit.declarations; | |
144 for (CompilationUnitMember unitMember in unitMembers) { | |
145 if (unitMember is FunctionDeclaration) { | |
146 if (unitMember.name.name == functionName) { | |
147 return unitMember; | |
148 } | |
149 } | |
150 } | |
151 fail('No toplevel function named $functionName found'); | |
152 return null; | |
153 } | |
154 | |
155 /** | |
156 * Return the declaration of the top-level variable with the given | |
157 * [variableName] in the given compilation [unit]. | |
158 */ | |
159 static VariableDeclaration getTopLevelVariable( | |
160 CompilationUnit unit, String variableName) { | |
161 NodeList<CompilationUnitMember> unitMembers = unit.declarations; | |
162 for (CompilationUnitMember unitMember in unitMembers) { | |
163 if (unitMember is TopLevelVariableDeclaration) { | |
164 NodeList<VariableDeclaration> variables = | |
165 unitMember.variables.variables; | |
166 for (VariableDeclaration variable in variables) { | |
167 if (variable.name.name == variableName) { | |
168 return variable; | |
169 } | |
170 } | |
171 } | |
172 } | |
173 fail('No toplevel variable named $variableName found'); | |
174 return null; | |
175 } | |
176 } | |
177 | |
178 /** Class for compositionally building up assertions on types | |
179 */ | |
180 class TypeAssertions { | |
Jennifer Messerly
2015/11/23 22:11:58
note: it'd be slightly nicer to make these be Matc
Leaf
2015/12/01 21:49:12
Added TODO. Nice to know
| |
181 /* Provides primitive types for basic type assertions */ | |
182 final TypeProvider _typeProvider; | |
183 | |
184 TypeAssertions(this._typeProvider); | |
185 | |
186 /** Primitive assertion for the dynamic type */ | |
187 Asserter<DartType> get isDynamic => isType(_typeProvider.dynamicType); | |
188 | |
189 /** Primitive assertion for the int type */ | |
190 Asserter<DartType> get isInt => isType(_typeProvider.intType); | |
191 | |
192 /** Primitive assertion for the list type | |
193 */ | |
194 Asserter<DartType> get isList => sameElement(_typeProvider.listType); | |
195 | |
196 /** Primitive assertion for the map type | |
197 */ | |
198 Asserter<DartType> get isMap => sameElement(_typeProvider.mapType); | |
199 | |
200 /** Primitive assertion for the num type */ | |
201 Asserter<DartType> get isNum => isType(_typeProvider.numType); | |
202 | |
203 /** Primitive assertion for the string type */ | |
204 Asserter<DartType> get isString => isType(_typeProvider.stringType); | |
205 | |
206 /** Given a type, produce an assertion that a type has the same element. | |
207 */ | |
208 Asserter<DartType> hasElement(Element element) => | |
209 (DartType type) => expect(element, same(type.element)); | |
210 | |
211 /** Given assertions for the argument and return types, produce an | |
Brian Wilkerson
2015/11/21 16:12:22
Format the file?
Leaf
2015/12/01 21:49:12
Filed https://github.com/dart-lang/dart_style/issu
| |
212 * assertion over unary function types. | |
213 */ | |
214 Asserter<DartType> isFunction2Of( | |
215 Asserter<DartType> argType, Asserter<DartType> returnType) => | |
216 (DartType type) { | |
217 FunctionType fType = (type as FunctionType); | |
218 argType(fType.normalParameterTypes[0]); | |
219 returnType(fType.returnType); | |
220 }; | |
221 | |
222 /** Given an assertion for the base type and assertions over the type | |
223 * parameters, produce an assertion over instantations. | |
224 */ | |
225 AsserterBuilder<List<Asserter<DartType>>, DartType> isInstantiationOf( | |
226 Asserter<DartType> baseAssert) => | |
227 (List<Asserter<DartType>> argAsserts) => (DartType type) { | |
228 InterfaceType t = (type as InterfaceType); | |
229 baseAssert(t); | |
230 List<DartType> typeArguments = t.typeArguments; | |
231 expect(typeArguments, hasLength(argAsserts.length)); | |
232 for (int i = 0; i < typeArguments.length; i++) { | |
233 argAsserts[i](typeArguments[i]); | |
234 } | |
235 }; | |
236 | |
237 /** Assert that a type is the List type, and that the given assertion holds | |
238 * over the type parameter. | |
239 */ | |
240 Asserter<InterfaceType> isListOf(Asserter<DartType> argAssert) => | |
241 isInstantiationOf(isList)([argAssert]); | |
242 | |
243 /** Assert that a type is the Map type, and that the given assertions hold | |
244 * over the type parameters. | |
245 */ | |
246 Asserter<InterfaceType> isMapOf( | |
247 Asserter<DartType> argAssert0, Asserter<DartType> argAssert1) => | |
248 isInstantiationOf(isMap)([argAssert0, argAssert1]); | |
249 | |
250 /** Assert that one type is the same as another | |
251 */ | |
252 Asserter<DartType> isType(DartType argument) => (DartType t) { | |
253 expect(t, same(argument)); | |
254 }; | |
255 | |
256 /** Given a type, produce an assertion that a type has the same element. | |
257 */ | |
258 Asserter<DartType> sameElement(DartType elementType) => | |
259 hasElement(elementType.element); | |
260 } | |
OLD | NEW |