OLD | NEW |
| (Empty) |
1 // Copyright (c) 2015, 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 // VMOptions=--compile-all --error_on_bad_type --error_on_bad_override --checked | |
5 | |
6 import 'package:observatory/service_io.dart'; | |
7 import 'package:observatory/debugger.dart'; | |
8 import 'package:unittest/unittest.dart'; | |
9 import 'test_helper.dart'; | |
10 import 'dart:async'; | |
11 | |
12 void testFunction() { | |
13 int i = 0; | |
14 while (true) { | |
15 if (++i % 100000000 == 0) { // line 15 | |
16 print(i); | |
17 } | |
18 } | |
19 } | |
20 | |
21 class TestDebugger extends Debugger { | |
22 TestDebugger(this.isolate, this.stack); | |
23 | |
24 VM get vm => isolate.vm; | |
25 Isolate isolate; | |
26 ServiceMap stack; | |
27 int currentFrame = 0; | |
28 } | |
29 | |
30 void source_location_dummy_function() { | |
31 } | |
32 | |
33 class SourceLocationTestFoo { | |
34 SourceLocationTestFoo(this.field); | |
35 SourceLocationTestFoo.named(); | |
36 | |
37 void method() {} | |
38 void madness() {} | |
39 | |
40 int field; | |
41 } | |
42 | |
43 class SourceLocationTestBar { | |
44 } | |
45 | |
46 Future<Debugger> initDebugger(Isolate isolate) { | |
47 return isolate.getStack().then((stack) { | |
48 return new TestDebugger(isolate, stack); | |
49 }); | |
50 } | |
51 | |
52 var tests = [ | |
53 | |
54 // Bring the isolate to a breakpoint at line 15. | |
55 (Isolate isolate) { | |
56 return isolate.rootLib.load().then((_) { | |
57 // Listen for breakpoint event. | |
58 Completer completer = new Completer(); | |
59 isolate.vm.events.stream.listen((ServiceEvent event) { | |
60 if (event.eventType == ServiceEvent.kPauseBreakpoint) { | |
61 completer.complete(); | |
62 } | |
63 }); | |
64 | |
65 // Add the breakpoint. | |
66 var script = isolate.rootLib.scripts[0]; | |
67 return isolate.addBreakpoint(script, 15).then((ServiceObject bpt) { | |
68 return completer.future; // Wait for breakpoint events. | |
69 }); | |
70 }); | |
71 }, | |
72 | |
73 // Parse '' => current position | |
74 (Isolate isolate) { | |
75 return initDebugger(isolate).then((debugger) { | |
76 return SourceLocation.parse(debugger, '').then((SourceLocation loc) { | |
77 expect(loc.valid, isTrue); | |
78 expect(loc.toString(), equals('source_location_test.dart:15')); | |
79 }); | |
80 }); | |
81 }, | |
82 | |
83 // Parse line | |
84 (Isolate isolate) { | |
85 return initDebugger(isolate).then((debugger) { | |
86 return SourceLocation.parse(debugger, '16').then((SourceLocation loc) { | |
87 expect(loc.valid, isTrue); | |
88 expect(loc.toString(), equals('source_location_test.dart:16')); | |
89 }); | |
90 }); | |
91 }, | |
92 | |
93 // Parse line + col | |
94 (Isolate isolate) { | |
95 return initDebugger(isolate).then((debugger) { | |
96 return SourceLocation.parse(debugger, '16:11').then((SourceLocation loc) { | |
97 expect(loc.valid, isTrue); | |
98 expect(loc.toString(), equals('source_location_test.dart:16:11')); | |
99 }); | |
100 }); | |
101 }, | |
102 | |
103 // Parse script + line | |
104 (Isolate isolate) { | |
105 return initDebugger(isolate).then((debugger) { | |
106 return SourceLocation.parse(debugger, 'unittest.dart:15') | |
107 .then((SourceLocation loc) { | |
108 expect(loc.valid, isTrue); | |
109 expect(loc.toString(), equals('unittest.dart:15')); | |
110 }); | |
111 }); | |
112 }, | |
113 | |
114 // Parse script + line + col | |
115 (Isolate isolate) { | |
116 return initDebugger(isolate).then((debugger) { | |
117 return SourceLocation.parse(debugger, 'unittest.dart:15:10') | |
118 .then((SourceLocation loc) { | |
119 expect(loc.valid, isTrue); | |
120 expect(loc.toString(), equals('unittest.dart:15:10')); | |
121 }); | |
122 }); | |
123 }, | |
124 | |
125 // Parse bad script | |
126 (Isolate isolate) { | |
127 return initDebugger(isolate).then((debugger) { | |
128 return SourceLocation.parse(debugger, 'bad.dart:15') | |
129 .then((SourceLocation loc) { | |
130 expect(loc.valid, isFalse); | |
131 expect(loc.toString(), equals( | |
132 'invalid source location (Script \'bad.dart\' not found)')); | |
133 }); | |
134 }); | |
135 }, | |
136 | |
137 // Parse function | |
138 (Isolate isolate) { | |
139 return initDebugger(isolate).then((debugger) { | |
140 return SourceLocation.parse(debugger, 'testFunction') | |
141 .then((SourceLocation loc) { | |
142 expect(loc.valid, isTrue); | |
143 expect(loc.toString(), equals('testFunction')); | |
144 }); | |
145 }); | |
146 }, | |
147 | |
148 // Parse bad function | |
149 (Isolate isolate) { | |
150 return initDebugger(isolate).then((debugger) { | |
151 return SourceLocation.parse(debugger, 'doesNotReallyExit') | |
152 .then((SourceLocation loc) { | |
153 expect(loc.valid, isFalse); | |
154 expect(loc.toString(), equals( | |
155 'invalid source location (Function \'doesNotReallyExit\' not found)'
)); | |
156 }); | |
157 }); | |
158 }, | |
159 | |
160 // Parse constructor | |
161 (Isolate isolate) { | |
162 return initDebugger(isolate).then((debugger) { | |
163 return SourceLocation.parse(debugger, 'SourceLocationTestFoo') | |
164 .then((SourceLocation loc) { | |
165 expect(loc.valid, isTrue); | |
166 // TODO(turnidge): Printing a constructor currently adds | |
167 // another class qualifier at the front. Do we want to change | |
168 // this to be more consistent? | |
169 expect(loc.toString(), equals( | |
170 'SourceLocationTestFoo.SourceLocationTestFoo')); | |
171 }); | |
172 }); | |
173 }, | |
174 | |
175 // Parse named constructor | |
176 (Isolate isolate) { | |
177 return initDebugger(isolate).then((debugger) { | |
178 return SourceLocation.parse(debugger, 'SourceLocationTestFoo.named') | |
179 .then((SourceLocation loc) { | |
180 expect(loc.valid, isTrue); | |
181 // TODO(turnidge): Printing a constructor currently adds | |
182 // another class qualifier at the front. Do we want to change | |
183 // this to be more consistent? | |
184 expect(loc.toString(), equals( | |
185 'SourceLocationTestFoo.SourceLocationTestFoo.named')); | |
186 }); | |
187 }); | |
188 }, | |
189 | |
190 // Parse method | |
191 (Isolate isolate) { | |
192 return initDebugger(isolate).then((debugger) { | |
193 return SourceLocation.parse(debugger, 'SourceLocationTestFoo.method') | |
194 .then((SourceLocation loc) { | |
195 expect(loc.valid, isTrue); | |
196 expect(loc.toString(), equals('SourceLocationTestFoo.method')); | |
197 }); | |
198 }); | |
199 }, | |
200 | |
201 // Parse method | |
202 (Isolate isolate) { | |
203 return initDebugger(isolate).then((debugger) { | |
204 return SourceLocation.parse(debugger, 'SourceLocationTestFoo.field=') | |
205 .then((SourceLocation loc) { | |
206 expect(loc.valid, isTrue); | |
207 expect(loc.toString(), equals('SourceLocationTestFoo.field=')); | |
208 }); | |
209 }); | |
210 }, | |
211 | |
212 // Parse bad method | |
213 (Isolate isolate) { | |
214 return initDebugger(isolate).then((debugger) { | |
215 return SourceLocation.parse(debugger, 'SourceLocationTestFoo.missing') | |
216 .then((SourceLocation loc) { | |
217 expect(loc.valid, isFalse); | |
218 expect(loc.toString(), equals( | |
219 'invalid source location ' | |
220 '(Function \'SourceLocationTestFoo.missing\' not found)')); | |
221 }); | |
222 }); | |
223 }, | |
224 | |
225 // Complete function + script | |
226 (Isolate isolate) { | |
227 return initDebugger(isolate).then((debugger) { | |
228 return SourceLocation.complete(debugger, 'source_loc') | |
229 .then((List<String> completions) { | |
230 expect(completions.toString(), equals( | |
231 '[source_location_dummy_function, ' | |
232 'source_location.dart:, source_location_test.dart:]')); | |
233 }); | |
234 }); | |
235 }, | |
236 | |
237 // Complete class | |
238 (Isolate isolate) { | |
239 return initDebugger(isolate).then((debugger) { | |
240 return SourceLocation.complete(debugger, 'SourceLocationTe') | |
241 .then((List<String> completions) { | |
242 expect(completions.toString(), equals( | |
243 '[SourceLocationTestBar, SourceLocationTestFoo]')); | |
244 }); | |
245 }); | |
246 }, | |
247 | |
248 // No completions: unqualified name | |
249 (Isolate isolate) { | |
250 return initDebugger(isolate).then((debugger) { | |
251 return SourceLocation.complete(debugger, 'source_locXYZZY') | |
252 .then((List<String> completions) { | |
253 expect(completions.toString(), equals('[]')); | |
254 }); | |
255 }); | |
256 }, | |
257 | |
258 // Complete method | |
259 (Isolate isolate) { | |
260 return initDebugger(isolate).then((debugger) { | |
261 return SourceLocation.complete(debugger, 'SourceLocationTestFoo.m') | |
262 .then((List<String> completions) { | |
263 expect(completions.toString(), equals( | |
264 '[SourceLocationTestFoo.madness, SourceLocationTestFoo.method]')); | |
265 }); | |
266 }); | |
267 }, | |
268 | |
269 // No completions: qualified name | |
270 (Isolate isolate) { | |
271 return initDebugger(isolate).then((debugger) { | |
272 return SourceLocation.complete(debugger, 'SourceLocationTestFoo.q') | |
273 .then((List<String> completions) { | |
274 expect(completions.toString(), equals('[]')); | |
275 }); | |
276 }); | |
277 }, | |
278 | |
279 ]; | |
280 | |
281 main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction); | |
OLD | NEW |