blob: b5e357c7ba99d5bacf322504a9ebe0da0ce3cdae [file] [log] [blame]
// Copyright (c) 2021, 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:test/test.dart';
import 'test_client.dart';
import 'test_support.dart';
main() {
late DapTestSession dap;
setUp(() async {
dap = await DapTestSession.setUp();
});
tearDown(() => dap.tearDown());
group('debug mode variables', () {
test('provides variable list for frames', () async {
final client = dap.client;
final testFile = await dap.createTestFile(r'''
void main(List<String> args) {
final myVariable = 1;
foo();
}
void foo() {
final b = 2;
print('Hello!'); // BREAKPOINT
}
''');
final breakpointLine = lineWith(testFile, '// BREAKPOINT');
final stop = await client.hitBreakpoint(testFile, breakpointLine);
final stack = await client.getValidStack(
stop.threadId!,
startFrame: 0,
numFrames: 2,
);
// Check top two frames (in `foo` and in `main`).
await client.expectScopeVariables(
stack.stackFrames[0].id, // Top frame: foo
'Variables',
'''
b: 2
''',
);
await client.expectScopeVariables(
stack.stackFrames[1].id, // Second frame: main
'Variables',
'''
args: List (0 items)
myVariable: 1
''',
);
});
test('provides simple exception types for frames', () async {
final client = dap.client;
final testFile = await dap.createTestFile(r'''
void main(List<String> args) {
throw 'my error';
}
''');
final stop = await client.hitException(testFile);
final stack = await client.getValidStack(
stop.threadId!,
startFrame: 0,
numFrames: 1,
);
final topFrameId = stack.stackFrames.first.id;
// Check for an additional Scope named "Exceptions" that includes the
// exception.
await client.expectScopeVariables(
topFrameId,
'Exceptions',
'''
String: "my error"
''',
);
});
test('provides complex exception types frames', () async {
final client = dap.client;
final testFile = await dap.createTestFile(r'''
void main(List<String> args) {
throw ArgumentError.notNull('args');
}
''');
final stop = await client.hitException(testFile);
final stack = await client.getValidStack(
stop.threadId!,
startFrame: 0,
numFrames: 1,
);
final topFrameId = stack.stackFrames.first.id;
// Check for an additional Scope named "Exceptions" that includes the
// exception.
await client.expectScopeVariables(
topFrameId,
'Exceptions',
// TODO(dantup): evaluateNames
'''
invalidValue: null
message: "Must not be null"
name: "args"
''',
);
});
test('includes simple variable fields', () async {
final client = dap.client;
final testFile = await dap.createTestFile(r'''
void main(List<String> args) {
final myVariable = DateTime(2000, 1, 1);
print('Hello!'); // BREAKPOINT
}
''');
final breakpointLine = lineWith(testFile, '// BREAKPOINT');
final stop = await client.hitBreakpoint(testFile, breakpointLine);
await client.expectLocalVariable(
stop.threadId!,
expectedName: 'myVariable',
expectedDisplayString: 'DateTime',
expectedVariables: '''
isUtc: false
''',
);
});
test('includes variable getters when evaluateGettersInDebugViews=true',
() async {
final client = dap.client;
final testFile = await dap.createTestFile(r'''
void main(List<String> args) {
final myVariable = DateTime(2000, 1, 1);
print('Hello!'); // BREAKPOINT
}
''');
final breakpointLine = lineWith(testFile, '// BREAKPOINT');
final stop = await client.hitBreakpoint(
testFile,
breakpointLine,
launch: () => client.launch(
testFile.path,
evaluateGettersInDebugViews: true,
),
);
await client.expectLocalVariable(
stop.threadId!,
expectedName: 'myVariable',
expectedDisplayString: 'DateTime',
expectedVariables: '''
day: 1
hour: 0
isUtc: false
microsecond: 0
millisecond: 0
minute: 0
month: 1
runtimeType: Type (DateTime)
second: 0
timeZoneOffset: Duration
weekday: 6
year: 2000
''',
ignore: {
// Don't check fields that may very based on timezone as it'll make
// these tests fragile, and this isn't really what's being tested.
'timeZoneName',
'microsecondsSinceEpoch',
'millisecondsSinceEpoch',
},
);
});
test('renders a simple list', () async {
final client = dap.client;
final testFile = await dap.createTestFile(r'''
void main(List<String> args) {
final myVariable = ["first", "second", "third"];
print('Hello!'); // BREAKPOINT
}
''');
final breakpointLine = lineWith(testFile, '// BREAKPOINT');
final stop = await client.hitBreakpoint(testFile, breakpointLine);
await client.expectLocalVariable(
stop.threadId!,
expectedName: 'myVariable',
expectedDisplayString: 'List (3 items)',
// TODO(dantup): evaluateNames
expectedVariables: '''
0: "first"
1: "second"
2: "third"
''',
);
});
test('renders a simple list subset', () async {
final client = dap.client;
final testFile = await dap.createTestFile(r'''
void main(List<String> args) {
final myVariable = ["first", "second", "third"];
print('Hello!'); // BREAKPOINT
}
''');
final breakpointLine = lineWith(testFile, '// BREAKPOINT');
final stop = await client.hitBreakpoint(testFile, breakpointLine);
await client.expectLocalVariable(
stop.threadId!,
expectedName: 'myVariable',
expectedDisplayString: 'List (3 items)',
// TODO(dantup): evaluateNames
expectedVariables: '''
1: "second"
''',
start: 1,
count: 1,
);
});
test('renders a simple map', () {
// TODO(dantup): Implement this (inc evaluateNames)
}, skip: true);
test('renders a simple map subset', () {
// TODO(dantup): Implement this (inc evaluateNames)
}, skip: true);
// These tests can be slow due to starting up the external server process.
}, timeout: Timeout.none);
}