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

Side by Side Diff: pkg/analysis_server/test/analysis_notification_navigation_test.dart

Issue 314493002: Navigation computer and two variants of tests for it. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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
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.domain.analysis.notification.navigation;
6
7 import 'dart:async';
8
9 import 'package:analysis_server/src/constants.dart';
10 import 'package:analysis_server/src/protocol.dart';
11 import 'package:unittest/unittest.dart';
12
13 import 'analysis_abstract_test.dart';
14 import 'reflective_tests.dart';
15
16
17 @ReflectiveTestCase()
18 class AnalysisNotificationNavigationTest extends AbstractAnalysisTest {
19 List<Map<String, Object>> regions;
20 Map<String, Object> testRegion;
21 List<Map<String, Object>> testTargets;
22
23 void processNotification(Notification notification) {
24 if (notification.event == NOTIFICATION_NAVIGATION) {
25 String file = notification.getParameter(FILE);
26 if (file == testFile) {
27 regions = notification.getParameter(REGIONS);
28 }
29 }
30 }
31
32 Future prepareNavigation(then()) {
33 // TODO(scheglov) add subscription
34 // addAnalysisSubscriptionHighlight(testFile);
35 return waitForTasksFinished().then((_) {
36 then();
37 });
38 }
39
40 /**
41 * Finds the navigation region with the given [offset] and [length].
42 * If [length] is `-1`, then it is ignored.
43 *
44 * If [exists] is `true`, then fails if such region does not exist.
45 * Otherwise remembers this it into [testRegion].
46 * Also fills [testTargets] with its targets.
47 *
48 * If [exists] is `false`, then fails if such region exists.
49 */
50 void findRegion(int offset, int length, [bool exists]) {
51 for (Map<String, Object> region in regions) {
52 if (region['offset'] == offset &&
53 (length == -1 || region['length'] == length)) {
54 if (exists == false) {
55 fail('Not expected to find (offset=$offset; length=$length) in\n'
56 '${regions.join('\n')}');
57 }
58 testRegion = region;
59 testTargets = region['targets'];
60 return;
61 }
62 }
63 if (exists == true) {
64 fail('Expected to find (offset=$offset; length=$length) in\n'
65 '${regions.join('\n')}');
66 }
67 }
68
69 /**
70 * Validates that there is a region at the offset of [search] in [testFile].
71 * If [length] is not specified explicitly, then length of an identifier
72 * from [search] is used.
73 */
74 void assertHasRegion(String search, [int length = -1]) {
75 int offset = findOffset(search);
76 if (length == -1) {
77 length = findIdentifierLength(search);
78 }
79 findRegion(offset, length, true);
80 }
81
82 /**
83 * Validates that there is a region at the offset of [search] in [testFile]
84 * with the length of [search].
85 */
86 void assertHasRegionString(String search) {
87 int offset = findOffset(search);
88 int length = search.length;
89 findRegion(offset, length, true);
90 }
91
92 /**
93 * Validates that there is a target in [testTargets] with [testFile], at the
94 * offset of [search] in [testFile], and with the given [length] or the length
95 * of an leading identifier in [search].
96 */
97 void assertHasTarget(String search, [int length = -1]) {
98 int offset = findOffset(search);
99 if (length == -1) {
100 length = findIdentifierLength(search);
101 }
102 for (Map<String, Object> target in testTargets) {
103 if (target['file'] == testFile &&
104 target['offset'] == offset &&
105 target['length'] == length) {
106 return;
107 }
108 }
109 fail('Expected to find target (offset=$offset; length=$length) in\n'
110 '${testRegion} in\n'
111 '${regions.join('\n')}');
112 }
113
114 /**
115 * Validates that there is a target in [testTargets] with [file], at [offset]
116 * and with the given [length].
117 */
118 void assertHasFileTarget(String file, int offset, int length) {
119 for (Map<String, Object> target in testTargets) {
120 if (target['file'] == file &&
121 target['offset'] == offset &&
122 target['length'] == length) {
123 return;
124 }
125 }
126 fail('Expected to find target (file=$file; offset=$offset; length=$length) i n\n'
127 '${testRegion} in\n'
128 '${regions.join('\n')}');
129 }
130
131 /**
132 * Validates that there is an identifier region at [regionSearch] with target
133 * at [targetSearch].
134 */
135 void assertHasRegionTarget(String regionSearch, String targetSearch) {
136 assertHasRegion(regionSearch);
137 assertHasTarget(targetSearch);
138 }
139
140 void assertHasOperatorRegion(String regionSearch, int regionLength,
141 String targetSearch, int targetLength) {
142 assertHasRegion(regionSearch, regionLength);
143 assertHasTarget(targetSearch, targetLength);
144 }
145
146 /**
147 * Validates that there is no a region at [search] and with the given
148 * [length].
149 */
150 void assertNoRegion(String search, int length) {
151 int offset = findOffset(search);
152 findRegion(offset, length, false);
153 }
154
155 /**
156 * Validates that there is no a region at [search] with any length.
157 */
158 void assertNoRegionAt(String search) {
159 int offset = findOffset(search);
160 findRegion(offset, -1, false);
161 }
162
163 /**
164 * Validates that there is no a region for [search] string.
165 */
166 void assertNoRegionString(String search) {
167 int offset = findOffset(search);
168 int length = search.length;
169 findRegion(offset, length, false);
170 }
171
172 test_constructor_named() {
173 addTestFile('''
174 class A {
175 A.named(BBB p) {}
176 }
177 class BBB {}
178 ''');
179 return prepareNavigation(() {
180 // has region for complete "A.named"
181 assertHasRegionString('A.named');
182 assertHasTarget('named(BBB');
183 // no separate regions for "A" and "named"
184 assertNoRegion('A.named(', 'A'.length);
185 assertNoRegion('named(', 'named'.length);
186 // validate that we don't forget to resolve parameters
187 assertHasRegionTarget('BBB p', 'BBB {}');
188 });
189 }
190
191 test_constructor_unnamed() {
192 addTestFile('''
193 class A {
194 A(BBB p) {}
195 }
196 class BBB {}
197 ''');
198 return prepareNavigation(() {
199 // has region for complete "A.named"
200 assertHasRegion("A(BBB");
201 assertHasTarget("A(BBB", 0);
202 // validate that we don't forget to resolve parameters
203 assertHasRegionTarget('BBB p', 'BBB {}');
204 });
205 }
206
207 test_fieldFormalParameter() {
208 addTestFile('''
209 class AAA {
210 int fff = 123;
211 AAA(this.fff);
212 }
213 ''');
214 return prepareNavigation(() {
215 assertHasRegionTarget('fff);', 'fff = 123');
216 });
217 }
218
219 test_identifier_resolved() {
220 addTestFile('''
221 class AAA {}
222 main() {
223 AAA aaa = null;
224 print(aaa);
225 }
226 ''');
227 return prepareNavigation(() {
228 assertHasRegionTarget('AAA aaa', 'AAA {}');
229 assertHasRegionTarget('aaa);', 'aaa = null');
230 assertHasRegionTarget('main() {', 'main() {');
231 });
232 }
233
234 test_identifier_unresolved() {
235 addTestFile('''
236 main() {
237 print(vvv);
238 }
239 ''');
240 return prepareNavigation(() {
241 assertNoRegionString('vvv');
242 });
243 }
244
245 test_instanceCreation_named() {
246 addTestFile('''
247 class A {
248 A.named() {}
249 }
250 main() {
251 new A.named();
252 }
253 ''');
254 return prepareNavigation(() {
255 assertHasRegionString('new A.named');
256 assertHasTarget('named() {}');
257 });
258 }
259
260 test_instanceCreation_unnamed() {
261 addTestFile('''
262 class A {
263 A() {}
264 }
265 main() {
266 new A();
267 }
268 ''');
269 return prepareNavigation(() {
270 assertHasRegionString('new A');
271 assertHasTarget("A() {}", 0);
272 });
273 }
274
275 test_operator_arithmetic() {
276 addTestFile('''
277 class A {
278 A operator +(other) => null;
279 A operator -() => null;
280 A operator -(other) => null;
281 A operator *(other) => null;
282 A operator /(other) => null;
283 }
284 main() {
285 var a = new A();
286 a - 1;
287 a + 2;
288 -a; // unary
289 --a;
290 ++a;
291 a--; // mm
292 a++; // pp
293 a -= 3;
294 a += 4;
295 a *= 5;
296 a /= 6;
297 }
298 ''');
299 return prepareNavigation(() {
300 assertHasOperatorRegion('- 1', 1, '-(other) => null', 1);
301 assertHasOperatorRegion('+ 2', 1, '+(other) => null', 1);
302 assertHasOperatorRegion('-a; // unary', 1, '-() => null', 1);
303 assertHasOperatorRegion('--a;', 2, '-(other) => null', 1);
304 assertHasOperatorRegion('++a;', 2, '+(other) => null', 1);
305 assertHasOperatorRegion('--; // mm', 2, '-(other) => null', 1);
306 assertHasOperatorRegion('++; // pp', 2, '+(other) => null', 1);
307 assertHasOperatorRegion('-= 3', 2, '-(other) => null', 1);
308 assertHasOperatorRegion('+= 4', 2, '+(other) => null', 1);
309 assertHasOperatorRegion('*= 5', 2, '*(other) => null', 1);
310 assertHasOperatorRegion('/= 6', 2, '/(other) => null', 1);
311 });
312 }
313
314 test_operator_index() {
315 addTestFile('''
316 class A {
317 A operator +(other) => null;
318 }
319 class B {
320 A operator [](index) => null;
321 operator []=(index, A value) {}
322 }
323 main() {
324 var b = new B();
325 b[0] // [];
326 b[1] = 1; // []=;
327 b[2] += 2;
328 }
329 ''');
330 return prepareNavigation(() {
331 assertHasOperatorRegion('] // []', 1, '[](index)', 2);
332 assertHasOperatorRegion('] = 1;', 1, '[]=(index,', 3);
333 assertHasOperatorRegion('] += 2;', 1, '[]=(index,', 3);
334 assertHasOperatorRegion('+= 2;', 2, '+(other)', 1);
335 });
336 }
337
338 test_partOf() {
339 var libCode = 'library lib; part "test.dart";';
340 var libFile = addFile('$projectPath/bin/lib.dart', libCode);
341 addTestFile('part of lib;');
342 return prepareNavigation(() {
343 assertHasRegionString('part of lib');
344 assertHasFileTarget(libFile, libCode.indexOf('lib;'), 'lib'.length);
345 });
346 }
347
348 test_string_export() {
349 var libCode = 'library lib;';
350 var libFile = addFile('$projectPath/bin/lib.dart', libCode);
351 addTestFile('export "lib.dart";');
352 return prepareNavigation(() {
353 assertHasRegionString('export "lib.dart"');
354 assertHasFileTarget(libFile, libCode.indexOf('lib;'), 'lib'.length);
355 });
356 }
357
358 test_string_export_unresolvedUri() {
359 addTestFile('export "no.dart";');
360 return prepareNavigation(() {
361 assertNoRegionString('export "no.dart"');
362 });
363 }
364
365 test_string_import() {
366 var libCode = 'library lib;';
367 var libFile = addFile('$projectPath/bin/lib.dart', libCode);
368 addTestFile('import "lib.dart";');
369 return prepareNavigation(() {
370 assertHasRegionString('import "lib.dart"');
371 assertHasFileTarget(libFile, libCode.indexOf('lib;'), 'lib'.length);
372 });
373 }
374
375 test_string_import_noUri() {
376 addTestFile('import ;');
377 return prepareNavigation(() {
378 assertNoRegionAt('import ;');
379 });
380 }
381
382 test_string_import_unresolvedUri() {
383 addTestFile('import "no.dart";');
384 return prepareNavigation(() {
385 assertNoRegionString('import "no.dart"');
386 });
387 }
388
389 test_string_part() {
390 var unitCode = 'part of lib; f() {}';
391 var unitFile = addFile('$projectPath/bin/test_unit.dart', unitCode);
392 addTestFile('''
393 library lib;
394 part "test_unit.dart";
395 ''');
396 return prepareNavigation(() {
397 assertHasRegionString('part "test_unit.dart"');
398 assertHasFileTarget(unitFile, 0, 0);
399 });
400 }
401
402 test_string_part_unresolvedUri() {
403 // TODO(scheglov) why do we throw MemoryResourceException here?
404 // This Source/File does not exist.
405 // addTestFile('''
406 //library lib;
407 //part "test_unit.dart";
408 //''');
409 // return prepareNavigation(() {
410 // assertNoRegionString('part "test_unit.dart"');
411 // });
412 }
413 }
414
415
416 main() {
417 group('notification.navigation', () {
418 runReflectiveTests(AnalysisNotificationNavigationTest);
419 });
420 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698