| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 library test.integration.search.domain; | |
| 6 | |
| 7 import 'dart:async'; | |
| 8 | |
| 9 import 'package:analysis_testing/reflective_tests.dart'; | |
| 10 import 'package:unittest/unittest.dart'; | |
| 11 | |
| 12 import 'integration_tests.dart'; | |
| 13 | |
| 14 /** | |
| 15 * Results of a getTypeHierarchy request, processed for easier testing. | |
| 16 */ | |
| 17 class HierarchyResults { | |
| 18 /** | |
| 19 * The list of hierarchy items from the result. | |
| 20 */ | |
| 21 List<Map> items; | |
| 22 | |
| 23 /** | |
| 24 * The first hierarchy item from the result, which represents the pivot | |
| 25 * class. | |
| 26 */ | |
| 27 Map pivot; | |
| 28 | |
| 29 /** | |
| 30 * A map from element name to item index. | |
| 31 */ | |
| 32 Map<String, int> nameToIndex; | |
| 33 | |
| 34 /** | |
| 35 * Create a [HierarchyResults] object based on the result from a | |
| 36 * getTypeHierarchy request. | |
| 37 */ | |
| 38 HierarchyResults(result) { | |
| 39 items = result['hierarchyItems']; | |
| 40 pivot = items[0]; | |
| 41 nameToIndex = <String, int> {}; | |
| 42 for (int i = 0; i < items.length; i++) { | |
| 43 nameToIndex[items[i]['classElement']['name']] = i; | |
| 44 } | |
| 45 } | |
| 46 | |
| 47 /** | |
| 48 * Get an item by class name. | |
| 49 */ | |
| 50 Map getItem(String name) { | |
| 51 if (nameToIndex.containsKey(name)) { | |
| 52 return items[nameToIndex[name]]; | |
| 53 } else { | |
| 54 fail('Class $name not found in hierarchy results'); | |
| 55 return null; | |
| 56 } | |
| 57 } | |
| 58 } | |
| 59 | |
| 60 @ReflectiveTestCase() | |
| 61 class SearchDomainIntegrationTest extends AbstractAnalysisServerIntegrationTest | |
| 62 { | |
| 63 /** | |
| 64 * Pathname of the main file to run tests in. | |
| 65 */ | |
| 66 String pathname; | |
| 67 | |
| 68 test_getTypeHierarchy() { | |
| 69 pathname = sourcePath('test.dart'); | |
| 70 // Write a dummy file which will be overridden by tests using | |
| 71 // [sendAnalysisUpdateContent]. | |
| 72 writeFile(pathname, '// dummy'); | |
| 73 standardAnalysisSetup(); | |
| 74 | |
| 75 // Run all the getTypeHierarchy tests at once so that the server can take | |
| 76 // advantage of incremental analysis and the test doesn't time out. | |
| 77 List tests = [getTypeHierarchy_classElement, getTypeHierarchy_displayName, | |
| 78 getTypeHierarchy_memberElement, getTypeHierarchy_superclass, | |
| 79 getTypeHierarchy_interfaces, getTypeHierarchy_mixins, | |
| 80 getTypeHierarchy_subclasses, getTypeHierarchy_badTarget, | |
| 81 getTypeHierarchy_functionTarget]; | |
| 82 return Future.forEach(tests, (test) => test()); | |
| 83 } | |
| 84 | |
| 85 Future getTypeHierarchy_classElement() { | |
| 86 String text = | |
| 87 r''' | |
| 88 class Base {} | |
| 89 class Pivot /* target */ extends Base {} | |
| 90 class Derived extends Pivot {} | |
| 91 '''; | |
| 92 return typeHierarchyTest(text).then((HierarchyResults results) { | |
| 93 expect(results.items, hasLength(4)); | |
| 94 expect(results.nameToIndex['Pivot'], equals(0)); | |
| 95 void checkElement(String name) { | |
| 96 // We don't check the full element data structure; just enough to make | |
| 97 // sure that we're pointing to the correct element. | |
| 98 Map element = results.items[results.nameToIndex[name]]['classElement']; | |
| 99 expect(element['kind'], equals('CLASS')); | |
| 100 expect(element['name'], equals(name)); | |
| 101 if (name != 'Object') { | |
| 102 expect(element['location']['offset'], equals(text.indexOf( | |
| 103 'class $name') + 'class '.length)); | |
| 104 } | |
| 105 } | |
| 106 checkElement('Object'); | |
| 107 checkElement('Base'); | |
| 108 checkElement('Pivot'); | |
| 109 checkElement('Derived'); | |
| 110 }); | |
| 111 } | |
| 112 | |
| 113 Future getTypeHierarchy_displayName() { | |
| 114 String text = | |
| 115 r''' | |
| 116 class Base<T> {} | |
| 117 class Pivot /* target */ extends Base<int> {} | |
| 118 '''; | |
| 119 return typeHierarchyTest(text).then((HierarchyResults results) { | |
| 120 expect(results.items, hasLength(3)); | |
| 121 expect(results.getItem('Object')['displayName'], isNull); | |
| 122 expect(results.getItem('Base')['displayName'], equals('Base<int>')); | |
| 123 expect(results.getItem('Pivot')['displayName'], isNull); | |
| 124 }); | |
| 125 } | |
| 126 | |
| 127 Future getTypeHierarchy_memberElement() { | |
| 128 String text = | |
| 129 r''' | |
| 130 class Base1 { | |
| 131 void foo /* base1 */ (); | |
| 132 } | |
| 133 class Base2 extends Base1 {} | |
| 134 class Pivot extends Base2 { | |
| 135 void foo /* target */ (); | |
| 136 } | |
| 137 class Derived1 extends Pivot {} | |
| 138 class Derived2 extends Derived1 { | |
| 139 void foo /* derived2 */ (); | |
| 140 }'''; | |
| 141 return typeHierarchyTest(text).then((HierarchyResults results) { | |
| 142 expect(results.items, hasLength(6)); | |
| 143 expect(results.getItem('Object')['memberElement'], isNull); | |
| 144 expect(results.getItem('Base1')['memberElement']['location']['offset'], | |
| 145 equals(text.indexOf('foo /* base1 */'))); | |
| 146 expect(results.getItem('Base2')['memberElement'], isNull); | |
| 147 expect(results.getItem('Pivot')['memberElement']['location']['offset'], | |
| 148 equals(text.indexOf('foo /* target */'))); | |
| 149 expect(results.getItem('Derived1')['memberElement'], isNull); | |
| 150 expect(results.getItem('Derived2')['memberElement']['location']['offset'], | |
| 151 equals(text.indexOf('foo /* derived2 */'))); | |
| 152 }); | |
| 153 } | |
| 154 | |
| 155 Future getTypeHierarchy_superclass() { | |
| 156 String text = | |
| 157 r''' | |
| 158 class Base1 {} | |
| 159 class Base2 extends Base1 {} | |
| 160 class Pivot /* target */ extends Base2 {} | |
| 161 '''; | |
| 162 return typeHierarchyTest(text).then((HierarchyResults results) { | |
| 163 expect(results.items, hasLength(4)); | |
| 164 expect(results.getItem('Object')['superclass'], isNull); | |
| 165 expect(results.getItem('Base1')['superclass'], equals( | |
| 166 results.nameToIndex['Object'])); | |
| 167 expect(results.getItem('Base2')['superclass'], equals( | |
| 168 results.nameToIndex['Base1'])); | |
| 169 expect(results.getItem('Pivot')['superclass'], equals( | |
| 170 results.nameToIndex['Base2'])); | |
| 171 }); | |
| 172 } | |
| 173 | |
| 174 Future getTypeHierarchy_interfaces() { | |
| 175 String text = | |
| 176 r''' | |
| 177 class Interface1 {} | |
| 178 class Interface2 {} | |
| 179 class Pivot /* target */ implements Interface1, Interface2 {} | |
| 180 '''; | |
| 181 return typeHierarchyTest(text).then((HierarchyResults results) { | |
| 182 expect(results.items, hasLength(4)); | |
| 183 expect(results.pivot['interfaces'], hasLength(2)); | |
| 184 expect(results.pivot['interfaces'], contains( | |
| 185 results.nameToIndex['Interface1'])); | |
| 186 expect(results.pivot['interfaces'], contains( | |
| 187 results.nameToIndex['Interface2'])); | |
| 188 expect(results.getItem('Object')['interfaces'], isEmpty); | |
| 189 expect(results.getItem('Interface1')['interfaces'], isEmpty); | |
| 190 expect(results.getItem('Interface2')['interfaces'], isEmpty); | |
| 191 }); | |
| 192 } | |
| 193 | |
| 194 Future getTypeHierarchy_mixins() { | |
| 195 String text = | |
| 196 r''' | |
| 197 class Base {} | |
| 198 class Mixin1 {} | |
| 199 class Mixin2 {} | |
| 200 class Pivot /* target */ extends Base with Mixin1, Mixin2 {} | |
| 201 '''; | |
| 202 return typeHierarchyTest(text).then((HierarchyResults results) { | |
| 203 expect(results.items, hasLength(5)); | |
| 204 expect(results.pivot['mixins'], hasLength(2)); | |
| 205 expect(results.pivot['mixins'], contains(results.nameToIndex['Mixin1'])); | |
| 206 expect(results.pivot['mixins'], contains(results.nameToIndex['Mixin2'])); | |
| 207 expect(results.getItem('Object')['mixins'], isEmpty); | |
| 208 expect(results.getItem('Base')['mixins'], isEmpty); | |
| 209 expect(results.getItem('Mixin1')['mixins'], isEmpty); | |
| 210 expect(results.getItem('Mixin2')['mixins'], isEmpty); | |
| 211 }); | |
| 212 } | |
| 213 | |
| 214 Future getTypeHierarchy_subclasses() { | |
| 215 String text = | |
| 216 r''' | |
| 217 class Base {} | |
| 218 class Pivot /* target */ extends Base {} | |
| 219 class Sub1 extends Pivot {} | |
| 220 class Sub2 extends Pivot {} | |
| 221 class Sub2a extends Sub2 {} | |
| 222 '''; | |
| 223 return typeHierarchyTest(text).then((HierarchyResults results) { | |
| 224 expect(results.items, hasLength(6)); | |
| 225 expect(results.pivot['subclasses'], hasLength(2)); | |
| 226 expect(results.pivot['subclasses'], contains(results.nameToIndex['Sub1']) | |
| 227 ); | |
| 228 expect(results.pivot['subclasses'], contains(results.nameToIndex['Sub2']) | |
| 229 ); | |
| 230 expect(results.getItem('Object')['subclasses'], isEmpty); | |
| 231 expect(results.getItem('Base')['subclasses'], isEmpty); | |
| 232 expect(results.getItem('Sub1')['subclasses'], isEmpty); | |
| 233 expect(results.getItem('Sub2')['subclasses'], equals( | |
| 234 [results.nameToIndex['Sub2a']])); | |
| 235 expect(results.getItem('Sub2a')['subclasses'], isEmpty); | |
| 236 }); | |
| 237 } | |
| 238 | |
| 239 Future getTypeHierarchy_badTarget() { | |
| 240 String text = | |
| 241 r''' | |
| 242 main() { | |
| 243 if /* target */ (true) { | |
| 244 print('Hello'); | |
| 245 } | |
| 246 } | |
| 247 '''; | |
| 248 return typeHierarchyTest(text).then((HierarchyResults results) { | |
| 249 expect(results, isNull); | |
| 250 }); | |
| 251 } | |
| 252 | |
| 253 Future getTypeHierarchy_functionTarget() { | |
| 254 String text = r''' | |
| 255 main /* target */ () { | |
| 256 } | |
| 257 '''; | |
| 258 return typeHierarchyTest(text).then((HierarchyResults results) { | |
| 259 expect(results, isNull); | |
| 260 }); | |
| 261 } | |
| 262 | |
| 263 Future<HierarchyResults> typeHierarchyTest(String text) { | |
| 264 int offset = text.indexOf(' /* target */') - 1; | |
| 265 sendAnalysisUpdateContent({ | |
| 266 pathname: { | |
| 267 'type': 'add', | |
| 268 'content': text | |
| 269 } | |
| 270 }); | |
| 271 return analysisFinished.then((_) => sendSearchGetTypeHierarchy(pathname, | |
| 272 offset)).then((result) { | |
| 273 if (result.isEmpty) { | |
| 274 return null; | |
| 275 } else { | |
| 276 return new HierarchyResults(result); | |
| 277 } | |
| 278 }); | |
| 279 } | |
| 280 } | |
| 281 | |
| 282 main() { | |
| 283 runReflectiveTests(SearchDomainIntegrationTest); | |
| 284 } | |
| OLD | NEW |