blob: e0cdd2113e7f4512da7cd7a4c348fb9bfe25815b [file] [log] [blame]
// Copyright (c) 2015, 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:unittest/unittest.dart';
import 'test_helper.dart';
import 'dart:async';
void testFunction() {
int i = 0;
while (true) {
if (++i % 100000000 == 0) { // line 14
print(i);
}
}
}
class TestDebugger extends Debugger {
TestDebugger(this.isolate, this.stack);
Isolate isolate;
ServiceMap stack;
int currentFrame = 0;
}
void source_location_dummy_function() {
}
class SourceLocationTestFoo {
SourceLocationTestFoo(this.field);
SourceLocationTestFoo.named();
void method() {}
void madness() {}
int field;
}
class SourceLocationTestBar {
}
Future<Debugger> initDebugger(Isolate isolate) {
return isolate.getStack().then((stack) {
return new TestDebugger(isolate, stack);
});
}
var tests = [
// Bring the isolate to a breakpoint at line 14.
(Isolate isolate) {
return isolate.rootLib.load().then((_) {
// Listen for breakpoint event.
Completer completer = new Completer();
isolate.vm.events.stream.listen((ServiceEvent event) {
if (event.eventType == ServiceEvent.kPauseBreakpoint) {
completer.complete();
}
});
// Add the breakpoint.
var script = isolate.rootLib.scripts[0];
return isolate.addBreakpoint(script, 14).then((ServiceObject bpt) {
return completer.future; // Wait for breakpoint events.
});
});
},
// Parse '' => current position
(Isolate isolate) {
return initDebugger(isolate).then((debugger) {
return SourceLocation.parse(debugger, '').then((SourceLocation loc) {
expect(loc.valid, isTrue);
expect(loc.toString(), equals('source_location_test.dart:14'));
});
});
},
// Parse line
(Isolate isolate) {
return initDebugger(isolate).then((debugger) {
return SourceLocation.parse(debugger, '15').then((SourceLocation loc) {
expect(loc.valid, isTrue);
expect(loc.toString(), equals('source_location_test.dart:15'));
});
});
},
// Parse line + col
(Isolate isolate) {
return initDebugger(isolate).then((debugger) {
return SourceLocation.parse(debugger, '15:11').then((SourceLocation loc) {
expect(loc.valid, isTrue);
expect(loc.toString(), equals('source_location_test.dart:15:11'));
});
});
},
// Parse script + line
(Isolate isolate) {
return initDebugger(isolate).then((debugger) {
return SourceLocation.parse(debugger, 'unittest.dart:15')
.then((SourceLocation loc) {
expect(loc.valid, isTrue);
expect(loc.toString(), equals('unittest.dart:15'));
});
});
},
// Parse script + line + col
(Isolate isolate) {
return initDebugger(isolate).then((debugger) {
return SourceLocation.parse(debugger, 'unittest.dart:15:10')
.then((SourceLocation loc) {
expect(loc.valid, isTrue);
expect(loc.toString(), equals('unittest.dart:15:10'));
});
});
},
// Parse bad script
(Isolate isolate) {
return initDebugger(isolate).then((debugger) {
return SourceLocation.parse(debugger, 'bad.dart:15')
.then((SourceLocation loc) {
expect(loc.valid, isFalse);
expect(loc.toString(), equals(
'invalid source location (Script \'bad.dart\' not found)'));
});
});
},
// Parse function
(Isolate isolate) {
return initDebugger(isolate).then((debugger) {
return SourceLocation.parse(debugger, 'testFunction')
.then((SourceLocation loc) {
expect(loc.valid, isTrue);
expect(loc.toString(), equals('testFunction'));
});
});
},
// Parse bad function
(Isolate isolate) {
return initDebugger(isolate).then((debugger) {
return SourceLocation.parse(debugger, 'doesNotReallyExit')
.then((SourceLocation loc) {
expect(loc.valid, isFalse);
expect(loc.toString(), equals(
'invalid source location (Function \'doesNotReallyExit\' not found)'));
});
});
},
// Parse constructor
(Isolate isolate) {
return initDebugger(isolate).then((debugger) {
return SourceLocation.parse(debugger, 'SourceLocationTestFoo')
.then((SourceLocation loc) {
expect(loc.valid, isTrue);
// TODO(turnidge): Printing a constructor currently adds
// another class qualifier at the front. Do we want to change
// this to be more consistent?
expect(loc.toString(), equals(
'SourceLocationTestFoo.SourceLocationTestFoo'));
});
});
},
// Parse named constructor
(Isolate isolate) {
return initDebugger(isolate).then((debugger) {
return SourceLocation.parse(debugger, 'SourceLocationTestFoo.named')
.then((SourceLocation loc) {
expect(loc.valid, isTrue);
// TODO(turnidge): Printing a constructor currently adds
// another class qualifier at the front. Do we want to change
// this to be more consistent?
expect(loc.toString(), equals(
'SourceLocationTestFoo.SourceLocationTestFoo.named'));
});
});
},
// Parse method
(Isolate isolate) {
return initDebugger(isolate).then((debugger) {
return SourceLocation.parse(debugger, 'SourceLocationTestFoo.method')
.then((SourceLocation loc) {
expect(loc.valid, isTrue);
expect(loc.toString(), equals('SourceLocationTestFoo.method'));
});
});
},
// Parse method
(Isolate isolate) {
return initDebugger(isolate).then((debugger) {
return SourceLocation.parse(debugger, 'SourceLocationTestFoo.field=')
.then((SourceLocation loc) {
expect(loc.valid, isTrue);
expect(loc.toString(), equals('SourceLocationTestFoo.field='));
});
});
},
// Parse bad method
(Isolate isolate) {
return initDebugger(isolate).then((debugger) {
return SourceLocation.parse(debugger, 'SourceLocationTestFoo.missing')
.then((SourceLocation loc) {
expect(loc.valid, isFalse);
expect(loc.toString(), equals(
'invalid source location '
'(Function \'SourceLocationTestFoo.missing\' not found)'));
});
});
},
// Complete function + script
(Isolate isolate) {
return initDebugger(isolate).then((debugger) {
return SourceLocation.complete(debugger, 'source_loc')
.then((List<String> completions) {
expect(completions.toString(), equals(
'[source_location_dummy_function, '
'source_location.dart:, source_location_test.dart:]'));
});
});
},
// Complete class
(Isolate isolate) {
return initDebugger(isolate).then((debugger) {
return SourceLocation.complete(debugger, 'SourceLocationTe')
.then((List<String> completions) {
expect(completions.toString(), equals(
'[SourceLocationTestBar, SourceLocationTestFoo]'));
});
});
},
// No completions: unqualified name
(Isolate isolate) {
return initDebugger(isolate).then((debugger) {
return SourceLocation.complete(debugger, 'source_locXYZZY')
.then((List<String> completions) {
expect(completions.toString(), equals('[]'));
});
});
},
// Complete method
(Isolate isolate) {
return initDebugger(isolate).then((debugger) {
return SourceLocation.complete(debugger, 'SourceLocationTestFoo.m')
.then((List<String> completions) {
expect(completions.toString(), equals(
'[SourceLocationTestFoo.madness, SourceLocationTestFoo.method]'));
});
});
},
// No completions: qualified name
(Isolate isolate) {
return initDebugger(isolate).then((debugger) {
return SourceLocation.complete(debugger, 'SourceLocationTestFoo.q')
.then((List<String> completions) {
expect(completions.toString(), equals('[]'));
});
});
},
];
main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction);