| 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 test_getTypeHierarchy_classElement() { |
| 64 String text = |
| 65 r''' |
| 66 class Base {} |
| 67 class Pivot /* target */ extends Base {} |
| 68 class Derived extends Pivot {} |
| 69 '''; |
| 70 return typeHierarchyTest(text).then((HierarchyResults results) { |
| 71 expect(results.items, hasLength(4)); |
| 72 expect(results.nameToIndex['Pivot'], equals(0)); |
| 73 void checkElement(String name) { |
| 74 // We don't check the full element data structure; just enough to make |
| 75 // sure that we're pointing to the correct element. |
| 76 Map element = results.items[results.nameToIndex[name]]['classElement']; |
| 77 expect(element['kind'], equals('CLASS')); |
| 78 expect(element['name'], equals(name)); |
| 79 if (name != 'Object') { |
| 80 expect(element['location']['offset'], equals(text.indexOf( |
| 81 'class $name') + 'class '.length)); |
| 82 } |
| 83 } |
| 84 checkElement('Object'); |
| 85 checkElement('Base'); |
| 86 checkElement('Pivot'); |
| 87 checkElement('Derived'); |
| 88 }); |
| 89 } |
| 90 |
| 91 test_getTypeHierarchy_displayName() { |
| 92 String text = r''' |
| 93 class Base<T> {} |
| 94 class Pivot /* target */ extends Base<int> {} |
| 95 '''; |
| 96 return typeHierarchyTest(text).then((HierarchyResults results) { |
| 97 expect(results.items, hasLength(3)); |
| 98 expect(results.getItem('Object')['displayName'], isNull); |
| 99 expect(results.getItem('Base')['displayName'], equals('Base<int>')); |
| 100 expect(results.getItem('Pivot')['displayName'], isNull); |
| 101 }); |
| 102 } |
| 103 |
| 104 test_getTypeHierarchy_memberElement() { |
| 105 String text = |
| 106 r''' |
| 107 class Base1 { |
| 108 void foo /* base1 */ (); |
| 109 } |
| 110 class Base2 extends Base1 {} |
| 111 class Pivot extends Base2 { |
| 112 void foo /* target */ (); |
| 113 } |
| 114 class Derived1 extends Pivot {} |
| 115 class Derived2 extends Derived1 { |
| 116 void foo /* derived2 */ (); |
| 117 }'''; |
| 118 return typeHierarchyTest(text).then((HierarchyResults results) { |
| 119 expect(results.items, hasLength(6)); |
| 120 expect(results.getItem('Object')['memberElement'], isNull); |
| 121 expect(results.getItem('Base1')['memberElement']['location']['offset'], |
| 122 equals(text.indexOf('foo /* base1 */'))); |
| 123 expect(results.getItem('Base2')['memberElement'], isNull); |
| 124 expect(results.getItem('Pivot')['memberElement']['location']['offset'], |
| 125 equals(text.indexOf('foo /* target */'))); |
| 126 expect(results.getItem('Derived1')['memberElement'], isNull); |
| 127 expect(results.getItem('Derived2')['memberElement']['location']['offset'], |
| 128 equals(text.indexOf('foo /* derived2 */'))); |
| 129 }); |
| 130 } |
| 131 |
| 132 test_getTypeHierarchy_superclass() { |
| 133 String text = |
| 134 r''' |
| 135 class Base1 {} |
| 136 class Base2 extends Base1 {} |
| 137 class Pivot /* target */ extends Base2 {} |
| 138 '''; |
| 139 return typeHierarchyTest(text).then((HierarchyResults results) { |
| 140 expect(results.items, hasLength(4)); |
| 141 expect(results.getItem('Object')['superclass'], isNull); |
| 142 expect(results.getItem('Base1')['superclass'], equals( |
| 143 results.nameToIndex['Object'])); |
| 144 expect(results.getItem('Base2')['superclass'], equals( |
| 145 results.nameToIndex['Base1'])); |
| 146 expect(results.getItem('Pivot')['superclass'], equals( |
| 147 results.nameToIndex['Base2'])); |
| 148 }); |
| 149 } |
| 150 |
| 151 test_getTypeHierarchy_interfaces() { |
| 152 String text = |
| 153 r''' |
| 154 class Interface1 {} |
| 155 class Interface2 {} |
| 156 class Pivot /* target */ implements Interface1, Interface2 {} |
| 157 '''; |
| 158 return typeHierarchyTest(text).then((HierarchyResults results) { |
| 159 expect(results.items, hasLength(4)); |
| 160 expect(results.pivot['interfaces'], hasLength(2)); |
| 161 expect(results.pivot['interfaces'], contains( |
| 162 results.nameToIndex['Interface1'])); |
| 163 expect(results.pivot['interfaces'], contains( |
| 164 results.nameToIndex['Interface2'])); |
| 165 expect(results.getItem('Object')['interfaces'], isEmpty); |
| 166 expect(results.getItem('Interface1')['interfaces'], isEmpty); |
| 167 expect(results.getItem('Interface2')['interfaces'], isEmpty); |
| 168 }); |
| 169 } |
| 170 |
| 171 test_getTypeHierarchy_mixins() { |
| 172 String text = |
| 173 r''' |
| 174 class Base {} |
| 175 class Mixin1 {} |
| 176 class Mixin2 {} |
| 177 class Pivot /* target */ extends Base with Mixin1, Mixin2 {} |
| 178 '''; |
| 179 return typeHierarchyTest(text).then((HierarchyResults results) { |
| 180 expect(results.items, hasLength(5)); |
| 181 expect(results.pivot['mixins'], hasLength(2)); |
| 182 expect(results.pivot['mixins'], contains(results.nameToIndex['Mixin1'])); |
| 183 expect(results.pivot['mixins'], contains(results.nameToIndex['Mixin2'])); |
| 184 expect(results.getItem('Object')['mixins'], isEmpty); |
| 185 expect(results.getItem('Base')['mixins'], isEmpty); |
| 186 expect(results.getItem('Mixin1')['mixins'], isEmpty); |
| 187 expect(results.getItem('Mixin2')['mixins'], isEmpty); |
| 188 }); |
| 189 } |
| 190 |
| 191 test_getTypeHierarchy_subclasses() { |
| 192 String text = |
| 193 r''' |
| 194 class Base {} |
| 195 class Pivot /* target */ extends Base {} |
| 196 class Sub1 extends Pivot {} |
| 197 class Sub2 extends Pivot {} |
| 198 class Sub2a extends Sub2 {} |
| 199 '''; |
| 200 return typeHierarchyTest(text).then((HierarchyResults results) { |
| 201 expect(results.items, hasLength(6)); |
| 202 expect(results.pivot['subclasses'], hasLength(2)); |
| 203 expect(results.pivot['subclasses'], contains(results.nameToIndex['Sub1']) |
| 204 ); |
| 205 expect(results.pivot['subclasses'], contains(results.nameToIndex['Sub2']) |
| 206 ); |
| 207 expect(results.getItem('Object')['subclasses'], isEmpty); |
| 208 expect(results.getItem('Base')['subclasses'], isEmpty); |
| 209 expect(results.getItem('Sub1')['subclasses'], isEmpty); |
| 210 expect(results.getItem('Sub2')['subclasses'], equals( |
| 211 [results.nameToIndex['Sub2a']])); |
| 212 expect(results.getItem('Sub2a')['subclasses'], isEmpty); |
| 213 }); |
| 214 } |
| 215 |
| 216 test_getTypeHierarchy_badTarget() { |
| 217 String text = |
| 218 r''' |
| 219 main() { |
| 220 if /* target */ (true) { |
| 221 print('Hello'); |
| 222 } |
| 223 } |
| 224 '''; |
| 225 return typeHierarchyTest(text).then((HierarchyResults results) { |
| 226 expect(results, isNull); |
| 227 }); |
| 228 } |
| 229 |
| 230 test_getTypeHierarchy_functionTarget() { |
| 231 String text = |
| 232 r''' |
| 233 main /* target */ () { |
| 234 } |
| 235 '''; |
| 236 return typeHierarchyTest(text).then((HierarchyResults results) { |
| 237 expect(results, isNull); |
| 238 }); |
| 239 } |
| 240 |
| 241 Future<HierarchyResults> typeHierarchyTest(String text) { |
| 242 String pathname = sourcePath('test.dart'); |
| 243 int offset = text.indexOf(' /* target */') - 1; |
| 244 writeFile(pathname, text); |
| 245 standardAnalysisRoot(); |
| 246 return analysisFinished.then((_) => sendSearchGetTypeHierarchy(pathname, |
| 247 offset)).then((result) { |
| 248 if (result.isEmpty) { |
| 249 return null; |
| 250 } else { |
| 251 return new HierarchyResults(result); |
| 252 } |
| 253 }); |
| 254 } |
| 255 } |
| 256 |
| 257 main() { |
| 258 runReflectiveTests(SearchDomainIntegrationTest); |
| 259 } |
| OLD | NEW |