| 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.services.completion.dart.keyword; | 5 library test.services.completion.dart.keyword; |
| 6 | 6 |
| 7 import 'package:analysis_server/src/protocol.dart'; | 7 import 'package:analysis_server/src/protocol.dart'; |
| 8 import 'package:analysis_server/src/services/completion/keyword_computer.dart'; | 8 import 'package:analysis_server/src/services/completion/keyword_computer.dart'; |
| 9 import '../../reflective_tests.dart'; | |
| 10 import 'package:analyzer/src/generated/scanner.dart'; | 9 import 'package:analyzer/src/generated/scanner.dart'; |
| 11 import 'package:unittest/unittest.dart'; | 10 import 'package:unittest/unittest.dart'; |
| 12 | 11 |
| 12 import '../../reflective_tests.dart'; |
| 13 import 'completion_test_util.dart'; | 13 import 'completion_test_util.dart'; |
| 14 | 14 |
| 15 main() { | 15 main() { |
| 16 groupSep = ' | '; | 16 groupSep = ' | '; |
| 17 runReflectiveTests(KeywordComputerTest); | 17 runReflectiveTests(KeywordComputerTest); |
| 18 } | 18 } |
| 19 | 19 |
| 20 @ReflectiveTestCase() | 20 @ReflectiveTestCase() |
| 21 class KeywordComputerTest extends AbstractCompletionTest { | 21 class KeywordComputerTest extends AbstractCompletionTest { |
| 22 | 22 |
| 23 void assertSuggestKeywords(List<String> names) { | 23 void assertSuggestKeywords(Iterable<Keyword> expectedKeywords) { |
| 24 Keyword.values.forEach((Keyword keyword) { | 24 Set<Keyword> actualKeywords = new Set<Keyword>(); |
| 25 if (names.contains(keyword.syntax)) { | 25 request.suggestions.forEach((CompletionSuggestion s) { |
| 26 assertSuggest(CompletionSuggestionKind.KEYWORD, keyword.syntax); | 26 if (s.kind == CompletionSuggestionKind.KEYWORD) { |
| 27 } else { | 27 Keyword k = Keyword.keywords[s.completion]; |
| 28 assertNotSuggested(keyword.syntax); | 28 if (k == null) { |
| 29 fail('Invalid keyword suggested: ${s.completion}'); |
| 30 } else { |
| 31 if (!actualKeywords.add(k)) { |
| 32 fail('Duplicate keyword suggested: ${s.completion}'); |
| 33 } |
| 34 } |
| 35 expect(s.relevance, equals(CompletionRelevance.DEFAULT)); |
| 36 expect(s.selectionOffset, equals(s.completion.length)); |
| 37 expect(s.selectionLength, equals(0)); |
| 38 expect(s.isDeprecated, equals(false)); |
| 39 expect(s.isPotential, equals(false)); |
| 29 } | 40 } |
| 30 }); | 41 }); |
| 42 if (expectedKeywords.any((k) => k is String)) { |
| 43 StringBuffer msg = new StringBuffer(); |
| 44 msg.writeln('Expected set should be:'); |
| 45 expectedKeywords.forEach((n) { |
| 46 Keyword k = Keyword.keywords[n]; |
| 47 msg.writeln(' Keyword.${k.name},'); |
| 48 }); |
| 49 fail(msg.toString()); |
| 50 } |
| 51 if (!_equalSets(expectedKeywords, actualKeywords)) { |
| 52 StringBuffer msg = new StringBuffer(); |
| 53 msg.writeln('Expected:'); |
| 54 _appendKeywords(msg, expectedKeywords); |
| 55 msg.writeln('but found:'); |
| 56 _appendKeywords(msg, actualKeywords); |
| 57 fail(msg.toString()); |
| 58 } |
| 31 } | 59 } |
| 32 | 60 |
| 33 @override | 61 @override |
| 34 void setUp() { | 62 void setUp() { |
| 35 super.setUp(); | 63 super.setUp(); |
| 36 computer = new KeywordComputer(); | 64 computer = new KeywordComputer(); |
| 37 } | 65 } |
| 38 | 66 |
| 39 test_after_class() { | 67 test_after_class() { |
| 40 addTestSource('class A {} ^'); | 68 addTestSource('class A {} ^'); |
| 41 expect(computeFast(), isTrue); | 69 expect(computeFast(), isTrue); |
| 42 assertSuggestKeywords( | 70 assertSuggestKeywords( |
| 43 ['abstract', 'class', 'const', 'final', 'typedef', 'var']); | 71 [ |
| 72 Keyword.ABSTRACT, |
| 73 Keyword.CLASS, |
| 74 Keyword.CONST, |
| 75 Keyword.FINAL, |
| 76 Keyword.TYPEDEF, |
| 77 Keyword.VAR]); |
| 44 } | 78 } |
| 45 | 79 |
| 46 test_before_import() { | 80 test_before_import() { |
| 47 addTestSource('^ import foo;'); | 81 addTestSource('^ import foo;'); |
| 48 expect(computeFast(), isTrue); | 82 expect(computeFast(), isTrue); |
| 49 assertSuggestKeywords(['export', 'import', 'library', 'part']); | 83 assertSuggestKeywords( |
| 84 [Keyword.EXPORT, Keyword.IMPORT, Keyword.LIBRARY, Keyword.PART]); |
| 50 } | 85 } |
| 51 | 86 |
| 52 test_class() { | 87 test_class() { |
| 53 addTestSource('class A ^'); | 88 addTestSource('class A ^'); |
| 54 expect(computeFast(), isTrue); | 89 expect(computeFast(), isTrue); |
| 55 assertSuggestKeywords(['extends', 'implements']); | 90 assertSuggestKeywords([Keyword.EXTENDS, Keyword.IMPLEMENTS]); |
| 56 } | 91 } |
| 57 | 92 |
| 58 test_class_extends() { | 93 test_class_extends() { |
| 59 addTestSource('class A extends foo ^'); | 94 addTestSource('class A extends foo ^'); |
| 60 expect(computeFast(), isTrue); | 95 expect(computeFast(), isTrue); |
| 61 assertSuggestKeywords(['implements', 'with']); | 96 assertSuggestKeywords([Keyword.IMPLEMENTS, Keyword.WITH]); |
| 62 } | 97 } |
| 63 | 98 |
| 64 test_class_extends_name() { | 99 test_class_extends_name() { |
| 65 addTestSource('class A extends ^'); | 100 addTestSource('class A extends ^'); |
| 66 expect(computeFast(), isTrue); | 101 expect(computeFast(), isTrue); |
| 67 assertSuggestKeywords([]); | 102 assertSuggestKeywords([]); |
| 68 } | 103 } |
| 69 | 104 |
| 70 test_class_implements() { | 105 test_class_implements() { |
| 71 addTestSource('class A ^ implements foo'); | 106 addTestSource('class A ^ implements foo'); |
| 72 expect(computeFast(), isTrue); | 107 expect(computeFast(), isTrue); |
| 73 assertSuggestKeywords(['extends']); | 108 assertSuggestKeywords([Keyword.EXTENDS]); |
| 74 } | 109 } |
| 75 | 110 |
| 76 test_class_implements_name() { | 111 test_class_implements_name() { |
| 77 addTestSource('class A implements ^'); | 112 addTestSource('class A implements ^'); |
| 78 expect(computeFast(), isTrue); | 113 expect(computeFast(), isTrue); |
| 79 assertSuggestKeywords([]); | 114 assertSuggestKeywords([]); |
| 80 } | 115 } |
| 81 | 116 |
| 82 test_class_name() { | 117 test_class_name() { |
| 83 addTestSource('class ^'); | 118 addTestSource('class ^'); |
| 84 expect(computeFast(), isTrue); | 119 expect(computeFast(), isTrue); |
| 85 assertSuggestKeywords([]); | 120 assertSuggestKeywords([]); |
| 86 } | 121 } |
| 87 | 122 |
| 88 test_class_with_name() { | 123 test_class_with_name() { |
| 89 addTestSource('class A extends foo with ^'); | 124 addTestSource('class A extends foo with ^'); |
| 90 expect(computeFast(), isTrue); | 125 expect(computeFast(), isTrue); |
| 91 assertSuggestKeywords([]); | 126 assertSuggestKeywords([]); |
| 92 } | 127 } |
| 93 | 128 |
| 94 test_empty() { | 129 test_empty() { |
| 95 addTestSource('^'); | 130 addTestSource('^'); |
| 96 expect(computeFast(), isTrue); | 131 expect(computeFast(), isTrue); |
| 97 assertSuggestKeywords( | 132 assertSuggestKeywords( |
| 98 [ | 133 [ |
| 99 'abstract', | 134 Keyword.ABSTRACT, |
| 100 'class', | 135 Keyword.CLASS, |
| 101 'const', | 136 Keyword.CONST, |
| 102 'export', | 137 Keyword.EXPORT, |
| 103 'final', | 138 Keyword.FINAL, |
| 104 'import', | 139 Keyword.IMPORT, |
| 105 'library', | 140 Keyword.LIBRARY, |
| 106 'part', | 141 Keyword.PART, |
| 107 'typedef', | 142 Keyword.TYPEDEF, |
| 108 'var']); | 143 Keyword.VAR]); |
| 144 } |
| 145 |
| 146 test_function_body() { |
| 147 addTestSource('main() {^}'); |
| 148 expect(computeFast(), isTrue); |
| 149 assertSuggestKeywords( |
| 150 [ |
| 151 Keyword.ASSERT, |
| 152 Keyword.CASE, |
| 153 Keyword.CONTINUE, |
| 154 Keyword.DO, |
| 155 Keyword.FACTORY, |
| 156 Keyword.FINAL, |
| 157 Keyword.FOR, |
| 158 Keyword.IF, |
| 159 Keyword.NEW, |
| 160 Keyword.RETHROW, |
| 161 Keyword.RETURN, |
| 162 Keyword.SUPER, |
| 163 Keyword.SWITCH, |
| 164 Keyword.THIS, |
| 165 Keyword.THROW, |
| 166 Keyword.TRY, |
| 167 Keyword.VAR, |
| 168 Keyword.VOID, |
| 169 Keyword.WHILE]); |
| 170 } |
| 171 |
| 172 test_in_class() { |
| 173 addTestSource('class A {^}'); |
| 174 expect(computeFast(), isTrue); |
| 175 assertSuggestKeywords( |
| 176 [ |
| 177 Keyword.CONST, |
| 178 Keyword.DYNAMIC, |
| 179 Keyword.FACTORY, |
| 180 Keyword.FINAL, |
| 181 Keyword.GET, |
| 182 Keyword.OPERATOR, |
| 183 Keyword.SET, |
| 184 Keyword.STATIC, |
| 185 Keyword.VAR, |
| 186 Keyword.VOID]); |
| 109 } | 187 } |
| 110 | 188 |
| 111 test_library() { | 189 test_library() { |
| 112 addTestSource('library foo;^'); | 190 addTestSource('library foo;^'); |
| 113 expect(computeFast(), isTrue); | 191 expect(computeFast(), isTrue); |
| 114 assertSuggestKeywords( | 192 assertSuggestKeywords( |
| 115 [ | 193 [ |
| 116 'abstract', | 194 Keyword.ABSTRACT, |
| 117 'class', | 195 Keyword.CLASS, |
| 118 'const', | 196 Keyword.CONST, |
| 119 'export', | 197 Keyword.EXPORT, |
| 120 'final', | 198 Keyword.FINAL, |
| 121 'import', | 199 Keyword.IMPORT, |
| 122 'part', | 200 Keyword.PART, |
| 123 'typedef', | 201 Keyword.TYPEDEF, |
| 124 'var']); | 202 Keyword.VAR]); |
| 125 } | 203 } |
| 126 | 204 |
| 127 test_library_name() { | 205 test_library_name() { |
| 128 addTestSource('library ^'); | 206 addTestSource('library ^'); |
| 129 expect(computeFast(), isTrue); | 207 expect(computeFast(), isTrue); |
| 130 assertSuggestKeywords([]); | 208 assertSuggestKeywords([]); |
| 131 } | 209 } |
| 132 | 210 |
| 211 test_method_body() { |
| 212 addTestSource('class A { foo() {^}}'); |
| 213 expect(computeFast(), isTrue); |
| 214 assertSuggestKeywords( |
| 215 [ |
| 216 Keyword.ASSERT, |
| 217 Keyword.CASE, |
| 218 Keyword.CONTINUE, |
| 219 Keyword.DO, |
| 220 Keyword.FACTORY, |
| 221 Keyword.FINAL, |
| 222 Keyword.FOR, |
| 223 Keyword.IF, |
| 224 Keyword.NEW, |
| 225 Keyword.RETHROW, |
| 226 Keyword.RETURN, |
| 227 Keyword.SUPER, |
| 228 Keyword.SWITCH, |
| 229 Keyword.THIS, |
| 230 Keyword.THROW, |
| 231 Keyword.TRY, |
| 232 Keyword.VAR, |
| 233 Keyword.VOID, |
| 234 Keyword.WHILE]); |
| 235 } |
| 236 |
| 237 test_named_constructor_invocation() { |
| 238 addTestSource('void main() {new Future.^}'); |
| 239 expect(computeFast(), isTrue); |
| 240 assertSuggestKeywords([]); |
| 241 } |
| 242 |
| 133 test_part_of() { | 243 test_part_of() { |
| 134 addTestSource('part of foo;^'); | 244 addTestSource('part of foo;^'); |
| 135 expect(computeFast(), isTrue); | 245 expect(computeFast(), isTrue); |
| 136 assertSuggestKeywords( | 246 assertSuggestKeywords( |
| 137 [ | 247 [ |
| 138 'abstract', | 248 Keyword.ABSTRACT, |
| 139 'class', | 249 Keyword.CLASS, |
| 140 'const', | 250 Keyword.CONST, |
| 141 'export', | 251 Keyword.EXPORT, |
| 142 'final', | 252 Keyword.FINAL, |
| 143 'import', | 253 Keyword.IMPORT, |
| 144 'part', | 254 Keyword.PART, |
| 145 'typedef', | 255 Keyword.TYPEDEF, |
| 146 'var']); | 256 Keyword.VAR]); |
| 147 } | 257 } |
| 148 | 258 |
| 149 test_partial_class() { | 259 test_partial_class() { |
| 150 addTestSource('cl^'); | 260 addTestSource('cl^'); |
| 151 expect(computeFast(), isTrue); | 261 expect(computeFast(), isTrue); |
| 152 assertSuggestKeywords( | 262 assertSuggestKeywords( |
| 153 [ | 263 [ |
| 154 'abstract', | 264 Keyword.ABSTRACT, |
| 155 'class', | 265 Keyword.CLASS, |
| 156 'const', | 266 Keyword.CONST, |
| 157 'export', | 267 Keyword.EXPORT, |
| 158 'final', | 268 Keyword.FINAL, |
| 159 'import', | 269 Keyword.IMPORT, |
| 160 'library', | 270 Keyword.LIBRARY, |
| 161 'part', | 271 Keyword.PART, |
| 162 'typedef', | 272 Keyword.TYPEDEF, |
| 163 'var']); | 273 Keyword.VAR]); |
| 164 } | 274 } |
| 165 | 275 |
| 166 test_partial_class2() { | 276 test_partial_class2() { |
| 167 addTestSource('library a; cl^'); | 277 addTestSource('library a; cl^'); |
| 168 expect(computeFast(), isTrue); | 278 expect(computeFast(), isTrue); |
| 169 assertSuggestKeywords( | 279 assertSuggestKeywords( |
| 170 [ | 280 [ |
| 171 'abstract', | 281 Keyword.ABSTRACT, |
| 172 'class', | 282 Keyword.CLASS, |
| 173 'const', | 283 Keyword.CONST, |
| 174 'export', | 284 Keyword.EXPORT, |
| 175 'final', | 285 Keyword.FINAL, |
| 176 'import', | 286 Keyword.IMPORT, |
| 177 'part', | 287 Keyword.PART, |
| 178 'typedef', | 288 Keyword.TYPEDEF, |
| 179 'var']); | 289 Keyword.VAR]); |
| 290 } |
| 291 |
| 292 void _appendKeywords(StringBuffer msg, Iterable<Keyword> keywords) { |
| 293 List<Keyword> sorted = keywords.toList(); |
| 294 sorted.sort((k1, k2) => k1.name.compareTo(k2.name)); |
| 295 sorted.forEach((k) => msg.writeln(' Keyword.${k.name},')); |
| 296 } |
| 297 |
| 298 bool _equalSets(Iterable<Keyword> iter1, Iterable<Keyword> iter2) { |
| 299 if (iter1.length != iter2.length) return false; |
| 300 if (iter1.any((k) => !iter2.contains(k))) return false; |
| 301 if (iter2.any((k) => !iter1.contains(k))) return false; |
| 302 return true; |
| 180 } | 303 } |
| 181 } | 304 } |
| OLD | NEW |