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