| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 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 | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library test.index.split_store; | 5 library test.index.split_store; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:collection'; | |
| 9 | 8 |
| 10 import 'package:analysis_server/src/index/store/codec.dart'; | 9 import 'package:analysis_server/src/index/store/codec.dart'; |
| 11 import 'package:analysis_server/src/index/store/split_store.dart'; | 10 import 'package:analysis_server/src/index/store/split_store.dart'; |
| 12 import 'package:analyzer/src/generated/element.dart'; | 11 import 'package:analyzer/src/generated/element.dart'; |
| 13 import 'package:analyzer/src/generated/engine.dart'; | 12 import 'package:analyzer/src/generated/engine.dart'; |
| 14 import 'package:analyzer/src/generated/index.dart'; | 13 import 'package:analyzer/src/generated/index.dart'; |
| 15 import 'package:analyzer/src/generated/source.dart'; | 14 import 'package:analyzer/src/generated/source.dart'; |
| 16 import 'package:typed_mock/typed_mock.dart'; | 15 import 'package:typed_mock/typed_mock.dart'; |
| 17 import 'package:unittest/unittest.dart'; | 16 import 'package:unittest/unittest.dart'; |
| 18 | 17 |
| 19 import '../../reflective_tests.dart'; | 18 import '../../reflective_tests.dart'; |
| 19 import 'memory_node_manager.dart'; |
| 20 import 'single_source_container.dart'; | 20 import 'single_source_container.dart'; |
| 21 import 'typed_mocks.dart'; | 21 import 'typed_mocks.dart'; |
| 22 | 22 |
| 23 | 23 |
| 24 main() { | 24 main() { |
| 25 groupSep = ' | '; | 25 groupSep = ' | '; |
| 26 group('FileNodeManager', () { | 26 group('FileNodeManager', () { |
| 27 runReflectiveTests(_FileNodeManagerTest); | 27 runReflectiveTests(_FileNodeManagerTest); |
| 28 }); | 28 }); |
| 29 group('IndexNode', () { | 29 group('IndexNode', () { |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 395 bool operator ==(Object other) { | 395 bool operator ==(Object other) { |
| 396 if (other is _LocationEqualsWrapper) { | 396 if (other is _LocationEqualsWrapper) { |
| 397 return other.location.offset == location.offset && other.location.length | 397 return other.location.offset == location.offset && other.location.length |
| 398 == location.length && other.location.element == location.element; | 398 == location.length && other.location.element == location.element; |
| 399 } | 399 } |
| 400 return false; | 400 return false; |
| 401 } | 401 } |
| 402 } | 402 } |
| 403 | 403 |
| 404 | 404 |
| 405 class _MemoryNodeManager implements NodeManager { | |
| 406 ContextCodec _contextCodec = new ContextCodec(); | |
| 407 ElementCodec _elementCodec; | |
| 408 int _locationCount = 0; | |
| 409 final Map<String, int> _nodeLocationCounts = new HashMap<String, int>(); | |
| 410 final Map<String, IndexNode> _nodes = new HashMap<String, IndexNode>(); | |
| 411 RelationshipCodec _relationshipCodec; | |
| 412 StringCodec _stringCodec = new StringCodec(); | |
| 413 | |
| 414 _MemoryNodeManager() { | |
| 415 _elementCodec = new ElementCodec(_stringCodec); | |
| 416 _relationshipCodec = new RelationshipCodec(_stringCodec); | |
| 417 } | |
| 418 | |
| 419 @override | |
| 420 ContextCodec get contextCodec { | |
| 421 return _contextCodec; | |
| 422 } | |
| 423 | |
| 424 @override | |
| 425 ElementCodec get elementCodec { | |
| 426 return _elementCodec; | |
| 427 } | |
| 428 | |
| 429 @override | |
| 430 int get locationCount { | |
| 431 return _locationCount; | |
| 432 } | |
| 433 | |
| 434 @override | |
| 435 StringCodec get stringCodec { | |
| 436 return _stringCodec; | |
| 437 } | |
| 438 | |
| 439 @override | |
| 440 void clear() { | |
| 441 _nodes.clear(); | |
| 442 } | |
| 443 | |
| 444 int getLocationCount(String name) { | |
| 445 int locationCount = _nodeLocationCounts[name]; | |
| 446 return locationCount != null ? locationCount : 0; | |
| 447 } | |
| 448 | |
| 449 @override | |
| 450 Future<IndexNode> getNode(String name) { | |
| 451 return new Future.value(_nodes[name]); | |
| 452 } | |
| 453 | |
| 454 bool isEmpty() { | |
| 455 for (IndexNode node in _nodes.values) { | |
| 456 Map<RelationKeyData, List<LocationData>> relations = node.relations; | |
| 457 if (!relations.isEmpty) { | |
| 458 return false; | |
| 459 } | |
| 460 } | |
| 461 return true; | |
| 462 } | |
| 463 | |
| 464 @override | |
| 465 IndexNode newNode(AnalysisContext context) { | |
| 466 return new IndexNode(context, elementCodec, _relationshipCodec); | |
| 467 } | |
| 468 | |
| 469 @override | |
| 470 void putNode(String name, IndexNode node) { | |
| 471 // update location count | |
| 472 { | |
| 473 _locationCount -= getLocationCount(name); | |
| 474 int nodeLocationCount = node.locationCount; | |
| 475 _nodeLocationCounts[name] = nodeLocationCount; | |
| 476 _locationCount += nodeLocationCount; | |
| 477 } | |
| 478 // remember the node | |
| 479 _nodes[name] = node; | |
| 480 } | |
| 481 | |
| 482 @override | |
| 483 void removeNode(String name) { | |
| 484 _nodes.remove(name); | |
| 485 } | |
| 486 } | |
| 487 | |
| 488 | |
| 489 class _MockFileManager extends TypedMock implements FileManager { | 405 class _MockFileManager extends TypedMock implements FileManager { |
| 490 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); | 406 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); |
| 491 } | 407 } |
| 492 | 408 |
| 493 | 409 |
| 494 class _MockIndexNode extends TypedMock implements IndexNode { | 410 class _MockIndexNode extends TypedMock implements IndexNode { |
| 495 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); | 411 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); |
| 496 } | 412 } |
| 497 | 413 |
| 498 | 414 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 ['/home/user/sourceB.dart', 'ClassB']); | 479 ['/home/user/sourceB.dart', 'ClassB']); |
| 564 ElementLocation elementLocationC = new ElementLocationImpl.con3( | 480 ElementLocation elementLocationC = new ElementLocationImpl.con3( |
| 565 ['/home/user/sourceC.dart', 'ClassC']); | 481 ['/home/user/sourceC.dart', 'ClassC']); |
| 566 ElementLocation elementLocationD = new ElementLocationImpl.con3( | 482 ElementLocation elementLocationD = new ElementLocationImpl.con3( |
| 567 ['/home/user/sourceD.dart', 'ClassD']); | 483 ['/home/user/sourceD.dart', 'ClassD']); |
| 568 HtmlElement htmlElementA = new MockHtmlElement(); | 484 HtmlElement htmlElementA = new MockHtmlElement(); |
| 569 HtmlElement htmlElementB = new MockHtmlElement(); | 485 HtmlElement htmlElementB = new MockHtmlElement(); |
| 570 LibraryElement libraryElement = new MockLibraryElement(); | 486 LibraryElement libraryElement = new MockLibraryElement(); |
| 571 Source librarySource = new MockSource('librarySource'); | 487 Source librarySource = new MockSource('librarySource'); |
| 572 CompilationUnitElement libraryUnitElement = new MockCompilationUnitElement(); | 488 CompilationUnitElement libraryUnitElement = new MockCompilationUnitElement(); |
| 573 _MemoryNodeManager nodeManager = new _MemoryNodeManager(); | 489 MemoryNodeManager nodeManager = new MemoryNodeManager(); |
| 574 Relationship relationship = Relationship.getRelationship('test-relationship'); | 490 Relationship relationship = Relationship.getRelationship('test-relationship'); |
| 575 Source sourceA = new MockSource('sourceA'); | 491 Source sourceA = new MockSource('sourceA'); |
| 576 Source sourceB = new MockSource('sourceB'); | 492 Source sourceB = new MockSource('sourceB'); |
| 577 Source sourceC = new MockSource('sourceC'); | 493 Source sourceC = new MockSource('sourceC'); |
| 578 Source sourceD = new MockSource('sourceD'); | 494 Source sourceD = new MockSource('sourceD'); |
| 579 SplitIndexStore store; | 495 SplitIndexStore store; |
| 580 CompilationUnitElement unitElementA = new MockCompilationUnitElement(); | 496 CompilationUnitElement unitElementA = new MockCompilationUnitElement(); |
| 581 CompilationUnitElement unitElementB = new MockCompilationUnitElement(); | 497 CompilationUnitElement unitElementB = new MockCompilationUnitElement(); |
| 582 CompilationUnitElement unitElementC = new MockCompilationUnitElement(); | 498 CompilationUnitElement unitElementC = new MockCompilationUnitElement(); |
| 583 CompilationUnitElement unitElementD = new MockCompilationUnitElement(); | 499 CompilationUnitElement unitElementD = new MockCompilationUnitElement(); |
| (...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1019 // re-index "unitElementA" | 935 // re-index "unitElementA" |
| 1020 store.aboutToIndexDart(contextA, unitElementA); | 936 store.aboutToIndexDart(contextA, unitElementA); |
| 1021 store.doneIndex(); | 937 store.doneIndex(); |
| 1022 return store.getRelationshipsAsync(UniverseElement.INSTANCE, | 938 return store.getRelationshipsAsync(UniverseElement.INSTANCE, |
| 1023 relationship).then((List<Location> locations) { | 939 relationship).then((List<Location> locations) { |
| 1024 assertLocations(locations, [locationB]); | 940 assertLocations(locations, [locationB]); |
| 1025 }); | 941 }); |
| 1026 }); | 942 }); |
| 1027 } | 943 } |
| 1028 | 944 |
| 1029 test_universe_removeContext() { | 945 test_universe_clear() { |
| 1030 when(contextA.getElement(elementLocationA)).thenReturn(elementA); | 946 when(contextA.getElement(elementLocationA)).thenReturn(elementA); |
| 1031 when(contextB.getElement(elementLocationB)).thenReturn(elementB); | 947 when(contextB.getElement(elementLocationB)).thenReturn(elementB); |
| 1032 Location locationA = mockLocation(elementA); | 948 Location locationA = mockLocation(elementA); |
| 1033 Location locationB = mockLocation(elementB); | 949 Location locationB = mockLocation(elementB); |
| 1034 { | 950 { |
| 1035 store.aboutToIndexDart(contextA, unitElementA); | 951 store.aboutToIndexDart(contextA, unitElementA); |
| 1036 store.recordRelationship(UniverseElement.INSTANCE, relationship, | 952 store.recordRelationship(UniverseElement.INSTANCE, relationship, |
| 1037 locationA); | 953 locationA); |
| 1038 store.doneIndex(); | 954 store.doneIndex(); |
| 1039 } | 955 } |
| 1040 { | 956 { |
| 1041 store.aboutToIndexDart(contextB, unitElementB); | 957 store.aboutToIndexDart(contextA, unitElementB); |
| 1042 store.recordRelationship(UniverseElement.INSTANCE, relationship, | 958 store.recordRelationship(UniverseElement.INSTANCE, relationship, |
| 1043 locationB); | 959 locationB); |
| 1044 store.doneIndex(); | 960 store.doneIndex(); |
| 1045 } | 961 } |
| 1046 return store.getRelationshipsAsync(UniverseElement.INSTANCE, | 962 return store.getRelationshipsAsync(UniverseElement.INSTANCE, |
| 1047 relationship).then((List<Location> locations) { | 963 relationship).then((List<Location> locations) { |
| 1048 assertLocations(locations, [locationA, locationB]); | 964 assertLocations(locations, [locationA, locationB]); |
| 1049 }).then((_) { | 965 }).then((_) { |
| 1050 // remove "contextA" | 966 // clear |
| 1051 store.removeContext(contextA); | 967 store.clear(); |
| 1052 return store.getRelationshipsAsync(UniverseElement.INSTANCE, | 968 return store.getRelationshipsAsync(UniverseElement.INSTANCE, |
| 1053 relationship).then((List<Location> locations) { | 969 relationship).then((List<Location> locations) { |
| 1054 assertLocations(locations, [locationB]); | 970 expect(locations, isEmpty); |
| 1055 }); | 971 }); |
| 1056 }); | 972 }); |
| 1057 } | 973 } |
| 1058 | 974 |
| 1059 test_universe_removeSource() { | 975 test_universe_removeContext() { |
| 1060 when(contextA.getElement(elementLocationA)).thenReturn(elementA); | 976 when(contextA.getElement(elementLocationA)).thenReturn(elementA); |
| 1061 when(contextB.getElement(elementLocationB)).thenReturn(elementB); | 977 when(contextB.getElement(elementLocationB)).thenReturn(elementB); |
| 1062 Location locationA = mockLocation(elementA); | 978 Location locationA = mockLocation(elementA); |
| 1063 Location locationB = mockLocation(elementB); | 979 Location locationB = mockLocation(elementB); |
| 1064 { | 980 { |
| 1065 store.aboutToIndexDart(contextA, unitElementA); | 981 store.aboutToIndexDart(contextA, unitElementA); |
| 1066 store.recordRelationship(UniverseElement.INSTANCE, relationship, | 982 store.recordRelationship(UniverseElement.INSTANCE, relationship, |
| 1067 locationA); | 983 locationA); |
| 1068 store.doneIndex(); | 984 store.doneIndex(); |
| 1069 } | 985 } |
| 1070 { | 986 { |
| 1071 store.aboutToIndexDart(contextA, unitElementB); | 987 store.aboutToIndexDart(contextB, unitElementB); |
| 1072 store.recordRelationship(UniverseElement.INSTANCE, relationship, | 988 store.recordRelationship(UniverseElement.INSTANCE, relationship, |
| 1073 locationB); | 989 locationB); |
| 1074 store.doneIndex(); | 990 store.doneIndex(); |
| 1075 } | 991 } |
| 1076 return store.getRelationshipsAsync(UniverseElement.INSTANCE, | 992 return store.getRelationshipsAsync(UniverseElement.INSTANCE, |
| 1077 relationship).then((List<Location> locations) { | 993 relationship).then((List<Location> locations) { |
| 1078 assertLocations(locations, [locationA, locationB]); | 994 assertLocations(locations, [locationA, locationB]); |
| 1079 }).then((_) { | 995 }).then((_) { |
| 1080 // remove "sourceA" | 996 // remove "contextA" |
| 1081 store.removeSource(contextA, sourceA); | 997 store.removeContext(contextA); |
| 1082 return store.getRelationshipsAsync(UniverseElement.INSTANCE, | 998 return store.getRelationshipsAsync(UniverseElement.INSTANCE, |
| 1083 relationship).then((List<Location> locations) { | 999 relationship).then((List<Location> locations) { |
| 1084 assertLocations(locations, [locationB]); | 1000 assertLocations(locations, [locationB]); |
| 1085 }); | 1001 }); |
| 1086 }); | 1002 }); |
| 1087 } | 1003 } |
| 1088 | 1004 |
| 1089 test_universe_clear() { | 1005 test_universe_removeSource() { |
| 1090 when(contextA.getElement(elementLocationA)).thenReturn(elementA); | 1006 when(contextA.getElement(elementLocationA)).thenReturn(elementA); |
| 1091 when(contextB.getElement(elementLocationB)).thenReturn(elementB); | 1007 when(contextB.getElement(elementLocationB)).thenReturn(elementB); |
| 1092 Location locationA = mockLocation(elementA); | 1008 Location locationA = mockLocation(elementA); |
| 1093 Location locationB = mockLocation(elementB); | 1009 Location locationB = mockLocation(elementB); |
| 1094 { | 1010 { |
| 1095 store.aboutToIndexDart(contextA, unitElementA); | 1011 store.aboutToIndexDart(contextA, unitElementA); |
| 1096 store.recordRelationship(UniverseElement.INSTANCE, relationship, | 1012 store.recordRelationship(UniverseElement.INSTANCE, relationship, |
| 1097 locationA); | 1013 locationA); |
| 1098 store.doneIndex(); | 1014 store.doneIndex(); |
| 1099 } | 1015 } |
| 1100 { | 1016 { |
| 1101 store.aboutToIndexDart(contextA, unitElementB); | 1017 store.aboutToIndexDart(contextA, unitElementB); |
| 1102 store.recordRelationship(UniverseElement.INSTANCE, relationship, | 1018 store.recordRelationship(UniverseElement.INSTANCE, relationship, |
| 1103 locationB); | 1019 locationB); |
| 1104 store.doneIndex(); | 1020 store.doneIndex(); |
| 1105 } | 1021 } |
| 1106 return store.getRelationshipsAsync(UniverseElement.INSTANCE, | 1022 return store.getRelationshipsAsync(UniverseElement.INSTANCE, |
| 1107 relationship).then((List<Location> locations) { | 1023 relationship).then((List<Location> locations) { |
| 1108 assertLocations(locations, [locationA, locationB]); | 1024 assertLocations(locations, [locationA, locationB]); |
| 1109 }).then((_) { | 1025 }).then((_) { |
| 1110 // clear | 1026 // remove "sourceA" |
| 1111 store.clear(); | 1027 store.removeSource(contextA, sourceA); |
| 1112 return store.getRelationshipsAsync(UniverseElement.INSTANCE, | 1028 return store.getRelationshipsAsync(UniverseElement.INSTANCE, |
| 1113 relationship).then((List<Location> locations) { | 1029 relationship).then((List<Location> locations) { |
| 1114 expect(locations, isEmpty); | 1030 assertLocations(locations, [locationB]); |
| 1115 }); | 1031 }); |
| 1116 }); | 1032 }); |
| 1117 } | 1033 } |
| 1118 | 1034 |
| 1119 /** | 1035 /** |
| 1120 * Asserts that the [actual] locations have all the [expected] locations and | 1036 * Asserts that the [actual] locations have all the [expected] locations and |
| 1121 * only them. | 1037 * only them. |
| 1122 */ | 1038 */ |
| 1123 static void assertLocations(List<Location> actual, List<Location> expected) { | 1039 static void assertLocations(List<Location> actual, List<Location> expected) { |
| 1124 List<_LocationEqualsWrapper> actualWrappers = wrapLocations(actual); | 1040 List<_LocationEqualsWrapper> actualWrappers = wrapLocations(actual); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1141 * Wraps the given locations into [LocationEqualsWrapper]. | 1057 * Wraps the given locations into [LocationEqualsWrapper]. |
| 1142 */ | 1058 */ |
| 1143 static List<_LocationEqualsWrapper> wrapLocations(List<Location> locations) { | 1059 static List<_LocationEqualsWrapper> wrapLocations(List<Location> locations) { |
| 1144 List<_LocationEqualsWrapper> wrappers = <_LocationEqualsWrapper>[]; | 1060 List<_LocationEqualsWrapper> wrappers = <_LocationEqualsWrapper>[]; |
| 1145 for (Location location in locations) { | 1061 for (Location location in locations) { |
| 1146 wrappers.add(new _LocationEqualsWrapper(location)); | 1062 wrappers.add(new _LocationEqualsWrapper(location)); |
| 1147 } | 1063 } |
| 1148 return wrappers; | 1064 return wrappers; |
| 1149 } | 1065 } |
| 1150 } | 1066 } |
| OLD | NEW |