Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(222)

Side by Side Diff: pkg/analysis_server/test/index/store/split_store_test.dart

Issue 365193004: Move Index and IndexStore implementations into Engine. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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.index.split_store;
6
7 import 'dart:async';
8
9 import 'package:analysis_server/src/index/store/codec.dart';
10 import 'package:analysis_server/src/index/store/split_store.dart';
11 import 'package:analyzer/src/generated/element.dart';
12 import 'package:analyzer/src/generated/engine.dart';
13 import 'package:analyzer/src/generated/index.dart';
14 import 'package:analyzer/src/generated/source.dart';
15 import 'package:typed_mock/typed_mock.dart';
16 import 'package:unittest/unittest.dart';
17
18 import '../../reflective_tests.dart';
19 import 'memory_node_manager.dart';
20 import 'single_source_container.dart';
21 import 'typed_mocks.dart';
22
23
24 main() {
25 groupSep = ' | ';
26 group('FileNodeManager', () {
27 runReflectiveTests(_FileNodeManagerTest);
28 });
29 group('IndexNode', () {
30 runReflectiveTests(_IndexNodeTest);
31 });
32 group('LocationData', () {
33 runReflectiveTests(_LocationDataTest);
34 });
35 group('RelationKeyData', () {
36 runReflectiveTests(_RelationKeyDataTest);
37 });
38 group('SplitIndexStore', () {
39 runReflectiveTests(_SplitIndexStoreTest);
40 });
41 }
42
43
44 void _assertHasLocation(List<Location> locations, Element element, int offset,
45 int length) {
46 for (Location location in locations) {
47 if ((element == null || location.element == element) && location.offset ==
48 offset && location.length == length) {
49 return;
50 }
51 }
52 fail('Expected to find Location'
53 '(element=$element, offset=$offset, length=$length)');
54 }
55
56
57 @ReflectiveTestCase()
58 class _FileNodeManagerTest {
59 AnalysisContext context = new MockAnalysisContext('context');
60 ContextCodec contextCodec = new MockContextCodec();
61 int contextId = 13;
62 ElementCodec elementCodec = new MockElementCodec();
63 FileManager fileManager = new _MockFileManager();
64 MockLogger logger = new MockLogger();
65 int nextElementId = 0;
66 FileNodeManager nodeManager;
67 RelationshipCodec relationshipCodec;
68 StringCodec stringCodec = new StringCodec();
69
70 void setUp() {
71 relationshipCodec = new RelationshipCodec(stringCodec);
72 nodeManager = new FileNodeManager(fileManager, logger, stringCodec,
73 contextCodec, elementCodec, relationshipCodec);
74 when(contextCodec.encode(context)).thenReturn(contextId);
75 when(contextCodec.decode(contextId)).thenReturn(context);
76 }
77
78 void test_clear() {
79 nodeManager.clear();
80 verify(fileManager.clear()).once();
81 }
82
83 void test_getLocationCount_empty() {
84 expect(nodeManager.locationCount, 0);
85 }
86
87 void test_getNode_contextNull() {
88 String name = '42.index';
89 // record bytes
90 List<int> bytes;
91 when(fileManager.write(name, anyObject)).thenInvoke((name, bs) {
92 bytes = bs;
93 });
94 // put Node
95 Future putFuture;
96 {
97 IndexNode node = new IndexNode(context, elementCodec, relationshipCodec);
98 putFuture = nodeManager.putNode(name, node);
99 }
100 // do in the "put" Future
101 putFuture.then((_) {
102 // force "null" context
103 when(contextCodec.decode(contextId)).thenReturn(null);
104 // prepare input bytes
105 when(fileManager.read(name)).thenReturn(new Future.value(bytes));
106 // get Node
107 return nodeManager.getNode(name).then((IndexNode node) {
108 expect(node, isNull);
109 // no exceptions
110 verifyZeroInteractions(logger);
111 });
112 });
113 }
114
115 test_getNode_invalidVersion() {
116 String name = '42.index';
117 // prepare a stream with an invalid version
118 when(fileManager.read(name)).thenReturn(new Future.value([0x01, 0x02, 0x03,
119 0x04]));
120 // do in the Future
121 return nodeManager.getNode(name).then((IndexNode node) {
122 // no IndexNode
123 expect(node, isNull);
124 // failed
125 verify(logger.logError2(anyObject, anyObject)).once();
126 });
127 }
128
129 test_getNode_streamException() {
130 String name = '42.index';
131 when(fileManager.read(name)).thenReturn(new Future(() {
132 return throw new Exception();
133 }));
134 // do in the Future
135 return nodeManager.getNode(name).then((IndexNode node) {
136 expect(node, isNull);
137 // failed
138 verify(logger.logError2(anyString, anyObject)).once();
139 });
140 }
141
142 test_getNode_streamNull() {
143 String name = '42.index';
144 when(fileManager.read(name)).thenReturn(new Future.value(null));
145 // do in the Future
146 return nodeManager.getNode(name).then((IndexNode node) {
147 expect(node, isNull);
148 // OK
149 verifyZeroInteractions(logger);
150 });
151 }
152
153 void test_newNode() {
154 IndexNode node = nodeManager.newNode(context);
155 expect(node.context, context);
156 expect(node.locationCount, 0);
157 }
158
159 test_putNode_getNode() {
160 String name = '42.index';
161 // record bytes
162 List<int> bytes;
163 when(fileManager.write(name, anyObject)).thenInvoke((name, bs) {
164 bytes = bs;
165 });
166 // prepare elements
167 Element elementA = _mockElement();
168 Element elementB = _mockElement();
169 Element elementC = _mockElement();
170 Relationship relationship = Relationship.getRelationship('my-relationship');
171 // put Node
172 Future putFuture;
173 {
174 // prepare relations
175 int elementIdA = 0;
176 int elementIdB = 1;
177 int elementIdC = 2;
178 int relationshipId = relationshipCodec.encode(relationship);
179 RelationKeyData key = new RelationKeyData.forData(elementIdA,
180 relationshipId);
181 List<LocationData> locations = [new LocationData.forData(elementIdB, 1,
182 10), new LocationData.forData(elementIdC, 2, 20)];
183 Map<RelationKeyData, List<LocationData>> relations = {
184 key: locations
185 };
186 // prepare Node
187 IndexNode node = new _MockIndexNode();
188 when(node.context).thenReturn(context);
189 when(node.relations).thenReturn(relations);
190 when(node.locationCount).thenReturn(2);
191 // put Node
192 putFuture = nodeManager.putNode(name, node);
193 }
194 // do in the Future
195 putFuture.then((_) {
196 // has locations
197 expect(nodeManager.locationCount, 2);
198 // prepare input bytes
199 when(fileManager.read(name)).thenReturn(new Future.value(bytes));
200 // get Node
201 return nodeManager.getNode(name).then((IndexNode node) {
202 expect(2, node.locationCount);
203 {
204 List<Location> locations = node.getRelationships(elementA,
205 relationship);
206 expect(locations, hasLength(2));
207 _assertHasLocation(locations, elementB, 1, 10);
208 _assertHasLocation(locations, elementC, 2, 20);
209 }
210 });
211 });
212 }
213
214 test_putNode_streamException() {
215 String name = '42.index';
216 Exception exception = new Exception();
217 when(fileManager.write(name, anyObject)).thenReturn(new Future(() {
218 return throw exception;
219 }));
220 // prepare IndexNode
221 IndexNode node = new _MockIndexNode();
222 when(node.context).thenReturn(context);
223 when(node.locationCount).thenReturn(0);
224 when(node.relations).thenReturn({});
225 // try to put
226 return nodeManager.putNode(name, node).then((_) {
227 // failed
228 verify(logger.logError2(anyString, anyObject)).once();
229 });
230 }
231
232 void test_removeNode() {
233 String name = '42.index';
234 nodeManager.removeNode(name);
235 verify(fileManager.delete(name)).once();
236 }
237
238 Element _mockElement() {
239 int elementId = nextElementId++;
240 Element element = new MockElement();
241 when(elementCodec.encode(element)).thenReturn(elementId);
242 when(elementCodec.decode(context, elementId)).thenReturn(element);
243 return element;
244 }
245 }
246
247
248 @ReflectiveTestCase()
249 class _IndexNodeTest {
250 AnalysisContext context = new MockAnalysisContext('context');
251 ElementCodec elementCodec = new MockElementCodec();
252 int nextElementId = 0;
253 IndexNode node;
254 RelationshipCodec relationshipCodec;
255 StringCodec stringCodec = new StringCodec();
256
257 void setUp() {
258 relationshipCodec = new RelationshipCodec(stringCodec);
259 node = new IndexNode(context, elementCodec, relationshipCodec);
260 }
261
262 void test_getContext() {
263 expect(node.context, context);
264 }
265
266 void test_recordRelationship() {
267 Element elementA = _mockElement();
268 Element elementB = _mockElement();
269 Element elementC = _mockElement();
270 Relationship relationship = Relationship.getRelationship('my-relationship');
271 Location locationA = new Location(elementB, 1, 2);
272 Location locationB = new Location(elementC, 10, 20);
273 // empty initially
274 expect(node.locationCount, 0);
275 // record
276 node.recordRelationship(elementA, relationship, locationA);
277 expect(node.locationCount, 1);
278 node.recordRelationship(elementA, relationship, locationB);
279 expect(node.locationCount, 2);
280 // get relations
281 expect(node.getRelationships(elementB, relationship), isEmpty);
282 {
283 List<Location> locations = node.getRelationships(elementA, relationship);
284 expect(locations, hasLength(2));
285 _assertHasLocation(locations, null, 1, 2);
286 _assertHasLocation(locations, null, 10, 20);
287 }
288 // verify relations map
289 {
290 Map<RelationKeyData, List<LocationData>> relations = node.relations;
291 expect(relations, hasLength(1));
292 List<LocationData> locations = relations.values.first;
293 expect(locations, hasLength(2));
294 }
295 }
296
297 void test_setRelations() {
298 Element elementA = _mockElement();
299 Element elementB = _mockElement();
300 Element elementC = _mockElement();
301 Relationship relationship = Relationship.getRelationship('my-relationship');
302 // record
303 {
304 int elementIdA = 0;
305 int elementIdB = 1;
306 int elementIdC = 2;
307 int relationshipId = relationshipCodec.encode(relationship);
308 RelationKeyData key = new RelationKeyData.forData(elementIdA,
309 relationshipId);
310 List<LocationData> locations = [new LocationData.forData(elementIdB, 1,
311 10), new LocationData.forData(elementIdC, 2, 20)];
312 node.relations = {
313 key: locations
314 };
315 }
316 // request
317 List<Location> locations = node.getRelationships(elementA, relationship);
318 expect(locations, hasLength(2));
319 _assertHasLocation(locations, elementB, 1, 10);
320 _assertHasLocation(locations, elementC, 2, 20);
321 }
322
323 Element _mockElement() {
324 int elementId = nextElementId++;
325 Element element = new MockElement();
326 when(elementCodec.encode(element)).thenReturn(elementId);
327 when(elementCodec.decode(context, elementId)).thenReturn(element);
328 return element;
329 }
330 }
331
332
333 @ReflectiveTestCase()
334 class _LocationDataTest {
335 AnalysisContext context = new MockAnalysisContext('context');
336 ElementCodec elementCodec = new MockElementCodec();
337 StringCodec stringCodec = new StringCodec();
338
339 void test_newForData() {
340 Element element = new MockElement();
341 when(elementCodec.decode(context, 0)).thenReturn(element);
342 LocationData locationData = new LocationData.forData(0, 1, 2);
343 Location location = locationData.getLocation(context, elementCodec);
344 expect(location.element, element);
345 expect(location.offset, 1);
346 expect(location.length, 2);
347 }
348
349 void test_newForObject() {
350 // prepare Element
351 Element element = new MockElement();
352 when(elementCodec.encode(element)).thenReturn(42);
353 when(elementCodec.decode(context, 42)).thenReturn(element);
354 // create
355 Location location = new Location(element, 1, 2);
356 LocationData locationData = new LocationData.forObject(elementCodec,
357 location);
358 // touch 'hashCode'
359 locationData.hashCode;
360 // ==
361 expect(locationData == new LocationData.forData(42, 1, 2), isTrue);
362 // getLocation()
363 {
364 Location newLocation = locationData.getLocation(context, elementCodec);
365 expect(location.element, element);
366 expect(location.offset, 1);
367 expect(location.length, 2);
368 }
369 // no Element - no Location
370 {
371 when(elementCodec.decode(context, 42)).thenReturn(null);
372 Location newLocation = locationData.getLocation(context, elementCodec);
373 expect(newLocation, isNull);
374 }
375 }
376 }
377
378
379 /**
380 * [Location] has no [==] and [hashCode], so to compare locations by value we
381 * need to wrap them into such object.
382 */
383 class _LocationEqualsWrapper {
384 final Location location;
385
386 _LocationEqualsWrapper(this.location);
387
388 @override
389 int get hashCode {
390 return 31 * (31 * location.element.hashCode + location.offset) +
391 location.length;
392 }
393
394 @override
395 bool operator ==(Object other) {
396 if (other is _LocationEqualsWrapper) {
397 return other.location.offset == location.offset && other.location.length
398 == location.length && other.location.element == location.element;
399 }
400 return false;
401 }
402 }
403
404
405 class _MockFileManager extends TypedMock implements FileManager {
406 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
407 }
408
409
410 class _MockIndexNode extends TypedMock implements IndexNode {
411 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
412 }
413
414
415 @ReflectiveTestCase()
416 class _RelationKeyDataTest {
417 AnalysisContext context = new MockAnalysisContext('context');
418 ElementCodec elementCodec = new MockElementCodec();
419 RelationshipCodec relationshipCodec = new MockRelationshipCodec();
420 StringCodec stringCodec = new StringCodec();
421
422 void test_newFromData() {
423 RelationKeyData keyData = new RelationKeyData.forData(1, 2);
424 // equals
425 expect(keyData == this, isFalse);
426 expect(keyData == new RelationKeyData.forData(10, 20), isFalse);
427 expect(keyData == keyData, isTrue);
428 expect(keyData == new RelationKeyData.forData(1, 2), isTrue);
429 }
430
431 void test_newFromObjects() {
432 // prepare Element
433 Element element;
434 int elementId = 2;
435 {
436 element = new MockElement();
437 ElementLocation location = new ElementLocationImpl.con3(['foo', 'bar']);
438 when(element.location).thenReturn(location);
439 when(context.getElement(location)).thenReturn(element);
440 when(elementCodec.encode(element)).thenReturn(elementId);
441 }
442 // prepare relationship
443 Relationship relationship = Relationship.getRelationship('my-relationship');
444 int relationshipId = 1;
445 when(relationshipCodec.encode(relationship)).thenReturn(relationshipId);
446 // create RelationKeyData
447 RelationKeyData keyData = new RelationKeyData.forObject(elementCodec,
448 relationshipCodec, element, relationship);
449 // touch
450 keyData.hashCode;
451 // equals
452 expect(keyData == this, isFalse);
453 expect(keyData == new RelationKeyData.forData(10, 20), isFalse);
454 expect(keyData == keyData, isTrue);
455 expect(keyData == new RelationKeyData.forData(elementId, relationshipId),
456 isTrue);
457 }
458 }
459
460
461
462
463 @ReflectiveTestCase()
464 class _SplitIndexStoreTest {
465 AnalysisContext contextA = new MockAnalysisContext('contextA');
466
467 AnalysisContext contextB = new MockAnalysisContext('contextB');
468
469 AnalysisContext contextC = new MockAnalysisContext('contextC');
470
471 Element elementA = new MockElement('elementA');
472 Element elementB = new MockElement('elementB');
473
474 Element elementC = new MockElement('elementC');
475 Element elementD = new MockElement('elementD');
476 ElementLocation elementLocationA = new ElementLocationImpl.con3(
477 ['/home/user/sourceA.dart', 'ClassA']);
478 ElementLocation elementLocationB = new ElementLocationImpl.con3(
479 ['/home/user/sourceB.dart', 'ClassB']);
480 ElementLocation elementLocationC = new ElementLocationImpl.con3(
481 ['/home/user/sourceC.dart', 'ClassC']);
482 ElementLocation elementLocationD = new ElementLocationImpl.con3(
483 ['/home/user/sourceD.dart', 'ClassD']);
484 HtmlElement htmlElementA = new MockHtmlElement();
485 HtmlElement htmlElementB = new MockHtmlElement();
486 LibraryElement libraryElement = new MockLibraryElement();
487 Source librarySource = new MockSource('librarySource');
488 CompilationUnitElement libraryUnitElement = new MockCompilationUnitElement();
489 MemoryNodeManager nodeManager = new MemoryNodeManager();
490 Relationship relationship = Relationship.getRelationship('test-relationship');
491 Source sourceA = new MockSource('sourceA');
492 Source sourceB = new MockSource('sourceB');
493 Source sourceC = new MockSource('sourceC');
494 Source sourceD = new MockSource('sourceD');
495 SplitIndexStore store;
496 CompilationUnitElement unitElementA = new MockCompilationUnitElement();
497 CompilationUnitElement unitElementB = new MockCompilationUnitElement();
498 CompilationUnitElement unitElementC = new MockCompilationUnitElement();
499 CompilationUnitElement unitElementD = new MockCompilationUnitElement();
500 void setUp() {
501 store = new SplitIndexStore(nodeManager);
502 when(contextA.isDisposed).thenReturn(false);
503 when(contextB.isDisposed).thenReturn(false);
504 when(contextC.isDisposed).thenReturn(false);
505 when(contextA.getElement(elementLocationA)).thenReturn(elementA);
506 when(contextA.getElement(elementLocationB)).thenReturn(elementB);
507 when(contextA.getElement(elementLocationC)).thenReturn(elementC);
508 when(contextA.getElement(elementLocationD)).thenReturn(elementD);
509 when(sourceA.fullName).thenReturn('/home/user/sourceA.dart');
510 when(sourceB.fullName).thenReturn('/home/user/sourceB.dart');
511 when(sourceC.fullName).thenReturn('/home/user/sourceC.dart');
512 when(sourceD.fullName).thenReturn('/home/user/sourceD.dart');
513 when(elementA.context).thenReturn(contextA);
514 when(elementB.context).thenReturn(contextA);
515 when(elementC.context).thenReturn(contextA);
516 when(elementD.context).thenReturn(contextA);
517 when(elementA.location).thenReturn(elementLocationA);
518 when(elementB.location).thenReturn(elementLocationB);
519 when(elementC.location).thenReturn(elementLocationC);
520 when(elementD.location).thenReturn(elementLocationD);
521 when(elementA.enclosingElement).thenReturn(unitElementA);
522 when(elementB.enclosingElement).thenReturn(unitElementB);
523 when(elementC.enclosingElement).thenReturn(unitElementC);
524 when(elementD.enclosingElement).thenReturn(unitElementD);
525 when(elementA.source).thenReturn(sourceA);
526 when(elementB.source).thenReturn(sourceB);
527 when(elementC.source).thenReturn(sourceC);
528 when(elementD.source).thenReturn(sourceD);
529 when(elementA.library).thenReturn(libraryElement);
530 when(elementB.library).thenReturn(libraryElement);
531 when(elementC.library).thenReturn(libraryElement);
532 when(elementD.library).thenReturn(libraryElement);
533 when(unitElementA.source).thenReturn(sourceA);
534 when(unitElementB.source).thenReturn(sourceB);
535 when(unitElementC.source).thenReturn(sourceC);
536 when(unitElementD.source).thenReturn(sourceD);
537 when(unitElementA.library).thenReturn(libraryElement);
538 when(unitElementB.library).thenReturn(libraryElement);
539 when(unitElementC.library).thenReturn(libraryElement);
540 when(unitElementD.library).thenReturn(libraryElement);
541 when(htmlElementA.source).thenReturn(sourceA);
542 when(htmlElementB.source).thenReturn(sourceB);
543 // library
544 when(libraryUnitElement.library).thenReturn(libraryElement);
545 when(libraryUnitElement.source).thenReturn(librarySource);
546 when(libraryElement.source).thenReturn(librarySource);
547 when(libraryElement.definingCompilationUnit).thenReturn(libraryUnitElement);
548 }
549
550 void test_aboutToIndexDart_disposedContext() {
551 when(contextA.isDisposed).thenReturn(true);
552 expect(store.aboutToIndexDart(contextA, unitElementA), isFalse);
553 }
554
555 void test_aboutToIndexDart_disposedContext_wrapped() {
556 when(contextA.isDisposed).thenReturn(true);
557 InstrumentedAnalysisContextImpl instrumentedContext =
558 new MockInstrumentedAnalysisContextImpl();
559 when(instrumentedContext.basis).thenReturn(contextA);
560 expect(store.aboutToIndexDart(instrumentedContext, unitElementA), isFalse);
561 }
562
563 void test_aboutToIndexDart_library_first() {
564 when(libraryElement.parts).thenReturn(<CompilationUnitElement>[unitElementA,
565 unitElementB]);
566 {
567 store.aboutToIndexDart(contextA, libraryUnitElement);
568 store.doneIndex();
569 }
570 {
571 List<Location> locations = store.getRelationships(elementA, relationship);
572 assertLocations(locations, []);
573 }
574 }
575
576 test_aboutToIndexDart_library_secondWithoutOneUnit() {
577 Location locationA = mockLocation(elementA);
578 Location locationB = mockLocation(elementB);
579 {
580 store.aboutToIndexDart(contextA, unitElementA);
581 store.recordRelationship(elementA, relationship, locationA);
582 store.doneIndex();
583 }
584 {
585 store.aboutToIndexDart(contextA, unitElementB);
586 store.recordRelationship(elementA, relationship, locationB);
587 store.doneIndex();
588 }
589 // "A" and "B" locations
590 return store.getRelationshipsAsync(elementA, relationship).then(
591 (List<Location> locations) {
592 assertLocations(locations, [locationA, locationB]);
593 }).then((_) {
594 // apply "libraryUnitElement", only with "B"
595 when(libraryElement.parts).thenReturn([unitElementB]);
596 {
597 store.aboutToIndexDart(contextA, libraryUnitElement);
598 store.doneIndex();
599 }
600 return store.getRelationshipsAsync(elementA, relationship).then(
601 (List<Location> locations) {
602 assertLocations(locations, [locationB]);
603 });
604 });
605 }
606
607 void test_aboutToIndexDart_nullLibraryElement() {
608 when(unitElementA.library).thenReturn(null);
609 expect(store.aboutToIndexDart(contextA, unitElementA), isFalse);
610 }
611
612 void test_aboutToIndexDart_nullLibraryUnitElement() {
613 when(libraryElement.definingCompilationUnit).thenReturn(null);
614 expect(store.aboutToIndexDart(contextA, unitElementA), isFalse);
615 }
616
617 void test_aboutToIndexDart_nullUnitElement() {
618 expect(store.aboutToIndexDart(contextA, null), isFalse);
619 }
620
621 test_aboutToIndexHtml_() {
622 Location locationA = mockLocation(elementA);
623 Location locationB = mockLocation(elementB);
624 {
625 store.aboutToIndexHtml(contextA, htmlElementA);
626 store.recordRelationship(elementA, relationship, locationA);
627 store.doneIndex();
628 }
629 {
630 store.aboutToIndexHtml(contextA, htmlElementB);
631 store.recordRelationship(elementA, relationship, locationB);
632 store.doneIndex();
633 }
634 // "A" and "B" locations
635 return store.getRelationshipsAsync(elementA, relationship).then(
636 (List<Location> locations) {
637 assertLocations(locations, [locationA, locationB]);
638 });
639 }
640
641 void test_aboutToIndexHtml_disposedContext() {
642 when(contextA.isDisposed).thenReturn(true);
643 expect(store.aboutToIndexHtml(contextA, htmlElementA), isFalse);
644 }
645
646 void test_clear() {
647 Location locationA = mockLocation(elementA);
648 store.aboutToIndexDart(contextA, unitElementA);
649 store.recordRelationship(elementA, relationship, locationA);
650 store.doneIndex();
651 expect(nodeManager.isEmpty(), isFalse);
652 // clear
653 store.clear();
654 expect(nodeManager.isEmpty(), isTrue);
655 }
656
657 test_getRelationships_empty() {
658 return store.getRelationshipsAsync(elementA, relationship).then(
659 (List<Location> locations) {
660 expect(locations, isEmpty);
661 });
662 }
663
664 void test_getStatistics() {
665 // empty initially
666 {
667 String statistics = store.statistics;
668 expect(statistics, contains('0 locations'));
669 expect(statistics, contains('0 sources'));
670 }
671 // add 2 locations
672 Location locationA = mockLocation(elementA);
673 Location locationB = mockLocation(elementB);
674 {
675 store.aboutToIndexDart(contextA, unitElementA);
676 store.recordRelationship(elementA, relationship, locationA);
677 store.doneIndex();
678 }
679 {
680 store.aboutToIndexDart(contextA, unitElementB);
681 store.recordRelationship(elementA, relationship, locationB);
682 store.doneIndex();
683 }
684 {
685 String statistics = store.statistics;
686 expect(statistics, contains('2 locations'));
687 expect(statistics, contains('3 sources'));
688 }
689 }
690
691 void test_recordRelationship_nullElement() {
692 Location locationA = mockLocation(elementA);
693 store.recordRelationship(null, relationship, locationA);
694 store.doneIndex();
695 expect(nodeManager.isEmpty(), isTrue);
696 }
697
698 void test_recordRelationship_nullLocation() {
699 store.recordRelationship(elementA, relationship, null);
700 store.doneIndex();
701 expect(nodeManager.isEmpty(), isTrue);
702 }
703
704 test_recordRelationship_oneElement_twoNodes() {
705 Location locationA = mockLocation(elementA);
706 Location locationB = mockLocation(elementB);
707 {
708 store.aboutToIndexDart(contextA, unitElementA);
709 store.recordRelationship(elementA, relationship, locationA);
710 store.doneIndex();
711 }
712 {
713 store.aboutToIndexDart(contextA, unitElementB);
714 store.recordRelationship(elementA, relationship, locationB);
715 store.doneIndex();
716 }
717 return store.getRelationshipsAsync(elementA, relationship).then(
718 (List<Location> locations) {
719 assertLocations(locations, [locationA, locationB]);
720 });
721 }
722
723 test_recordRelationship_oneLocation() {
724 Location locationA = mockLocation(elementA);
725 store.aboutToIndexDart(contextA, unitElementA);
726 store.recordRelationship(elementA, relationship, locationA);
727 store.doneIndex();
728 return store.getRelationshipsAsync(elementA, relationship).then(
729 (List<Location> locations) {
730 assertLocations(locations, [locationA]);
731 });
732 }
733
734 test_recordRelationship_twoLocations() {
735 Location locationA = mockLocation(elementA);
736 Location locationB = mockLocation(elementA);
737 store.aboutToIndexDart(contextA, unitElementA);
738 store.recordRelationship(elementA, relationship, locationA);
739 store.recordRelationship(elementA, relationship, locationB);
740 store.doneIndex();
741 return store.getRelationshipsAsync(elementA, relationship).then(
742 (List<Location> locations) {
743 assertLocations(locations, [locationA, locationB]);
744 });
745 }
746
747 test_removeContext() {
748 Location locationA = mockLocation(elementA);
749 Location locationB = mockLocation(elementB);
750 {
751 store.aboutToIndexDart(contextA, unitElementA);
752 store.recordRelationship(elementA, relationship, locationA);
753 store.doneIndex();
754 }
755 {
756 store.aboutToIndexDart(contextA, unitElementB);
757 store.recordRelationship(elementA, relationship, locationB);
758 store.doneIndex();
759 }
760 // "A" and "B" locations
761 return store.getRelationshipsAsync(elementA, relationship).then(
762 (List<Location> locations) {
763 assertLocations(locations, [locationA, locationB]);
764 }).then((_) {
765 // remove "A" context
766 store.removeContext(contextA);
767 return store.getRelationshipsAsync(elementA, relationship).then(
768 (List<Location> locations) {
769 assertLocations(locations, []);
770 });
771 });
772 }
773
774 void test_removeContext_nullContext() {
775 store.removeContext(null);
776 }
777
778 test_removeSource_library() {
779 Location locationA = mockLocation(elementA);
780 Location locationB = mockLocation(elementB);
781 Location locationC = mockLocation(elementC);
782 {
783 store.aboutToIndexDart(contextA, unitElementA);
784 store.recordRelationship(elementA, relationship, locationA);
785 store.doneIndex();
786 }
787 {
788 store.aboutToIndexDart(contextA, unitElementB);
789 store.recordRelationship(elementA, relationship, locationB);
790 store.doneIndex();
791 }
792 {
793 store.aboutToIndexDart(contextA, unitElementC);
794 store.recordRelationship(elementA, relationship, locationC);
795 store.doneIndex();
796 }
797 // "A", "B" and "C" locations
798 return store.getRelationshipsAsync(elementA, relationship).then(
799 (List<Location> locations) {
800 assertLocations(locations, [locationA, locationB, locationC]);
801 }).then((_) {
802 // remove "librarySource"
803 store.removeSource(contextA, librarySource);
804 return store.getRelationshipsAsync(elementA, relationship).then(
805 (List<Location> locations) {
806 assertLocations(locations, []);
807 });
808 });
809 }
810
811 void test_removeSource_nullContext() {
812 store.removeSource(null, sourceA);
813 }
814
815 test_removeSource_unit() {
816 Location locationA = mockLocation(elementA);
817 Location locationB = mockLocation(elementB);
818 Location locationC = mockLocation(elementC);
819 {
820 store.aboutToIndexDart(contextA, unitElementA);
821 store.recordRelationship(elementA, relationship, locationA);
822 store.doneIndex();
823 }
824 {
825 store.aboutToIndexDart(contextA, unitElementB);
826 store.recordRelationship(elementA, relationship, locationB);
827 store.doneIndex();
828 }
829 {
830 store.aboutToIndexDart(contextA, unitElementC);
831 store.recordRelationship(elementA, relationship, locationC);
832 store.doneIndex();
833 }
834 // "A", "B" and "C" locations
835 return store.getRelationshipsAsync(elementA, relationship).then(
836 (List<Location> locations) {
837 assertLocations(locations, [locationA, locationB, locationC]);
838 }).then((_) {
839 // remove "A" source
840 store.removeSource(contextA, sourceA);
841 return store.getRelationshipsAsync(elementA, relationship).then(
842 (List<Location> locations) {
843 assertLocations(locations, [locationB, locationC]);
844 });
845 });
846 }
847
848 test_removeSources_library() {
849 Location locationA = mockLocation(elementA);
850 Location locationB = mockLocation(elementB);
851 {
852 store.aboutToIndexDart(contextA, unitElementA);
853 store.recordRelationship(elementA, relationship, locationA);
854 store.doneIndex();
855 }
856 {
857 store.aboutToIndexDart(contextA, unitElementB);
858 store.recordRelationship(elementA, relationship, locationB);
859 store.doneIndex();
860 }
861 // "A" and "B" locations
862 return store.getRelationshipsAsync(elementA, relationship).then(
863 (List<Location> locations) {
864 assertLocations(locations, [locationA, locationB]);
865 }).then((_) {
866 // remove "librarySource"
867 store.removeSources(contextA, new SingleSourceContainer(librarySource));
868 return store.getRelationshipsAsync(elementA, relationship).then(
869 (List<Location> locations) {
870 assertLocations(locations, []);
871 });
872 });
873 }
874
875 void test_removeSources_nullContext() {
876 store.removeSources(null, null);
877 }
878
879 test_removeSources_unit() {
880 Location locationA = mockLocation(elementA);
881 Location locationB = mockLocation(elementB);
882 Location locationC = mockLocation(elementC);
883 {
884 store.aboutToIndexDart(contextA, unitElementA);
885 store.recordRelationship(elementA, relationship, locationA);
886 store.doneIndex();
887 }
888 {
889 store.aboutToIndexDart(contextA, unitElementB);
890 store.recordRelationship(elementA, relationship, locationB);
891 store.doneIndex();
892 }
893 {
894 store.aboutToIndexDart(contextA, unitElementC);
895 store.recordRelationship(elementA, relationship, locationC);
896 store.doneIndex();
897 }
898 // "A", "B" and "C" locations
899 return store.getRelationshipsAsync(elementA, relationship).then(
900 (List<Location> locations) {
901 assertLocations(locations, [locationA, locationB, locationC]);
902 }).then((_) {
903 // remove "A" source
904 store.removeSources(contextA, new SingleSourceContainer(sourceA));
905 store.removeSource(contextA, sourceA);
906 return store.getRelationshipsAsync(elementA, relationship).then(
907 (List<Location> locations) {
908 assertLocations(locations, [locationB, locationC]);
909 });
910 });
911 }
912
913 test_universe_aboutToIndex() {
914 when(contextA.getElement(elementLocationA)).thenReturn(elementA);
915 when(contextB.getElement(elementLocationB)).thenReturn(elementB);
916 Location locationA = mockLocation(elementA);
917 Location locationB = mockLocation(elementB);
918 {
919 store.aboutToIndexDart(contextA, unitElementA);
920 store.recordRelationship(UniverseElement.INSTANCE, relationship,
921 locationA);
922 store.doneIndex();
923 }
924 {
925 store.aboutToIndexDart(contextB, unitElementB);
926 store.recordRelationship(UniverseElement.INSTANCE, relationship,
927 locationB);
928 store.doneIndex();
929 }
930 // get relationships
931 return store.getRelationshipsAsync(UniverseElement.INSTANCE,
932 relationship).then((List<Location> locations) {
933 assertLocations(locations, [locationA, locationB]);
934 }).then((_) {
935 // re-index "unitElementA"
936 store.aboutToIndexDart(contextA, unitElementA);
937 store.doneIndex();
938 return store.getRelationshipsAsync(UniverseElement.INSTANCE,
939 relationship).then((List<Location> locations) {
940 assertLocations(locations, [locationB]);
941 });
942 });
943 }
944
945 test_universe_clear() {
946 when(contextA.getElement(elementLocationA)).thenReturn(elementA);
947 when(contextB.getElement(elementLocationB)).thenReturn(elementB);
948 Location locationA = mockLocation(elementA);
949 Location locationB = mockLocation(elementB);
950 {
951 store.aboutToIndexDart(contextA, unitElementA);
952 store.recordRelationship(UniverseElement.INSTANCE, relationship,
953 locationA);
954 store.doneIndex();
955 }
956 {
957 store.aboutToIndexDart(contextA, unitElementB);
958 store.recordRelationship(UniverseElement.INSTANCE, relationship,
959 locationB);
960 store.doneIndex();
961 }
962 return store.getRelationshipsAsync(UniverseElement.INSTANCE,
963 relationship).then((List<Location> locations) {
964 assertLocations(locations, [locationA, locationB]);
965 }).then((_) {
966 // clear
967 store.clear();
968 return store.getRelationshipsAsync(UniverseElement.INSTANCE,
969 relationship).then((List<Location> locations) {
970 expect(locations, isEmpty);
971 });
972 });
973 }
974
975 test_universe_removeContext() {
976 when(contextA.getElement(elementLocationA)).thenReturn(elementA);
977 when(contextB.getElement(elementLocationB)).thenReturn(elementB);
978 Location locationA = mockLocation(elementA);
979 Location locationB = mockLocation(elementB);
980 {
981 store.aboutToIndexDart(contextA, unitElementA);
982 store.recordRelationship(UniverseElement.INSTANCE, relationship,
983 locationA);
984 store.doneIndex();
985 }
986 {
987 store.aboutToIndexDart(contextB, unitElementB);
988 store.recordRelationship(UniverseElement.INSTANCE, relationship,
989 locationB);
990 store.doneIndex();
991 }
992 return store.getRelationshipsAsync(UniverseElement.INSTANCE,
993 relationship).then((List<Location> locations) {
994 assertLocations(locations, [locationA, locationB]);
995 }).then((_) {
996 // remove "contextA"
997 store.removeContext(contextA);
998 return store.getRelationshipsAsync(UniverseElement.INSTANCE,
999 relationship).then((List<Location> locations) {
1000 assertLocations(locations, [locationB]);
1001 });
1002 });
1003 }
1004
1005 test_universe_removeSource() {
1006 when(contextA.getElement(elementLocationA)).thenReturn(elementA);
1007 when(contextB.getElement(elementLocationB)).thenReturn(elementB);
1008 Location locationA = mockLocation(elementA);
1009 Location locationB = mockLocation(elementB);
1010 {
1011 store.aboutToIndexDart(contextA, unitElementA);
1012 store.recordRelationship(UniverseElement.INSTANCE, relationship,
1013 locationA);
1014 store.doneIndex();
1015 }
1016 {
1017 store.aboutToIndexDart(contextA, unitElementB);
1018 store.recordRelationship(UniverseElement.INSTANCE, relationship,
1019 locationB);
1020 store.doneIndex();
1021 }
1022 return store.getRelationshipsAsync(UniverseElement.INSTANCE,
1023 relationship).then((List<Location> locations) {
1024 assertLocations(locations, [locationA, locationB]);
1025 }).then((_) {
1026 // remove "sourceA"
1027 store.removeSource(contextA, sourceA);
1028 return store.getRelationshipsAsync(UniverseElement.INSTANCE,
1029 relationship).then((List<Location> locations) {
1030 assertLocations(locations, [locationB]);
1031 });
1032 });
1033 }
1034
1035 /**
1036 * Asserts that the [actual] locations have all the [expected] locations and
1037 * only them.
1038 */
1039 static void assertLocations(List<Location> actual, List<Location> expected) {
1040 List<_LocationEqualsWrapper> actualWrappers = wrapLocations(actual);
1041 List<_LocationEqualsWrapper> expectedWrappers = wrapLocations(expected);
1042 expect(actualWrappers, unorderedEquals(expectedWrappers));
1043 }
1044
1045 /**
1046 * @return the new [Location] mock.
1047 */
1048 static Location mockLocation(Element element) {
1049 Location location = new MockLocation();
1050 when(location.element).thenReturn(element);
1051 when(location.offset).thenReturn(0);
1052 when(location.length).thenReturn(0);
1053 return location;
1054 }
1055
1056 /**
1057 * Wraps the given locations into [LocationEqualsWrapper].
1058 */
1059 static List<_LocationEqualsWrapper> wrapLocations(List<Location> locations) {
1060 List<_LocationEqualsWrapper> wrappers = <_LocationEqualsWrapper>[];
1061 for (Location location in locations) {
1062 wrappers.add(new _LocationEqualsWrapper(location));
1063 }
1064 return wrappers;
1065 }
1066 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698