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

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

Issue 348773003: Port SplitIndexStore to Dart. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fixes for review comments Created 6 years, 6 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
« no previous file with comments | « pkg/analysis_server/pubspec.yaml ('k') | pkg/analysis_server/test/index/test_all.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 import 'dart:collection';
9
10 import 'package:analysis_server/src/index/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
20
21 main() {
22 groupSep = ' | ';
23 group('ContextCodec', () {
24 runReflectiveTests(_ContextCodecTest);
25 });
26 group('ElementCodec', () {
27 runReflectiveTests(_ElementCodecTest);
28 });
29 group('FileNodeManager', () {
30 runReflectiveTests(_FileNodeManagerTest);
31 });
32 group('IndexNode', () {
33 runReflectiveTests(_IndexNodeTest);
34 });
35 group('IntToIntSetMap', () {
36 runReflectiveTests(_IntToIntSetMapTest);
37 });
38 group('LocationData', () {
39 runReflectiveTests(_LocationDataTest);
40 });
41 group('RelationKeyData', () {
42 runReflectiveTests(_RelationKeyDataTest);
43 });
44 group('RelationshipCodec', () {
45 runReflectiveTests(_RelationshipCodecTest);
46 });
47 group('SplitIndexStore', () {
48 runReflectiveTests(_SplitIndexStoreTest);
49 });
50 group('StringCodec', () {
51 runReflectiveTests(_StringCodecTest);
52 });
53 }
54
55
56 void _assertHasLocation(List<Location> locations, Element element, int offset,
57 int length) {
58 for (Location location in locations) {
59 if ((element == null || location.element == element) && location.offset ==
60 offset && location.length == length) {
61 return;
62 }
63 }
64 fail('Expected to find Location'
65 '(element=$element, offset=$offset, length=$length)');
66 }
67
68
69 @ReflectiveTestCase()
70 class _ContextCodecTest {
71 ContextCodec codec = new ContextCodec();
72
73 void test_all() {
74 AnalysisContext contextA = new _MockAnalysisContext('contextA');
75 AnalysisContext contextB = new _MockAnalysisContext('contextB');
76 int idA = codec.encode(contextA);
77 int idB = codec.encode(contextB);
78 expect(codec.decode(idA), contextA);
79 expect(codec.decode(idB), contextB);
80 }
81 }
82
83
84 @ReflectiveTestCase()
85 class _ElementCodecTest {
86 ElementCodec codec;
87 AnalysisContext context = new _MockAnalysisContext('context');
88 StringCodec stringCodec = new StringCodec();
89
90 void setUp() {
91 codec = new ElementCodec(stringCodec);
92 }
93
94 void test_localLocalVariable() {
95 {
96 Element element = new _MockElement();
97 ElementLocation location = new ElementLocationImpl.con3(["main", "foo@1",
98 "bar@2"]);
99 when(context.getElement(location)).thenReturn(element);
100 when(element.location).thenReturn(location);
101 int id = codec.encode(element);
102 expect(codec.decode(context, id), element);
103 }
104 {
105 Element element = new _MockElement();
106 ElementLocation location = new ElementLocationImpl.con3(["main", "foo@10",
107 "bar@20"]);
108 when(context.getElement(location)).thenReturn(element);
109 when(element.location).thenReturn(location);
110 int id = codec.encode(element);
111 expect(codec.decode(context, id), element);
112 }
113 // check strings, "foo" as a single string, no "foo@1" or "foo@10"
114 expect(stringCodec.nameToIndex, hasLength(3));
115 expect(stringCodec.nameToIndex, containsPair('main', 0));
116 expect(stringCodec.nameToIndex, containsPair('foo', 1));
117 expect(stringCodec.nameToIndex, containsPair('bar', 2));
118 }
119
120 void test_localVariable() {
121 {
122 Element element = new _MockElement();
123 ElementLocation location = new ElementLocationImpl.con3(["main",
124 "foo@42"]);
125 when(context.getElement(location)).thenReturn(element);
126 when(element.location).thenReturn(location);
127 int id = codec.encode(element);
128 expect(codec.decode(context, id), element);
129 }
130 {
131 Element element = new _MockElement();
132 ElementLocation location = new ElementLocationImpl.con3(["main",
133 "foo@4200"]);
134 when(context.getElement(location)).thenReturn(element);
135 when(element.location).thenReturn(location);
136 int id = codec.encode(element);
137 expect(codec.decode(context, id), element);
138 }
139 // check strings, "foo" as a single string, no "foo@42" or "foo@4200"
140 expect(stringCodec.nameToIndex, hasLength(2));
141 expect(stringCodec.nameToIndex, containsPair('main', 0));
142 expect(stringCodec.nameToIndex, containsPair('foo', 1));
143 }
144
145 void test_notLocal() {
146 Element element = new _MockElement();
147 ElementLocation location = new ElementLocationImpl.con3(["foo", "bar"]);
148 when(element.location).thenReturn(location);
149 when(context.getElement(location)).thenReturn(element);
150 int id = codec.encode(element);
151 expect(codec.encode(element), id);
152 expect(codec.decode(context, id), element);
153 // check strings
154 expect(stringCodec.nameToIndex, hasLength(2));
155 expect(stringCodec.nameToIndex, containsPair('foo', 0));
156 expect(stringCodec.nameToIndex, containsPair('bar', 1));
157 }
158 }
159
160
161 @ReflectiveTestCase()
162 class _FileNodeManagerTest {
163 AnalysisContext context = new _MockAnalysisContext('context');
164 ContextCodec contextCodec = new _MockContextCodec();
165 int contextId = 13;
166 ElementCodec elementCodec = new _MockElementCodec();
167 FileManager fileManager = new _MockFileManager();
168 _MockLogger logger = new _MockLogger();
169 int nextElementId = 0;
170 FileNodeManager nodeManager;
171 RelationshipCodec relationshipCodec;
172 StringCodec stringCodec = new StringCodec();
173
174 void setUp() {
175 relationshipCodec = new RelationshipCodec(stringCodec);
176 nodeManager = new FileNodeManager(fileManager, logger, stringCodec,
177 contextCodec, elementCodec, relationshipCodec);
178 when(contextCodec.encode(context)).thenReturn(contextId);
179 when(contextCodec.decode(contextId)).thenReturn(context);
180 }
181
182 void test_clear() {
183 nodeManager.clear();
184 verify(fileManager.clear()).once();
185 }
186
187 void test_getLocationCount_empty() {
188 expect(nodeManager.locationCount, 0);
189 }
190
191 void test_getNode_contextNull() {
192 String name = "42.index";
193 // record bytes
194 List<int> bytes;
195 when(fileManager.write(name, anyObject)).thenInvoke((name, bs) {
196 bytes = bs;
197 });
198 // put Node
199 Future putFuture;
200 {
201 IndexNode node = new IndexNode(context, elementCodec, relationshipCodec);
202 putFuture = nodeManager.putNode(name, node);
203 }
204 // do in the "put" Future
205 putFuture.then((_) {
206 // force "null" context
207 when(contextCodec.decode(contextId)).thenReturn(null);
208 // prepare input bytes
209 when(fileManager.read(name)).thenReturn(new Future.value(bytes));
210 // get Node
211 return nodeManager.getNode(name).then((IndexNode node) {
212 expect(node, isNull);
213 // no exceptions
214 verifyZeroInteractions(logger);
215 });
216 });
217 }
218
219 test_getNode_invalidVersion() {
220 String name = "42.index";
221 // prepare a stream with an invalid version
222 when(fileManager.read(name)).thenReturn(new Future.value([0x01, 0x02, 0x03,
223 0x04]));
224 // do in the Future
225 return nodeManager.getNode(name).then((IndexNode node) {
226 // no IndexNode
227 expect(node, isNull);
228 // failed
229 verify(logger.logError2(anyObject, anyObject)).once();
230 });
231 }
232
233 test_getNode_streamException() {
234 String name = "42.index";
235 when(fileManager.read(name)).thenReturn(new Future(() {
236 return throw new Exception();
237 }));
238 // do in the Future
239 return nodeManager.getNode(name).then((IndexNode node) {
240 expect(node, isNull);
241 // failed
242 verify(logger.logError2(anyString, anyObject)).once();
243 });
244 }
245
246 test_getNode_streamNull() {
247 String name = "42.index";
248 when(fileManager.read(name)).thenReturn(new Future.value(null));
249 // do in the Future
250 return nodeManager.getNode(name).then((IndexNode node) {
251 expect(node, isNull);
252 // OK
253 verifyZeroInteractions(logger);
254 });
255 }
256
257 void test_newNode() {
258 IndexNode node = nodeManager.newNode(context);
259 expect(node.context, context);
260 expect(node.locationCount, 0);
261 }
262
263 test_putNode_getNode() {
264 String name = "42.index";
265 // record bytes
266 List<int> bytes;
267 when(fileManager.write(name, anyObject)).thenInvoke((name, bs) {
268 bytes = bs;
269 });
270 // prepare elements
271 Element elementA = _mockElement();
272 Element elementB = _mockElement();
273 Element elementC = _mockElement();
274 Relationship relationship = Relationship.getRelationship("my-relationship");
275 // put Node
276 Future putFuture;
277 {
278 // prepare relations
279 int elementIdA = 0;
280 int elementIdB = 1;
281 int elementIdC = 2;
282 int relationshipId = relationshipCodec.encode(relationship);
283 RelationKeyData key = new RelationKeyData.forData(elementIdA,
284 relationshipId);
285 List<LocationData> locations = [new LocationData.forData(elementIdB, 1,
286 10), new LocationData.forData(elementIdC, 2, 20)];
287 Map<RelationKeyData, List<LocationData>> relations = {
288 key: locations
289 };
290 // prepare Node
291 IndexNode node = new _MockIndexNode();
292 when(node.context).thenReturn(context);
293 when(node.relations).thenReturn(relations);
294 when(node.locationCount).thenReturn(2);
295 // put Node
296 putFuture = nodeManager.putNode(name, node);
297 }
298 // do in the Future
299 putFuture.then((_) {
300 // has locations
301 expect(nodeManager.locationCount, 2);
302 // prepare input bytes
303 when(fileManager.read(name)).thenReturn(new Future.value(bytes));
304 // get Node
305 return nodeManager.getNode(name).then((IndexNode node) {
306 expect(2, node.locationCount);
307 {
308 List<Location> locations = node.getRelationships(elementA,
309 relationship);
310 expect(locations, hasLength(2));
311 _assertHasLocation(locations, elementB, 1, 10);
312 _assertHasLocation(locations, elementC, 2, 20);
313 }
314 });
315 });
316 }
317
318 test_putNode_streamException() {
319 String name = "42.index";
320 Exception exception = new Exception();
321 when(fileManager.write(name, anyObject)).thenReturn(new Future(() {
322 return throw exception;
323 }));
324 // prepare IndexNode
325 IndexNode node = new _MockIndexNode();
326 when(node.context).thenReturn(context);
327 when(node.locationCount).thenReturn(0);
328 when(node.relations).thenReturn({});
329 // try to put
330 return nodeManager.putNode(name, node).then((_) {
331 // failed
332 verify(logger.logError2(anyString, anyObject)).once();
333 });
334 }
335
336 void test_removeNode() {
337 String name = "42.index";
338 nodeManager.removeNode(name);
339 verify(fileManager.delete(name)).once();
340 }
341
342 Element _mockElement() {
343 int elementId = nextElementId++;
344 Element element = new _MockElement();
345 when(elementCodec.encode(element)).thenReturn(elementId);
346 when(elementCodec.decode(context, elementId)).thenReturn(element);
347 return element;
348 }
349 }
350
351
352 @ReflectiveTestCase()
353 class _IndexNodeTest {
354 AnalysisContext context = new _MockAnalysisContext('context');
355 ElementCodec elementCodec = new _MockElementCodec();
356 int nextElementId = 0;
357 IndexNode node;
358 RelationshipCodec relationshipCodec;
359 StringCodec stringCodec = new StringCodec();
360
361 void setUp() {
362 relationshipCodec = new RelationshipCodec(stringCodec);
363 node = new IndexNode(context, elementCodec, relationshipCodec);
364 }
365
366 void test_getContext() {
367 expect(node.context, context);
368 }
369
370 void test_recordRelationship() {
371 Element elementA = _mockElement();
372 Element elementB = _mockElement();
373 Element elementC = _mockElement();
374 Relationship relationship = Relationship.getRelationship("my-relationship");
375 Location locationA = new Location(elementB, 1, 2);
376 Location locationB = new Location(elementC, 10, 20);
377 // empty initially
378 expect(node.locationCount, 0);
379 // record
380 node.recordRelationship(elementA, relationship, locationA);
381 expect(node.locationCount, 1);
382 node.recordRelationship(elementA, relationship, locationB);
383 expect(node.locationCount, 2);
384 // get relations
385 expect(node.getRelationships(elementB, relationship), isEmpty);
386 {
387 List<Location> locations = node.getRelationships(elementA, relationship);
388 expect(locations, hasLength(2));
389 _assertHasLocation(locations, null, 1, 2);
390 _assertHasLocation(locations, null, 10, 20);
391 }
392 // verify relations map
393 {
394 Map<RelationKeyData, List<LocationData>> relations = node.relations;
395 expect(relations, hasLength(1));
396 List<LocationData> locations = relations.values.first;
397 expect(locations, hasLength(2));
398 }
399 }
400
401 void test_setRelations() {
402 Element elementA = _mockElement();
403 Element elementB = _mockElement();
404 Element elementC = _mockElement();
405 Relationship relationship = Relationship.getRelationship("my-relationship");
406 // record
407 {
408 int elementIdA = 0;
409 int elementIdB = 1;
410 int elementIdC = 2;
411 int relationshipId = relationshipCodec.encode(relationship);
412 RelationKeyData key = new RelationKeyData.forData(elementIdA,
413 relationshipId);
414 List<LocationData> locations = [new LocationData.forData(elementIdB, 1,
415 10), new LocationData.forData(elementIdC, 2, 20)];
416 node.relations = {
417 key: locations
418 };
419 }
420 // request
421 List<Location> locations = node.getRelationships(elementA, relationship);
422 expect(locations, hasLength(2));
423 _assertHasLocation(locations, elementB, 1, 10);
424 _assertHasLocation(locations, elementC, 2, 20);
425 }
426
427 Element _mockElement() {
428 int elementId = nextElementId++;
429 Element element = new _MockElement();
430 when(elementCodec.encode(element)).thenReturn(elementId);
431 when(elementCodec.decode(context, elementId)).thenReturn(element);
432 return element;
433 }
434 }
435
436
437 @ReflectiveTestCase()
438 class _IntToIntSetMapTest {
439 IntToIntSetMap map = new IntToIntSetMap(32, 0.75);
440
441 void test_clear() {
442 map.add(1, 10);
443 map.add(2, 20);
444 expect(map.length, 2);
445 map.clear();
446 expect(map.length, 0);
447 }
448
449 void test_get() {
450 map.add(1, 10);
451 map.add(1, 11);
452 map.add(1, 12);
453 map.add(2, 20);
454 map.add(2, 21);
455 expect(map.get(1), unorderedEquals([10, 11, 12]));
456 expect(map.get(2), unorderedEquals([20, 21]));
457 }
458
459 void test_get_no() {
460 expect(map.get(3), []);
461 }
462
463 void test_length() {
464 expect(map.length, 0);
465 map.add(1, 10);
466 expect(map.length, 1);
467 map.add(1, 11);
468 expect(map.length, 2);
469 map.add(1, 12);
470 expect(map.length, 3);
471 map.add(2, 20);
472 expect(map.length, 4);
473 map.add(2, 21);
474 expect(map.length, 5);
475 }
476 }
477
478
479 @ReflectiveTestCase()
480 class _LocationDataTest {
481 AnalysisContext context = new _MockAnalysisContext('context');
482 ElementCodec elementCodec = new _MockElementCodec();
483 StringCodec stringCodec = new StringCodec();
484
485 void test_newForData() {
486 Element element = new _MockElement();
487 when(elementCodec.decode(context, 0)).thenReturn(element);
488 LocationData locationData = new LocationData.forData(0, 1, 2);
489 Location location = locationData.getLocation(context, elementCodec);
490 expect(location.element, element);
491 expect(location.offset, 1);
492 expect(location.length, 2);
493 }
494
495 void test_newForObject() {
496 // prepare Element
497 Element element = new _MockElement();
498 when(elementCodec.encode(element)).thenReturn(42);
499 when(elementCodec.decode(context, 42)).thenReturn(element);
500 // create
501 Location location = new Location(element, 1, 2);
502 LocationData locationData = new LocationData.forObject(elementCodec,
503 location);
504 // touch 'hashCode'
505 locationData.hashCode;
506 // ==
507 expect(locationData == new LocationData.forData(42, 1, 2), isTrue);
508 // getLocation()
509 {
510 Location newLocation = locationData.getLocation(context, elementCodec);
511 expect(location.element, element);
512 expect(location.offset, 1);
513 expect(location.length, 2);
514 }
515 // no Element - no Location
516 {
517 when(elementCodec.decode(context, 42)).thenReturn(null);
518 Location newLocation = locationData.getLocation(context, elementCodec);
519 expect(newLocation, isNull);
520 }
521 }
522 }
523
524
525 /**
526 * [Location] has no [==] and [hashCode], so to compare locations by value we
527 * need to wrap them into such object.
528 */
529 class _LocationEqualsWrapper {
530 final Location location;
531
532 _LocationEqualsWrapper(this.location);
533
534 @override
535 int get hashCode {
536 return 31 * (31 * location.element.hashCode + location.offset) +
537 location.length;
538 }
539
540 @override
541 bool operator ==(Object other) {
542 if (other is _LocationEqualsWrapper) {
543 return other.location.offset == location.offset && other.location.length
544 == location.length && other.location.element == location.element;
545 }
546 return false;
547 }
548 }
549
550
551 class _MemoryNodeManager implements NodeManager {
552 ContextCodec _contextCodec = new ContextCodec();
553 ElementCodec _elementCodec;
554 int _locationCount = 0;
555 final Map<String, int> _nodeLocationCounts = new HashMap<String, int>();
556
557 final Map<String, IndexNode> _nodes = new HashMap<String, IndexNode>();
558 RelationshipCodec _relationshipCodec;
559 StringCodec _stringCodec = new StringCodec();
560
561 _MemoryNodeManager() {
562 _elementCodec = new ElementCodec(_stringCodec);
563 _relationshipCodec = new RelationshipCodec(_stringCodec);
564 }
565
566 @override
567 ContextCodec get contextCodec {
568 return _contextCodec;
569 }
570
571 @override
572 ElementCodec get elementCodec {
573 return _elementCodec;
574 }
575
576 @override
577 int get locationCount {
578 return _locationCount;
579 }
580
581 @override
582 StringCodec get stringCodec {
583 return _stringCodec;
584 }
585
586 @override
587 void clear() {
588 _nodes.clear();
589 }
590
591 int getLocationCount(String name) {
592 int locationCount = _nodeLocationCounts[name];
593 return locationCount != null ? locationCount : 0;
594 }
595
596 @override
597 Future<IndexNode> getNode(String name) {
598 return new Future.value(_nodes[name]);
599 }
600
601 bool isEmpty() {
602 for (IndexNode node in _nodes.values) {
603 Map<RelationKeyData, List<LocationData>> relations = node.relations;
604 if (!relations.isEmpty) {
605 return false;
606 }
607 }
608 return true;
609 }
610
611 @override
612 IndexNode newNode(AnalysisContext context) {
613 return new IndexNode(context, elementCodec, _relationshipCodec);
614 }
615
616 @override
617 void putNode(String name, IndexNode node) {
618 // update location count
619 {
620 _locationCount -= getLocationCount(name);
621 int nodeLocationCount = node.locationCount;
622 _nodeLocationCounts[name] = nodeLocationCount;
623 _locationCount += nodeLocationCount;
624 }
625 // remember the node
626 _nodes[name] = node;
627 }
628
629 @override
630 void removeNode(String name) {
631 _nodes.remove(name);
632 }
633 }
634
635
636 class _MockAnalysisContext extends TypedMock implements AnalysisContext {
637 String _name;
638 _MockAnalysisContext(this._name);
639 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
640 String toString() => _name;
641 }
642
643
644 class _MockCompilationUnitElement extends TypedMock implements
645 CompilationUnitElement {
646 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
647 }
648
649
650 class _MockContextCodec extends TypedMock implements ContextCodec {
651 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
652 }
653
654
655 class _MockElement extends TypedMock implements Element {
656 String _name;
657 _MockElement([this._name = '<element>']);
658 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
659 String toString() => _name;
660 }
661
662
663 class _MockElementCodec extends TypedMock implements ElementCodec {
664 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
665 }
666
667
668 class _MockFileManager extends TypedMock implements FileManager {
669 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
670 }
671
672
673 class _MockHtmlElement extends TypedMock implements HtmlElement {
674 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
675 }
676
677
678 class _MockIndexNode extends TypedMock implements IndexNode {
679 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
680 }
681
682
683 class _MockInstrumentedAnalysisContextImpl extends TypedMock implements
684 InstrumentedAnalysisContextImpl {
685 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
686 }
687
688
689 class _MockLibraryElement extends TypedMock implements LibraryElement {
690 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
691 }
692
693
694 class _MockLocation extends TypedMock implements Location {
695 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
696 }
697
698
699 class _MockLogger extends TypedMock implements Logger {
700 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
701 }
702
703
704 class _MockRelationshipCodec extends TypedMock implements RelationshipCodec {
705 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
706 }
707
708
709 class _MockSource extends TypedMock implements Source {
710 String _name;
711 _MockSource(this._name);
712 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
713 String toString() => _name;
714 }
715
716
717 @ReflectiveTestCase()
718 class _RelationKeyDataTest {
719 AnalysisContext context = new _MockAnalysisContext('context');
720 ElementCodec elementCodec = new _MockElementCodec();
721 RelationshipCodec relationshipCodec = new _MockRelationshipCodec();
722 StringCodec stringCodec = new StringCodec();
723
724 void test_newFromData() {
725 RelationKeyData keyData = new RelationKeyData.forData(1, 2);
726 // equals
727 expect(keyData == this, isFalse);
728 expect(keyData == new RelationKeyData.forData(10, 20), isFalse);
729 expect(keyData == keyData, isTrue);
730 expect(keyData == new RelationKeyData.forData(1, 2), isTrue);
731 }
732
733 void test_newFromObjects() {
734 // prepare Element
735 Element element;
736 int elementId = 2;
737 {
738 element = new _MockElement();
739 ElementLocation location = new ElementLocationImpl.con3(["foo", "bar"]);
740 when(element.location).thenReturn(location);
741 when(context.getElement(location)).thenReturn(element);
742 when(elementCodec.encode(element)).thenReturn(elementId);
743 }
744 // prepare relationship
745 Relationship relationship = Relationship.getRelationship("my-relationship");
746 int relationshipId = 1;
747 when(relationshipCodec.encode(relationship)).thenReturn(relationshipId);
748 // create RelationKeyData
749 RelationKeyData keyData = new RelationKeyData.forObject(elementCodec,
750 relationshipCodec, element, relationship);
751 // touch
752 keyData.hashCode;
753 // equals
754 expect(keyData == this, isFalse);
755 expect(keyData == new RelationKeyData.forData(10, 20), isFalse);
756 expect(keyData == keyData, isTrue);
757 expect(keyData == new RelationKeyData.forData(elementId, relationshipId),
758 isTrue);
759 }
760 }
761
762
763 @ReflectiveTestCase()
764 class _RelationshipCodecTest {
765 RelationshipCodec codec;
766 StringCodec stringCodec = new StringCodec();
767
768 void setUp() {
769 codec = new RelationshipCodec(stringCodec);
770 }
771
772 void test_all() {
773 Relationship relationship = Relationship.getRelationship("my-relationship");
774 int id = codec.encode(relationship);
775 expect(codec.decode(id), relationship);
776 }
777 }
778
779
780 class _SingleSourceContainer implements SourceContainer {
781 final Source _source;
782 _SingleSourceContainer(this._source);
783 @override
784 bool contains(Source source) => source == _source;
785 }
786
787
788 @ReflectiveTestCase()
789 class _SplitIndexStoreTest {
790 AnalysisContext contextA = new _MockAnalysisContext('contextA');
791
792 AnalysisContext contextB = new _MockAnalysisContext('contextB');
793
794 AnalysisContext contextC = new _MockAnalysisContext('contextC');
795
796 Element elementA = new _MockElement('elementA');
797 Element elementB = new _MockElement('elementB');
798
799 Element elementC = new _MockElement('elementC');
800 Element elementD = new _MockElement('elementD');
801 ElementLocation elementLocationA = new ElementLocationImpl.con3(
802 ["/home/user/sourceA.dart", "ClassA"]);
803 ElementLocation elementLocationB = new ElementLocationImpl.con3(
804 ["/home/user/sourceB.dart", "ClassB"]);
805 ElementLocation elementLocationC = new ElementLocationImpl.con3(
806 ["/home/user/sourceC.dart", "ClassC"]);
807 ElementLocation elementLocationD = new ElementLocationImpl.con3(
808 ["/home/user/sourceD.dart", "ClassD"]);
809 HtmlElement htmlElementA = new _MockHtmlElement();
810 HtmlElement htmlElementB = new _MockHtmlElement();
811 LibraryElement libraryElement = new _MockLibraryElement();
812 Source librarySource = new _MockSource('librarySource');
813 CompilationUnitElement libraryUnitElement = new _MockCompilationUnitElement();
814 _MemoryNodeManager nodeManager = new _MemoryNodeManager();
815 Relationship relationship = Relationship.getRelationship("test-relationship");
816 Source sourceA = new _MockSource('sourceA');
817 Source sourceB = new _MockSource('sourceB');
818 Source sourceC = new _MockSource('sourceC');
819 Source sourceD = new _MockSource('sourceD');
820 SplitIndexStore store;
821 CompilationUnitElement unitElementA = new _MockCompilationUnitElement();
822 CompilationUnitElement unitElementB = new _MockCompilationUnitElement();
823 CompilationUnitElement unitElementC = new _MockCompilationUnitElement();
824 CompilationUnitElement unitElementD = new _MockCompilationUnitElement();
825 void setUp() {
826 store = new SplitIndexStore(nodeManager);
827 when(contextA.isDisposed).thenReturn(false);
828 when(contextB.isDisposed).thenReturn(false);
829 when(contextC.isDisposed).thenReturn(false);
830 when(contextA.getElement(elementLocationA)).thenReturn(elementA);
831 when(contextA.getElement(elementLocationB)).thenReturn(elementB);
832 when(contextA.getElement(elementLocationC)).thenReturn(elementC);
833 when(contextA.getElement(elementLocationD)).thenReturn(elementD);
834 when(sourceA.fullName).thenReturn("/home/user/sourceA.dart");
835 when(sourceB.fullName).thenReturn("/home/user/sourceB.dart");
836 when(sourceC.fullName).thenReturn("/home/user/sourceC.dart");
837 when(sourceD.fullName).thenReturn("/home/user/sourceD.dart");
838 when(elementA.context).thenReturn(contextA);
839 when(elementB.context).thenReturn(contextA);
840 when(elementC.context).thenReturn(contextA);
841 when(elementD.context).thenReturn(contextA);
842 when(elementA.location).thenReturn(elementLocationA);
843 when(elementB.location).thenReturn(elementLocationB);
844 when(elementC.location).thenReturn(elementLocationC);
845 when(elementD.location).thenReturn(elementLocationD);
846 when(elementA.enclosingElement).thenReturn(unitElementA);
847 when(elementB.enclosingElement).thenReturn(unitElementB);
848 when(elementC.enclosingElement).thenReturn(unitElementC);
849 when(elementD.enclosingElement).thenReturn(unitElementD);
850 when(elementA.source).thenReturn(sourceA);
851 when(elementB.source).thenReturn(sourceB);
852 when(elementC.source).thenReturn(sourceC);
853 when(elementD.source).thenReturn(sourceD);
854 when(elementA.library).thenReturn(libraryElement);
855 when(elementB.library).thenReturn(libraryElement);
856 when(elementC.library).thenReturn(libraryElement);
857 when(elementD.library).thenReturn(libraryElement);
858 when(unitElementA.source).thenReturn(sourceA);
859 when(unitElementB.source).thenReturn(sourceB);
860 when(unitElementC.source).thenReturn(sourceC);
861 when(unitElementD.source).thenReturn(sourceD);
862 when(unitElementA.library).thenReturn(libraryElement);
863 when(unitElementB.library).thenReturn(libraryElement);
864 when(unitElementC.library).thenReturn(libraryElement);
865 when(unitElementD.library).thenReturn(libraryElement);
866 when(htmlElementA.source).thenReturn(sourceA);
867 when(htmlElementB.source).thenReturn(sourceB);
868 // library
869 when(libraryUnitElement.library).thenReturn(libraryElement);
870 when(libraryUnitElement.source).thenReturn(librarySource);
871 when(libraryElement.source).thenReturn(librarySource);
872 when(libraryElement.definingCompilationUnit).thenReturn(libraryUnitElement);
873 }
874 void test_aboutToIndexDart_disposedContext() {
875 when(contextA.isDisposed).thenReturn(true);
876 expect(store.aboutToIndexDart(contextA, unitElementA), isFalse);
877 }
878 void test_aboutToIndexDart_disposedContext_wrapped() {
879 when(contextA.isDisposed).thenReturn(true);
880 InstrumentedAnalysisContextImpl instrumentedContext =
881 new _MockInstrumentedAnalysisContextImpl();
882 when(instrumentedContext.basis).thenReturn(contextA);
883 expect(store.aboutToIndexDart(instrumentedContext, unitElementA), isFalse);
884 }
885
886 void test_aboutToIndexDart_library_first() {
887 when(libraryElement.parts).thenReturn(<CompilationUnitElement>[unitElementA,
888 unitElementB]);
889 {
890 store.aboutToIndexDart(contextA, libraryUnitElement);
891 store.doneIndex();
892 }
893 {
894 List<Location> locations = store.getRelationships(elementA, relationship);
895 assertLocations(locations, []);
896 }
897 }
898
899 test_aboutToIndexDart_library_secondWithoutOneUnit() {
900 Location locationA = mockLocation(elementA);
901 Location locationB = mockLocation(elementB);
902 {
903 store.aboutToIndexDart(contextA, unitElementA);
904 store.recordRelationship(elementA, relationship, locationA);
905 store.doneIndex();
906 }
907 {
908 store.aboutToIndexDart(contextA, unitElementB);
909 store.recordRelationship(elementA, relationship, locationB);
910 store.doneIndex();
911 }
912 // "A" and "B" locations
913 return store.getRelationshipsAsync(elementA, relationship).then(
914 (List<Location> locations) {
915 assertLocations(locations, [locationA, locationB]);
916 }).then((_) {
917 // apply "libraryUnitElement", only with "B"
918 when(libraryElement.parts).thenReturn([unitElementB]);
919 {
920 store.aboutToIndexDart(contextA, libraryUnitElement);
921 store.doneIndex();
922 }
923 return store.getRelationshipsAsync(elementA, relationship).then(
924 (List<Location> locations) {
925 assertLocations(locations, [locationB]);
926 });
927 });
928 }
929
930 void test_aboutToIndexDart_nullLibraryElement() {
931 when(unitElementA.library).thenReturn(null);
932 expect(store.aboutToIndexDart(contextA, unitElementA), isFalse);
933 }
934
935 void test_aboutToIndexDart_nullLibraryUnitElement() {
936 when(libraryElement.definingCompilationUnit).thenReturn(null);
937 expect(store.aboutToIndexDart(contextA, unitElementA), isFalse);
938 }
939
940 void test_aboutToIndexDart_nullUnitElement() {
941 expect(store.aboutToIndexDart(contextA, null), isFalse);
942 }
943
944 test_aboutToIndexHtml_() {
945 Location locationA = mockLocation(elementA);
946 Location locationB = mockLocation(elementB);
947 {
948 store.aboutToIndexHtml(contextA, htmlElementA);
949 store.recordRelationship(elementA, relationship, locationA);
950 store.doneIndex();
951 }
952 {
953 store.aboutToIndexHtml(contextA, htmlElementB);
954 store.recordRelationship(elementA, relationship, locationB);
955 store.doneIndex();
956 }
957 // "A" and "B" locations
958 return store.getRelationshipsAsync(elementA, relationship).then(
959 (List<Location> locations) {
960 assertLocations(locations, [locationA, locationB]);
961 });
962 }
963
964 void test_aboutToIndexHtml_disposedContext() {
965 when(contextA.isDisposed).thenReturn(true);
966 expect(store.aboutToIndexHtml(contextA, htmlElementA), isFalse);
967 }
968
969 void test_clear() {
970 Location locationA = mockLocation(elementA);
971 store.aboutToIndexDart(contextA, unitElementA);
972 store.recordRelationship(elementA, relationship, locationA);
973 store.doneIndex();
974 expect(nodeManager.isEmpty(), isFalse);
975 // clear
976 store.clear();
977 expect(nodeManager.isEmpty(), isTrue);
978 }
979
980 test_getRelationships_empty() {
981 return store.getRelationshipsAsync(elementA, relationship).then(
982 (List<Location> locations) {
983 expect(locations, isEmpty);
984 });
985 }
986
987 void test_getStatistics() {
988 // empty initially
989 {
990 String statistics = store.statistics;
991 expect(statistics, contains('0 locations'));
992 expect(statistics, contains('0 sources'));
993 }
994 // add 2 locations
995 Location locationA = mockLocation(elementA);
996 Location locationB = mockLocation(elementB);
997 {
998 store.aboutToIndexDart(contextA, unitElementA);
999 store.recordRelationship(elementA, relationship, locationA);
1000 store.doneIndex();
1001 }
1002 {
1003 store.aboutToIndexDart(contextA, unitElementB);
1004 store.recordRelationship(elementA, relationship, locationB);
1005 store.doneIndex();
1006 }
1007 {
1008 String statistics = store.statistics;
1009 expect(statistics, contains('2 locations'));
1010 expect(statistics, contains('3 sources'));
1011 }
1012 }
1013
1014 void test_recordRelationship_nullElement() {
1015 Location locationA = mockLocation(elementA);
1016 store.recordRelationship(null, relationship, locationA);
1017 store.doneIndex();
1018 expect(nodeManager.isEmpty(), isTrue);
1019 }
1020
1021 void test_recordRelationship_nullLocation() {
1022 store.recordRelationship(elementA, relationship, null);
1023 store.doneIndex();
1024 expect(nodeManager.isEmpty(), isTrue);
1025 }
1026
1027 test_recordRelationship_oneElement_twoNodes() {
1028 Location locationA = mockLocation(elementA);
1029 Location locationB = mockLocation(elementB);
1030 {
1031 store.aboutToIndexDart(contextA, unitElementA);
1032 store.recordRelationship(elementA, relationship, locationA);
1033 store.doneIndex();
1034 }
1035 {
1036 store.aboutToIndexDart(contextA, unitElementB);
1037 store.recordRelationship(elementA, relationship, locationB);
1038 store.doneIndex();
1039 }
1040 return store.getRelationshipsAsync(elementA, relationship).then(
1041 (List<Location> locations) {
1042 assertLocations(locations, [locationA, locationB]);
1043 });
1044 }
1045
1046 test_recordRelationship_oneLocation() {
1047 Location locationA = mockLocation(elementA);
1048 store.aboutToIndexDart(contextA, unitElementA);
1049 store.recordRelationship(elementA, relationship, locationA);
1050 store.doneIndex();
1051 return store.getRelationshipsAsync(elementA, relationship).then(
1052 (List<Location> locations) {
1053 assertLocations(locations, [locationA]);
1054 });
1055 }
1056
1057 test_recordRelationship_twoLocations() {
1058 Location locationA = mockLocation(elementA);
1059 Location locationB = mockLocation(elementA);
1060 store.aboutToIndexDart(contextA, unitElementA);
1061 store.recordRelationship(elementA, relationship, locationA);
1062 store.recordRelationship(elementA, relationship, locationB);
1063 store.doneIndex();
1064 return store.getRelationshipsAsync(elementA, relationship).then(
1065 (List<Location> locations) {
1066 assertLocations(locations, [locationA, locationB]);
1067 });
1068 }
1069
1070 test_removeContext() {
1071 Location locationA = mockLocation(elementA);
1072 Location locationB = mockLocation(elementB);
1073 {
1074 store.aboutToIndexDart(contextA, unitElementA);
1075 store.recordRelationship(elementA, relationship, locationA);
1076 store.doneIndex();
1077 }
1078 {
1079 store.aboutToIndexDart(contextA, unitElementB);
1080 store.recordRelationship(elementA, relationship, locationB);
1081 store.doneIndex();
1082 }
1083 // "A" and "B" locations
1084 return store.getRelationshipsAsync(elementA, relationship).then(
1085 (List<Location> locations) {
1086 assertLocations(locations, [locationA, locationB]);
1087 }).then((_) {
1088 // remove "A" context
1089 store.removeContext(contextA);
1090 return store.getRelationshipsAsync(elementA, relationship).then(
1091 (List<Location> locations) {
1092 assertLocations(locations, []);
1093 });
1094 });
1095 }
1096
1097 void test_removeContext_nullContext() {
1098 store.removeContext(null);
1099 }
1100
1101 test_removeSource_library() {
1102 Location locationA = mockLocation(elementA);
1103 Location locationB = mockLocation(elementB);
1104 Location locationC = mockLocation(elementC);
1105 {
1106 store.aboutToIndexDart(contextA, unitElementA);
1107 store.recordRelationship(elementA, relationship, locationA);
1108 store.doneIndex();
1109 }
1110 {
1111 store.aboutToIndexDart(contextA, unitElementB);
1112 store.recordRelationship(elementA, relationship, locationB);
1113 store.doneIndex();
1114 }
1115 {
1116 store.aboutToIndexDart(contextA, unitElementC);
1117 store.recordRelationship(elementA, relationship, locationC);
1118 store.doneIndex();
1119 }
1120 // "A", "B" and "C" locations
1121 return store.getRelationshipsAsync(elementA, relationship).then(
1122 (List<Location> locations) {
1123 assertLocations(locations, [locationA, locationB, locationC]);
1124 }).then((_) {
1125 // remove "librarySource"
1126 store.removeSource(contextA, librarySource);
1127 return store.getRelationshipsAsync(elementA, relationship).then(
1128 (List<Location> locations) {
1129 assertLocations(locations, []);
1130 });
1131 });
1132 }
1133
1134 void test_removeSource_nullContext() {
1135 store.removeSource(null, sourceA);
1136 }
1137
1138 test_removeSource_unit() {
1139 Location locationA = mockLocation(elementA);
1140 Location locationB = mockLocation(elementB);
1141 Location locationC = mockLocation(elementC);
1142 {
1143 store.aboutToIndexDart(contextA, unitElementA);
1144 store.recordRelationship(elementA, relationship, locationA);
1145 store.doneIndex();
1146 }
1147 {
1148 store.aboutToIndexDart(contextA, unitElementB);
1149 store.recordRelationship(elementA, relationship, locationB);
1150 store.doneIndex();
1151 }
1152 {
1153 store.aboutToIndexDart(contextA, unitElementC);
1154 store.recordRelationship(elementA, relationship, locationC);
1155 store.doneIndex();
1156 }
1157 // "A", "B" and "C" locations
1158 return store.getRelationshipsAsync(elementA, relationship).then(
1159 (List<Location> locations) {
1160 assertLocations(locations, [locationA, locationB, locationC]);
1161 }).then((_) {
1162 // remove "A" source
1163 store.removeSource(contextA, sourceA);
1164 return store.getRelationshipsAsync(elementA, relationship).then(
1165 (List<Location> locations) {
1166 assertLocations(locations, [locationB, locationC]);
1167 });
1168 });
1169 }
1170
1171 test_removeSources_library() {
1172 Location locationA = mockLocation(elementA);
1173 Location locationB = mockLocation(elementB);
1174 {
1175 store.aboutToIndexDart(contextA, unitElementA);
1176 store.recordRelationship(elementA, relationship, locationA);
1177 store.doneIndex();
1178 }
1179 {
1180 store.aboutToIndexDart(contextA, unitElementB);
1181 store.recordRelationship(elementA, relationship, locationB);
1182 store.doneIndex();
1183 }
1184 // "A" and "B" locations
1185 return store.getRelationshipsAsync(elementA, relationship).then(
1186 (List<Location> locations) {
1187 assertLocations(locations, [locationA, locationB]);
1188 }).then((_) {
1189 // remove "librarySource"
1190 store.removeSources(contextA, new _SingleSourceContainer(librarySource));
1191 return store.getRelationshipsAsync(elementA, relationship).then(
1192 (List<Location> locations) {
1193 assertLocations(locations, []);
1194 });
1195 });
1196 }
1197
1198 void test_removeSources_nullContext() {
1199 store.removeSources(null, null);
1200 }
1201
1202 test_removeSources_unit() {
1203 Location locationA = mockLocation(elementA);
1204 Location locationB = mockLocation(elementB);
1205 Location locationC = mockLocation(elementC);
1206 {
1207 store.aboutToIndexDart(contextA, unitElementA);
1208 store.recordRelationship(elementA, relationship, locationA);
1209 store.doneIndex();
1210 }
1211 {
1212 store.aboutToIndexDart(contextA, unitElementB);
1213 store.recordRelationship(elementA, relationship, locationB);
1214 store.doneIndex();
1215 }
1216 {
1217 store.aboutToIndexDart(contextA, unitElementC);
1218 store.recordRelationship(elementA, relationship, locationC);
1219 store.doneIndex();
1220 }
1221 // "A", "B" and "C" locations
1222 return store.getRelationshipsAsync(elementA, relationship).then(
1223 (List<Location> locations) {
1224 assertLocations(locations, [locationA, locationB, locationC]);
1225 }).then((_) {
1226 // remove "A" source
1227 store.removeSources(contextA, new _SingleSourceContainer(sourceA));
1228 store.removeSource(contextA, sourceA);
1229 return store.getRelationshipsAsync(elementA, relationship).then(
1230 (List<Location> locations) {
1231 assertLocations(locations, [locationB, locationC]);
1232 });
1233 });
1234 }
1235
1236 test_universe_aboutToIndex() {
1237 when(contextA.getElement(elementLocationA)).thenReturn(elementA);
1238 when(contextB.getElement(elementLocationB)).thenReturn(elementB);
1239 Location locationA = mockLocation(elementA);
1240 Location locationB = mockLocation(elementB);
1241 {
1242 store.aboutToIndexDart(contextA, unitElementA);
1243 store.recordRelationship(UniverseElement.INSTANCE, relationship,
1244 locationA);
1245 store.doneIndex();
1246 }
1247 {
1248 store.aboutToIndexDart(contextB, unitElementB);
1249 store.recordRelationship(UniverseElement.INSTANCE, relationship,
1250 locationB);
1251 store.doneIndex();
1252 }
1253 // get relationships
1254 return store.getRelationshipsAsync(UniverseElement.INSTANCE,
1255 relationship).then((List<Location> locations) {
1256 assertLocations(locations, [locationA, locationB]);
1257 }).then((_) {
1258 // re-index "unitElementA"
1259 store.aboutToIndexDart(contextA, unitElementA);
1260 store.doneIndex();
1261 return store.getRelationshipsAsync(UniverseElement.INSTANCE,
1262 relationship).then((List<Location> locations) {
1263 assertLocations(locations, [locationB]);
1264 });
1265 });
1266 }
1267
1268 test_universe_removeContext() {
1269 when(contextA.getElement(elementLocationA)).thenReturn(elementA);
1270 when(contextB.getElement(elementLocationB)).thenReturn(elementB);
1271 Location locationA = mockLocation(elementA);
1272 Location locationB = mockLocation(elementB);
1273 {
1274 store.aboutToIndexDart(contextA, unitElementA);
1275 store.recordRelationship(UniverseElement.INSTANCE, relationship,
1276 locationA);
1277 store.doneIndex();
1278 }
1279 {
1280 store.aboutToIndexDart(contextB, unitElementB);
1281 store.recordRelationship(UniverseElement.INSTANCE, relationship,
1282 locationB);
1283 store.doneIndex();
1284 }
1285 return store.getRelationshipsAsync(UniverseElement.INSTANCE,
1286 relationship).then((List<Location> locations) {
1287 assertLocations(locations, [locationA, locationB]);
1288 }).then((_) {
1289 // remove "contextA"
1290 store.removeContext(contextA);
1291 return store.getRelationshipsAsync(UniverseElement.INSTANCE,
1292 relationship).then((List<Location> locations) {
1293 assertLocations(locations, [locationB]);
1294 });
1295 });
1296 }
1297
1298 /**
1299 * Asserts that the "actual" locations have all the "expected" locations and o nly them.
1300 */
1301 static void assertLocations(List<Location> actual, List<Location> expected) {
1302 List<_LocationEqualsWrapper> actualWrappers = wrapLocations(actual);
1303 List<_LocationEqualsWrapper> expectedWrappers = wrapLocations(expected);
1304 expect(actualWrappers, unorderedEquals(expectedWrappers));
1305 }
1306
1307 /**
1308 * @return the new [Location] mock.
1309 */
1310 static Location mockLocation(Element element) {
1311 Location location = new _MockLocation();
1312 when(location.element).thenReturn(element);
1313 when(location.offset).thenReturn(0);
1314 when(location.length).thenReturn(0);
1315 return location;
1316 }
1317
1318 /**
1319 * Wraps the given locations into [LocationEqualsWrapper].
1320 */
1321 static List<_LocationEqualsWrapper> wrapLocations(List<Location> locations) {
1322 List<_LocationEqualsWrapper> wrappers = <_LocationEqualsWrapper>[];
1323 for (Location location in locations) {
1324 wrappers.add(new _LocationEqualsWrapper(location));
1325 }
1326 return wrappers;
1327 }
1328 }
1329
1330
1331 @ReflectiveTestCase()
1332 class _StringCodecTest {
1333 StringCodec codec = new StringCodec();
1334
1335 void test_all() {
1336 int idA = codec.encode('aaa');
1337 int idB = codec.encode('bbb');
1338 expect(codec.decode(idA), 'aaa');
1339 expect(codec.decode(idB), 'bbb');
1340 }
1341 }
OLDNEW
« no previous file with comments | « pkg/analysis_server/pubspec.yaml ('k') | pkg/analysis_server/test/index/test_all.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698