// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. import 'package:observatory/service_io.dart'; import 'package:observatory/debugger.dart'; import 'package:test/test.dart'; import 'service_test_common.dart'; import 'test_helper.dart'; import 'dart:async'; import 'dart:developer'; const int LINE_A = 21; const int LINE_B = 110; const int LINE_C = 11; void testFunction() { int i = 0; while (i == 0) { debugger(); print('loop'); // Line A. print('loop'); } } class TestDebugger extends Debugger { TestDebugger(this.isolate, this.stack); VM get vm => isolate.vm; Isolate isolate; ServiceMap stack; int currentFrame = 0; } void debugger_location_dummy_function() {} class DebuggerLocationTestFoo { DebuggerLocationTestFoo(this.field); DebuggerLocationTestFoo.named(); void method() {} void madness() {} int? field; } class DebuggerLocationTestBar {} Future initDebugger(Isolate isolate) { return isolate.getStack().then((stack) { return new TestDebugger(isolate, stack); }); } var tests = [ hasStoppedAtBreakpoint, // Load the isolate's libraries (Isolate isolate) async { for (var lib in isolate.libraries) { await lib.load(); } }, // Parse method (Isolate isolate) async { var debugger = await initDebugger(isolate); var loc = await DebuggerLocation.parse( debugger, 'DebuggerLocationTestFoo.method'); expect(loc.valid, isTrue); expect(loc.toString(), equals('DebuggerLocationTestFoo.method')); }, // Parse method (Isolate isolate) async { var debugger = await initDebugger(isolate); var loc = await DebuggerLocation.parse( debugger, 'DebuggerLocationTestFoo.field='); expect(loc.valid, isTrue); expect(loc.toString(), equals('DebuggerLocationTestFoo.field=')); }, // Parse bad method (Isolate isolate) async { var debugger = await initDebugger(isolate); var loc = await DebuggerLocation.parse( debugger, 'DebuggerLocationTestFoo.missing'); expect(loc.valid, isFalse); expect( loc.toString(), equals('invalid source location ' '(Function \'DebuggerLocationTestFoo.missing\' not found)')); }, // Complete function + script (Isolate isolate) async { var debugger = await initDebugger(isolate); var completions = await DebuggerLocation.complete(debugger, 'debugger_loc'); expect( completions.toString(), equals('[debugger_location_dummy_function,' ' debugger_location.dart:,' ' debugger_location_second_test.dart:]')); }, // Complete class (Isolate isolate) async { var debugger = await initDebugger(isolate); var completions = await DebuggerLocation.complete(debugger, 'DebuggerLocationTe'); expect( completions.toString(), equals('[DebuggerLocationTestBar,' ' DebuggerLocationTestFoo]')); }, // No completions: unqualified name (Isolate isolate) async { var debugger = await initDebugger(isolate); var completions = await DebuggerLocation.complete(debugger, 'debugger_locXYZZY'); expect(completions.toString(), equals('[]')); }, // Complete method (Isolate isolate) async { var debugger = await initDebugger(isolate); var completions = await DebuggerLocation.complete(debugger, 'DebuggerLocationTestFoo.m'); expect( completions.toString(), equals('[DebuggerLocationTestFoo.madness,' ' DebuggerLocationTestFoo.method]')); }, // No completions: qualified name (Isolate isolate) async { var debugger = await initDebugger(isolate); var completions = await DebuggerLocation.complete(debugger, 'DebuggerLocationTestFoo.q'); expect(completions.toString(), equals('[]')); }, // Complete script (Isolate isolate) async { var debugger = await initDebugger(isolate); var completions = await DebuggerLocation.complete( debugger, 'debugger_location_second_te'); expect(completions.toString(), equals('[debugger_location_second_test.dart:]')); }, // Complete script:line (Isolate isolate) async { var debugger = await initDebugger(isolate); var completions = await DebuggerLocation.complete( debugger, 'debugger_location_second_test.dart:11'); expect( completions.toString(), equals('[debugger_location_second_test.dart:${LINE_B + 0} ,' ' debugger_location_second_test.dart:${LINE_B + 0}:,' ' debugger_location_second_test.dart:${LINE_B + 1} ,' ' debugger_location_second_test.dart:${LINE_B + 1}:,' ' debugger_location_second_test.dart:${LINE_B + 2} ,' ' debugger_location_second_test.dart:${LINE_B + 2}:,' ' debugger_location_second_test.dart:${LINE_B + 3} ,' ' debugger_location_second_test.dart:${LINE_B + 3}:,' ' debugger_location_second_test.dart:${LINE_B + 4} ,' ' debugger_location_second_test.dart:${LINE_B + 4}:,' ' debugger_location_second_test.dart:${LINE_B + 5} ,' ' debugger_location_second_test.dart:${LINE_B + 5}:,' ' debugger_location_second_test.dart:${LINE_B + 8} ,' ' debugger_location_second_test.dart:${LINE_B + 8}:,' ' debugger_location_second_test.dart:${LINE_B + 9} ,' ' debugger_location_second_test.dart:${LINE_B + 9}:]')); }, // Complete script:line:col (Isolate isolate) async { var debugger = await initDebugger(isolate); var completions = await DebuggerLocation.complete( debugger, 'debugger_location_second_test.dart:$LINE_C:2'); expect( completions.toString(), equals('[debugger_location_second_test.dart:$LINE_C:2 ,' ' debugger_location_second_test.dart:$LINE_C:20 ,' ' debugger_location_second_test.dart:$LINE_C:21 ,' ' debugger_location_second_test.dart:$LINE_C:22 ,' ' debugger_location_second_test.dart:$LINE_C:23 ,' ' debugger_location_second_test.dart:$LINE_C:24 ]')); }, // Complete without the script name. (Isolate isolate) async { var debugger = await initDebugger(isolate); var completions = await DebuggerLocation.complete(debugger, '$LINE_C:2'); expect( completions.toString(), equals('[debugger_location_second_test.dart:$LINE_C:2 ,' ' debugger_location_second_test.dart:$LINE_C:20 ,' ' debugger_location_second_test.dart:$LINE_C:21 ,' ' debugger_location_second_test.dart:$LINE_C:22 ,' ' debugger_location_second_test.dart:$LINE_C:23 ,' ' debugger_location_second_test.dart:$LINE_C:24 ]')); }, ]; main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction);