OLD | NEW |
| (Empty) |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | |
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. | |
4 | |
5 library test.services.src.search.search_engine; | |
6 | |
7 import 'dart:async'; | |
8 | |
9 import 'package:analysis_services/index/index.dart'; | |
10 import 'package:analysis_services/index/local_memory_index.dart'; | |
11 import 'package:analysis_services/search/search_engine.dart'; | |
12 import 'package:analysis_services/src/search/search_engine.dart'; | |
13 import 'package:analysis_testing/abstract_single_unit.dart'; | |
14 import 'package:analysis_testing/mocks.dart'; | |
15 import 'package:analysis_testing/reflective_tests.dart'; | |
16 import 'package:analyzer/src/generated/element.dart'; | |
17 import 'package:analyzer/src/generated/source.dart'; | |
18 import 'package:typed_mock/typed_mock.dart'; | |
19 import 'package:unittest/unittest.dart'; | |
20 | |
21 | |
22 main() { | |
23 groupSep = ' | '; | |
24 runReflectiveTests(SearchEngineImplTest); | |
25 } | |
26 | |
27 class ExpectedMatch { | |
28 final Element element; | |
29 final MatchKind kind; | |
30 SourceRange range; | |
31 final bool isResolved; | |
32 final bool isQualified; | |
33 | |
34 ExpectedMatch(this.element, this.kind, int offset, int length, | |
35 {this.isResolved: true, this.isQualified: false}) { | |
36 this.range = new SourceRange(offset, length); | |
37 } | |
38 | |
39 bool operator ==(SearchMatch match) { | |
40 return match.element == this.element && | |
41 match.kind == this.kind && | |
42 match.isResolved == this.isResolved && | |
43 match.isQualified == this.isQualified && | |
44 match.sourceRange == this.range; | |
45 } | |
46 | |
47 @override | |
48 String toString() { | |
49 StringBuffer buffer = new StringBuffer(); | |
50 buffer.write("ExpectedMatch(kind="); | |
51 buffer.write(kind); | |
52 buffer.write(", element="); | |
53 buffer.write(element != null ? element.displayName : 'null'); | |
54 buffer.write(", range="); | |
55 buffer.write(range); | |
56 buffer.write(", isResolved="); | |
57 buffer.write(isResolved); | |
58 buffer.write(", isQualified="); | |
59 buffer.write(isQualified); | |
60 buffer.write(")"); | |
61 return buffer.toString(); | |
62 } | |
63 } | |
64 | |
65 | |
66 class MockAngularComponentElement extends TypedMock implements | |
67 AngularComponentElement { | |
68 final kind = ElementKind.ANGULAR_COMPONENT; | |
69 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); | |
70 } | |
71 | |
72 | |
73 class MockAngularControllerElement extends TypedMock implements | |
74 AngularControllerElement { | |
75 final kind = ElementKind.ANGULAR_CONTROLLER; | |
76 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); | |
77 } | |
78 | |
79 | |
80 class MockAngularFormatterElement extends TypedMock implements | |
81 AngularFormatterElement { | |
82 final kind = ElementKind.ANGULAR_FORMATTER; | |
83 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); | |
84 } | |
85 | |
86 | |
87 class MockIndex extends TypedMock implements Index { | |
88 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); | |
89 } | |
90 | |
91 | |
92 @ReflectiveTestCase() | |
93 class SearchEngineImplTest extends AbstractSingleUnitTest { | |
94 Index index; | |
95 SearchEngineImpl searchEngine; | |
96 | |
97 void setUp() { | |
98 super.setUp(); | |
99 index = createLocalMemoryIndex(); | |
100 searchEngine = new SearchEngineImpl(index); | |
101 } | |
102 | |
103 Future test_searchElementDeclarations() { | |
104 _indexTestUnit(''' | |
105 class A { | |
106 test() {} | |
107 } | |
108 class B { | |
109 int test = 1; | |
110 main() { | |
111 int test = 2; | |
112 } | |
113 } | |
114 '''); | |
115 ClassElement elementA = findElement('A'); | |
116 ClassElement elementB = findElement('B'); | |
117 Element element_test = findElement('test', ElementKind.LOCAL_VARIABLE); | |
118 var expected = [ | |
119 _expectId(elementA.methods[0], MatchKind.DECLARATION, 'test() {}'), | |
120 _expectId(elementB.fields[0], MatchKind.DECLARATION, 'test = 1;'), | |
121 _expectId(element_test, MatchKind.DECLARATION, 'test = 2;'),]; | |
122 return searchEngine.searchElementDeclarations('test').then((matches) { | |
123 _assertMatches(matches, expected); | |
124 }); | |
125 } | |
126 | |
127 Future test_searchMemberDeclarations() { | |
128 _indexTestUnit(''' | |
129 class A { | |
130 test() {} | |
131 } | |
132 class B { | |
133 int test = 1; | |
134 main() { | |
135 int test = 2; | |
136 } | |
137 } | |
138 '''); | |
139 ClassElement elementA = findElement('A'); | |
140 ClassElement elementB = findElement('B'); | |
141 var expected = [ | |
142 _expectId(elementA.methods[0], MatchKind.DECLARATION, 'test() {}'), | |
143 _expectId(elementB.fields[0], MatchKind.DECLARATION, 'test = 1;')]; | |
144 return searchEngine.searchMemberDeclarations('test').then((matches) { | |
145 _assertMatches(matches, expected); | |
146 }); | |
147 } | |
148 | |
149 Future test_searchMemberReferences() { | |
150 _indexTestUnit(''' | |
151 class A { | |
152 var test; // A | |
153 mainA() { | |
154 test(); // a-inv-r-nq | |
155 test = 1; // a-write-r-nq | |
156 test += 2; // a-read-write-r-nq | |
157 print(test); // a-read-r-nq | |
158 } | |
159 } | |
160 main(A a, p) { | |
161 a.test(); // a-inv-r-q | |
162 a.test = 1; // a-write-r-q | |
163 a.test += 2; // a-read-write-r-q | |
164 print(a.test); // a-read-r-q | |
165 p.test(); // p-inv-ur-q | |
166 p.test = 1; // p-write-ur-q | |
167 p.test += 2; // p-read-write-ur-q | |
168 print(p.test); // p-read-ur-q | |
169 } | |
170 '''); | |
171 ClassElement elementA = findElement('A'); | |
172 ClassElement elementB = findElement('B'); | |
173 Element mainA = findElement('mainA'); | |
174 Element main = findElement('main'); | |
175 var expected = [ | |
176 _expectId(mainA, MatchKind.INVOCATION, 'test(); // a-inv-r-nq'), | |
177 _expectId(mainA, MatchKind.WRITE, 'test = 1; // a-write-r-nq'), | |
178 _expectId(mainA, MatchKind.READ_WRITE, 'test += 2; // a-read-write-r-nq'
), | |
179 _expectId(mainA, MatchKind.READ, 'test); // a-read-r-nq'), | |
180 _expectIdQ(main, MatchKind.INVOCATION, 'test(); // a-inv-r-q'), | |
181 _expectIdQ(main, MatchKind.WRITE, 'test = 1; // a-write-r-q'), | |
182 _expectIdQ(main, MatchKind.READ_WRITE, 'test += 2; // a-read-write-r-q')
, | |
183 _expectIdQ(main, MatchKind.READ, 'test); // a-read-r-q'), | |
184 _expectIdU(main, MatchKind.INVOCATION, 'test(); // p-inv-ur-q'), | |
185 _expectIdU(main, MatchKind.WRITE, 'test = 1; // p-write-ur-q'), | |
186 _expectIdU(main, MatchKind.READ_WRITE, 'test += 2; // p-read-write-ur-q'
), | |
187 _expectIdU(main, MatchKind.READ, 'test); // p-read-ur-q'),]; | |
188 return searchEngine.searchMemberReferences('test').then((matches) { | |
189 _assertMatches(matches, expected); | |
190 }); | |
191 } | |
192 | |
193 Future test_searchReferences_AngularComponentElement() { | |
194 // use mocks | |
195 index = new MockIndex(); | |
196 searchEngine = new SearchEngineImpl(index); | |
197 Element elementA = new MockElement('A'); | |
198 Element elementB = new MockElement('B'); | |
199 // fill mocks | |
200 AngularComponentElement element = new MockAngularComponentElement(); | |
201 void mockLocation(Element element, Relationship relationship, | |
202 Location location) { | |
203 index.getRelationships(element, relationship); | |
204 when(null).thenReturn(new Future.value([location])); | |
205 } | |
206 mockLocation( | |
207 element, | |
208 IndexConstants.ANGULAR_REFERENCE, | |
209 new Location(elementA, 1, 10)); | |
210 mockLocation( | |
211 element, | |
212 IndexConstants.ANGULAR_CLOSING_TAG_REFERENCE, | |
213 new Location(elementB, 2, 20)); | |
214 var expected = [ | |
215 new ExpectedMatch(elementA, MatchKind.ANGULAR_REFERENCE, 1, 10), | |
216 new ExpectedMatch(elementB, MatchKind.ANGULAR_CLOSING_TAG_REFERENCE, 2,
20)]; | |
217 return _verifyReferences(element, expected); | |
218 } | |
219 | |
220 Future test_searchReferences_ClassElement() { | |
221 _indexTestUnit(''' | |
222 class A {} | |
223 main(A p) { | |
224 A v; | |
225 } | |
226 '''); | |
227 ClassElement element = findElement('A'); | |
228 Element pElement = findElement('p'); | |
229 Element vElement = findElement('v'); | |
230 var expected = [ | |
231 _expectId(pElement, MatchKind.REFERENCE, 'A p'), | |
232 _expectId(vElement, MatchKind.REFERENCE, 'A v')]; | |
233 return _verifyReferences(element, expected); | |
234 } | |
235 | |
236 Future test_searchReferences_CompilationUnitElement() { | |
237 addSource('/my_part.dart', ''' | |
238 part of lib; | |
239 '''); | |
240 _indexTestUnit(''' | |
241 library lib; | |
242 part 'my_part.dart'; | |
243 '''); | |
244 CompilationUnitElement element = testLibraryElement.parts[0]; | |
245 var expected = [ | |
246 _expectId( | |
247 testUnitElement, | |
248 MatchKind.REFERENCE, | |
249 "'my_part.dart'", | |
250 length: "'my_part.dart'".length)]; | |
251 return _verifyReferences(element, expected); | |
252 } | |
253 | |
254 Future test_searchReferences_ConstructorElement() { | |
255 _indexTestUnit(''' | |
256 class A { | |
257 A.named() {} | |
258 } | |
259 main() { | |
260 new A.named(); | |
261 } | |
262 '''); | |
263 ConstructorElement element = findElement('named'); | |
264 ClassElement elementA = findElement('A'); | |
265 Element mainElement = findElement('main'); | |
266 var expected = [ | |
267 _expectId(elementA, MatchKind.DECLARATION, '.named() {}', length: 6), | |
268 _expectId(mainElement, MatchKind.REFERENCE, '.named();', length: 6)]; | |
269 return _verifyReferences(element, expected); | |
270 } | |
271 | |
272 Future test_searchReferences_Element_unknown() { | |
273 return _verifyReferences(UniverseElement.INSTANCE, []); | |
274 } | |
275 | |
276 Future test_searchReferences_FieldElement() { | |
277 _indexTestUnit(''' | |
278 class A { | |
279 var field; | |
280 A({this.field}); | |
281 main() { | |
282 new A(field: 1); | |
283 // getter | |
284 print(field); // ref-nq | |
285 print(this.field); // ref-q | |
286 field(); // inv-nq | |
287 this.field(); // inv-q | |
288 // setter | |
289 field = 2; // ref-nq; | |
290 this.field = 3; // ref-q; | |
291 } | |
292 } | |
293 '''); | |
294 FieldElement element = findElement('field'); | |
295 Element main = findElement('main'); | |
296 Element fieldParameter = findElement('field', ElementKind.PARAMETER); | |
297 var expected = [ | |
298 _expectId(fieldParameter, MatchKind.REFERENCE, 'field}'), | |
299 _expectId(main, MatchKind.REFERENCE, 'field: 1'), | |
300 _expectId(main, MatchKind.READ, 'field); // ref-nq'), | |
301 _expectIdQ(main, MatchKind.READ, 'field); // ref-q'), | |
302 _expectId(main, MatchKind.INVOCATION, 'field(); // inv-nq'), | |
303 _expectIdQ(main, MatchKind.INVOCATION, 'field(); // inv-q'), | |
304 _expectId(main, MatchKind.WRITE, 'field = 2; // ref-nq'), | |
305 _expectIdQ(main, MatchKind.WRITE, 'field = 3; // ref-q'),]; | |
306 return _verifyReferences(element, expected); | |
307 } | |
308 | |
309 Future test_searchReferences_FunctionElement() { | |
310 _indexTestUnit(''' | |
311 test() {} | |
312 main() { | |
313 test(); | |
314 print(test); | |
315 } | |
316 '''); | |
317 FunctionElement element = findElement('test'); | |
318 Element mainElement = findElement('main'); | |
319 var expected = [ | |
320 _expectId(mainElement, MatchKind.INVOCATION, 'test();'), | |
321 _expectId(mainElement, MatchKind.REFERENCE, 'test);')]; | |
322 return _verifyReferences(element, expected); | |
323 } | |
324 | |
325 Future test_searchReferences_FunctionTypeAliasElement() { | |
326 _indexTestUnit(''' | |
327 typedef Test(); | |
328 main() { | |
329 Test a; | |
330 Test b; | |
331 } | |
332 '''); | |
333 FunctionTypeAliasElement element = findElement('Test'); | |
334 Element aElement = findElement('a'); | |
335 Element bElement = findElement('b'); | |
336 var expected = [ | |
337 _expectId(aElement, MatchKind.REFERENCE, 'Test a;'), | |
338 _expectId(bElement, MatchKind.REFERENCE, 'Test b;')]; | |
339 return _verifyReferences(element, expected); | |
340 } | |
341 | |
342 Future test_searchReferences_ImportElement_noPrefix() { | |
343 _indexTestUnit(''' | |
344 import 'dart:math'; | |
345 main() { | |
346 print(E); | |
347 } | |
348 '''); | |
349 ImportElement element = testLibraryElement.imports[0]; | |
350 Element mainElement = findElement('main'); | |
351 var kind = MatchKind.REFERENCE; | |
352 var expected = [_expectId(mainElement, kind, 'E);', length: 0)]; | |
353 return _verifyReferences(element, expected); | |
354 } | |
355 | |
356 Future test_searchReferences_ImportElement_withPrefix() { | |
357 _indexTestUnit(''' | |
358 import 'dart:math' as math; | |
359 main() { | |
360 print(math.PI); | |
361 } | |
362 '''); | |
363 ImportElement element = testLibraryElement.imports[0]; | |
364 Element mainElement = findElement('main'); | |
365 var kind = MatchKind.REFERENCE; | |
366 var expected = [ | |
367 _expectId(mainElement, kind, 'math.PI);', length: 'math.'.length)]; | |
368 return _verifyReferences(element, expected); | |
369 } | |
370 | |
371 Future test_searchReferences_LibraryElement() { | |
372 var codeA = 'part of lib; // A'; | |
373 var codeB = 'part of lib; // B'; | |
374 var sourceA = addSource('/unitA.dart', codeA); | |
375 var sourceB = addSource('/unitB.dart', codeB); | |
376 _indexTestUnit(''' | |
377 library lib; | |
378 part 'unitA.dart'; | |
379 part 'unitB.dart'; | |
380 '''); | |
381 LibraryElement element = testLibraryElement; | |
382 CompilationUnitElement elementA = element.parts[0]; | |
383 CompilationUnitElement elementB = element.parts[1]; | |
384 index.indexUnit(context, elementA.node); | |
385 index.indexUnit(context, elementB.node); | |
386 Element mainElement = findElement('main'); | |
387 var expected = [ | |
388 new ExpectedMatch( | |
389 elementA, | |
390 MatchKind.REFERENCE, | |
391 codeA.indexOf('lib; // A'), | |
392 'lib'.length), | |
393 new ExpectedMatch( | |
394 elementB, | |
395 MatchKind.REFERENCE, | |
396 codeB.indexOf('lib; // B'), | |
397 'lib'.length),]; | |
398 return _verifyReferences(element, expected); | |
399 } | |
400 | |
401 Future test_searchReferences_LocalVariableElement() { | |
402 _indexTestUnit(''' | |
403 main() { | |
404 var v; | |
405 v = 1; | |
406 v += 2; | |
407 print(v); | |
408 v(); | |
409 } | |
410 '''); | |
411 LocalVariableElement element = findElement('v'); | |
412 Element mainElement = findElement('main'); | |
413 var expected = [ | |
414 _expectId(mainElement, MatchKind.WRITE, 'v = 1;'), | |
415 _expectId(mainElement, MatchKind.READ_WRITE, 'v += 2;'), | |
416 _expectId(mainElement, MatchKind.READ, 'v);'), | |
417 _expectId(mainElement, MatchKind.INVOCATION, 'v();')]; | |
418 return _verifyReferences(element, expected); | |
419 } | |
420 | |
421 Future test_searchReferences_MethodElement() { | |
422 _indexTestUnit(''' | |
423 class A { | |
424 m() {} | |
425 main() { | |
426 m(); // 1 | |
427 this.m(); // 2 | |
428 print(m); // 3 | |
429 print(this.m); // 4 | |
430 } | |
431 } | |
432 '''); | |
433 MethodElement method = findElement('m'); | |
434 Element mainElement = findElement('main'); | |
435 var expected = [ | |
436 _expectId(mainElement, MatchKind.INVOCATION, 'm(); // 1'), | |
437 _expectIdQ(mainElement, MatchKind.INVOCATION, 'm(); // 2'), | |
438 _expectId(mainElement, MatchKind.REFERENCE, 'm); // 3'), | |
439 _expectIdQ(mainElement, MatchKind.REFERENCE, 'm); // 4')]; | |
440 return _verifyReferences(method, expected); | |
441 } | |
442 | |
443 Future test_searchReferences_MethodMember() { | |
444 _indexTestUnit(''' | |
445 class A<T> { | |
446 T m() => null; | |
447 } | |
448 main(A<int> a) { | |
449 a.m(); // ref | |
450 } | |
451 '''); | |
452 MethodMember method = findNodeElementAtString('m(); // ref'); | |
453 Element mainElement = findElement('main'); | |
454 var expected = [ | |
455 _expectIdQ(mainElement, MatchKind.INVOCATION, 'm(); // ref')]; | |
456 return _verifyReferences(method, expected); | |
457 } | |
458 | |
459 Future test_searchReferences_ParameterElement() { | |
460 _indexTestUnit(''' | |
461 foo({p}) { | |
462 p = 1; | |
463 p += 2; | |
464 print(p); | |
465 p(); | |
466 } | |
467 main() { | |
468 foo(p: 42); | |
469 } | |
470 '''); | |
471 ParameterElement element = findElement('p'); | |
472 Element fooElement = findElement('foo'); | |
473 Element mainElement = findElement('main'); | |
474 var expected = [ | |
475 _expectId(fooElement, MatchKind.WRITE, 'p = 1;'), | |
476 _expectId(fooElement, MatchKind.READ_WRITE, 'p += 2;'), | |
477 _expectId(fooElement, MatchKind.READ, 'p);'), | |
478 _expectId(fooElement, MatchKind.INVOCATION, 'p();'), | |
479 _expectId(mainElement, MatchKind.REFERENCE, 'p: 42')]; | |
480 return _verifyReferences(element, expected); | |
481 } | |
482 | |
483 Future test_searchReferences_PropertyAccessorElement_getter() { | |
484 _indexTestUnit(''' | |
485 class A { | |
486 get g => null; | |
487 main() { | |
488 g; // 1 | |
489 this.g; // 2 | |
490 } | |
491 } | |
492 '''); | |
493 PropertyAccessorElement element = findElement('g', ElementKind.GETTER); | |
494 Element mainElement = findElement('main'); | |
495 var expected = [ | |
496 _expectId(mainElement, MatchKind.REFERENCE, 'g; // 1'), | |
497 _expectIdQ(mainElement, MatchKind.REFERENCE, 'g; // 2')]; | |
498 return _verifyReferences(element, expected); | |
499 } | |
500 | |
501 Future test_searchReferences_PropertyAccessorElement_setter() { | |
502 _indexTestUnit(''' | |
503 class A { | |
504 set s(x) {} | |
505 main() { | |
506 s = 1; | |
507 this.s = 2; | |
508 } | |
509 } | |
510 '''); | |
511 PropertyAccessorElement element = findElement('s='); | |
512 Element mainElement = findElement('main'); | |
513 var expected = [ | |
514 _expectId(mainElement, MatchKind.REFERENCE, 's = 1'), | |
515 _expectIdQ(mainElement, MatchKind.REFERENCE, 's = 2')]; | |
516 return _verifyReferences(element, expected); | |
517 } | |
518 | |
519 Future test_searchReferences_TopLevelVariableElement() { | |
520 addSource('/lib.dart', ''' | |
521 library lib; | |
522 var V; | |
523 '''); | |
524 _indexTestUnit(''' | |
525 import 'lib.dart' show V; // imp | |
526 import 'lib.dart' as pref; | |
527 main() { | |
528 pref.V = 1; // q | |
529 print(pref.V); // q | |
530 pref.V(); // q | |
531 V = 1; // nq | |
532 print(V); // nq | |
533 V(); // nq | |
534 } | |
535 '''); | |
536 ImportElement importElement = testLibraryElement.imports[0]; | |
537 CompilationUnitElement impUnit = | |
538 importElement.importedLibrary.definingCompilationUnit; | |
539 TopLevelVariableElement variable = impUnit.topLevelVariables[0]; | |
540 Element main = findElement('main'); | |
541 var expected = [ | |
542 _expectId(testUnitElement, MatchKind.REFERENCE, 'V; // imp'), | |
543 _expectId(main, MatchKind.WRITE, 'V = 1; // q'), | |
544 _expectId(main, MatchKind.READ, 'V); // q'), | |
545 _expectId(main, MatchKind.INVOCATION, 'V(); // q'), | |
546 _expectId(main, MatchKind.WRITE, 'V = 1; // nq'), | |
547 _expectId(main, MatchKind.READ, 'V); // nq'), | |
548 _expectId(main, MatchKind.INVOCATION, 'V(); // nq'),]; | |
549 return _verifyReferences(variable, expected); | |
550 } | |
551 | |
552 Future test_searchReferences_TypeParameterElement() { | |
553 _indexTestUnit(''' | |
554 class A<T> { | |
555 main(T a, T b) {} | |
556 } | |
557 '''); | |
558 TypeParameterElement element = findElement('T'); | |
559 Element aElement = findElement('a'); | |
560 Element bElement = findElement('b'); | |
561 var expected = [ | |
562 _expectId(aElement, MatchKind.REFERENCE, 'T a'), | |
563 _expectId(bElement, MatchKind.REFERENCE, 'T b')]; | |
564 return _verifyReferences(element, expected); | |
565 } | |
566 | |
567 Future test_searchSubtypes() { | |
568 _indexTestUnit(''' | |
569 class T {} | |
570 class A extends T {} // A | |
571 class B = Object with T; // B | |
572 class C implements T {} // C | |
573 '''); | |
574 ClassElement element = findElement('T'); | |
575 ClassElement elementA = findElement('A'); | |
576 ClassElement elementB = findElement('B'); | |
577 ClassElement elementC = findElement('C'); | |
578 var expected = [ | |
579 _expectId(elementA, MatchKind.REFERENCE, 'T {} // A'), | |
580 _expectId(elementB, MatchKind.REFERENCE, 'T; // B'), | |
581 _expectId(elementC, MatchKind.REFERENCE, 'T {} // C')]; | |
582 return searchEngine.searchSubtypes(element).then((matches) { | |
583 _assertMatches(matches, expected); | |
584 }); | |
585 } | |
586 | |
587 Future test_searchTopLevelDeclarations() { | |
588 _indexTestUnit(''' | |
589 class A {} // A | |
590 class B = Object with A; | |
591 typedef C(); | |
592 D() {} | |
593 var E = null; | |
594 class NoMatchABCDE {} | |
595 '''); | |
596 NameElement element = new NameElement('test'); | |
597 Element topA = findElement('A'); | |
598 Element topB = findElement('B'); | |
599 Element topC = findElement('C'); | |
600 Element topD = findElement('D'); | |
601 Element topE = findElement('E'); | |
602 Element topNoMatch = new MockElement('NoMatchABCDE'); | |
603 var expected = [ | |
604 _expectId(topA, MatchKind.DECLARATION, 'A {} // A'), | |
605 _expectId(topB, MatchKind.DECLARATION, 'B ='), | |
606 _expectId(topC, MatchKind.DECLARATION, 'C()'), | |
607 _expectId(topD, MatchKind.DECLARATION, 'D() {}'), | |
608 _expectId(topE, MatchKind.DECLARATION, 'E = null')]; | |
609 return _verifyTopLevelDeclarations('^[A-E]\$', expected); | |
610 } | |
611 | |
612 ExpectedMatch _expectId(Element element, MatchKind kind, String search, | |
613 {int length, bool isResolved: true, bool isQualified: false}) { | |
614 int offset = findOffset(search); | |
615 if (length == null) { | |
616 length = getLeadingIdentifierLength(search); | |
617 } | |
618 return new ExpectedMatch( | |
619 element, | |
620 kind, | |
621 offset, | |
622 length, | |
623 isResolved: isResolved, | |
624 isQualified: isQualified); | |
625 } | |
626 | |
627 ExpectedMatch _expectIdQ(Element element, MatchKind kind, String search) { | |
628 return _expectId(element, kind, search, isQualified: true); | |
629 } | |
630 | |
631 ExpectedMatch _expectIdU(Element element, MatchKind kind, String search) { | |
632 return _expectId( | |
633 element, | |
634 kind, | |
635 search, | |
636 isQualified: true, | |
637 isResolved: false); | |
638 } | |
639 | |
640 void _indexTestUnit(String code) { | |
641 resolveTestUnit(code); | |
642 index.indexUnit(context, testUnit); | |
643 } | |
644 | |
645 Future _verifyReferences(Element element, | |
646 List<ExpectedMatch> expectedMatches) { | |
647 return searchEngine.searchReferences( | |
648 element).then((List<SearchMatch> matches) { | |
649 _assertMatches(matches, expectedMatches); | |
650 }); | |
651 } | |
652 | |
653 Future _verifyTopLevelDeclarations(String pattern, | |
654 List<ExpectedMatch> expectedMatches) { | |
655 return searchEngine.searchTopLevelDeclarations( | |
656 pattern).then((List<SearchMatch> matches) { | |
657 _assertMatches(matches, expectedMatches); | |
658 }); | |
659 } | |
660 | |
661 static void _assertMatches(List<SearchMatch> matches, | |
662 List<ExpectedMatch> expectedMatches) { | |
663 expect(matches, unorderedEquals(expectedMatches)); | |
664 } | |
665 } | |
OLD | NEW |