[package:vm_service] Add dot_shorthands_test
Fixes: https://github.com/dart-lang/sdk/issues/59875
Change-Id: I2653a6473a00cbf89b26872c7e50a34e6d486a22
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/431120
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Derek Xu <derekx@google.com>
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 2486873..61615ce 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -134,6 +134,7 @@
vm_service/test/developer_extension_test: SkipByDesign # Debugger is disabled in AOT mode.
vm_service/test/developer_service_get_isolate_id_test: SkipByDesign # Debugger is disabled in AOT mode.
vm_service/test/developer_service_get_object_id_test: SkipByDesign # Debugger is disabled in AOT mode.
+vm_service/test/dot_shorthands_test: SkipByDesign # Debugger is disabled in AOT mode.
vm_service/test/enhanced_enum_test: SkipByDesign # Debugger is disabled in AOT mode.
vm_service/test/eval_*test: SkipByDesign # Debugger is disabled in AOT mode.
vm_service/test/evaluate_*test: SkipByDesign # Debugger is disabled in AOT mode.
diff --git a/pkg/vm_service/test/common/service_test_common.dart b/pkg/vm_service/test/common/service_test_common.dart
index fc208ac..465f0e7 100644
--- a/pkg/vm_service/test/common/service_test_common.dart
+++ b/pkg/vm_service/test/common/service_test_common.dart
@@ -212,6 +212,29 @@
};
}
+extension BreakpointLocation on Breakpoint {
+ Future<(String uri, (int line, int column))> getLocation(
+ VmService service,
+ IsolateRef isolateRef,
+ ) async {
+ if (location?.tokenPos == null) {
+ return ('<unknown>', (-1, -1));
+ }
+
+ final script = (await service.getObject(
+ isolateRef.id!,
+ location!.script!.id!,
+ )) as Script;
+ return (
+ script.uri!,
+ (
+ script.getLineNumberFromTokenPos(location!.tokenPos!) ?? -1,
+ script.getColumnNumberFromTokenPos(location!.tokenPos!) ?? -1
+ )
+ );
+ }
+}
+
extension FrameLocation on Frame {
Future<(String uri, (int line, int column))> getLocation(
VmService service,
diff --git a/pkg/vm_service/test/dot_shorthands_test.dart b/pkg/vm_service/test/dot_shorthands_test.dart
new file mode 100644
index 0000000..9e064c8
--- /dev/null
+++ b/pkg/vm_service/test/dot_shorthands_test.dart
@@ -0,0 +1,138 @@
+// Copyright (c) 2024, 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.
+
+// SharedOptions=--enable-experiment=dot-shorthands
+// @dart = 3.9
+
+import 'dart:developer';
+
+import 'package:test/test.dart';
+import 'package:vm_service/vm_service.dart';
+
+import 'common/service_test_common.dart';
+import 'common/test_helper.dart';
+
+const String shortFile = 'dot_shorthands_test.dart';
+
+// AUTOGENERATED START
+//
+// Update these constants by running:
+//
+// dart pkg/vm_service/test/update_line_numbers.dart pkg/vm_service/test/dot_shorthands_test.dart
+//
+const LINE_A = 34;
+const LINE_B = 37;
+const LINE_C = 38;
+const LINE_D = 45;
+const LINE_E = 47;
+const LINE_F = 49;
+// AUTOGENERATED END
+
+class C {
+ int value;
+ C(this.value); // LINE_A
+
+ static C two = C(2);
+ static C get three => C(3); // LINE_B
+ static C four() => C(4); // LINE_C
+}
+
+void testeeMain() {
+ C c = C(1);
+ debugger();
+ // ignore: experiment_not_enabled
+ c = .two; // LINE_D
+ // ignore: experiment_not_enabled
+ c = .three; // LINE_E
+ // ignore: experiment_not_enabled
+ c = .four(); // LINE_F
+ print(c.value);
+}
+
+List<String> stops = [];
+
+const List<String> expected = [
+ '$shortFile:$LINE_D:7', // on '.'
+ '$shortFile:$LINE_E:7', // on '.'
+ '$shortFile:$LINE_B:22', // on '=' of '=>'
+ '$shortFile:$LINE_B:25', // on 'C'
+ '$shortFile:$LINE_A:10', // on 'v' of 'value'
+ '$shortFile:$LINE_A:16', // on ';'
+ '$shortFile:$LINE_B:25', // on 'C'
+ '$shortFile:$LINE_F:7', // on '.'
+ '$shortFile:$LINE_C:16', // on '('
+ '$shortFile:$LINE_C:22', // on 'C'
+ '$shortFile:$LINE_A:10', // on 'v' of 'value'
+ '$shortFile:$LINE_A:16', // on ';'
+ '$shortFile:$LINE_C:22', // on 'C'
+];
+
+final tests = <IsolateTest>[
+ hasStoppedAtBreakpoint,
+
+ // Test interaction of expression evaluation with dot shorthands.
+ (VmService service, IsolateRef isolateRef) async {
+ final isolateId = isolateRef.id!;
+
+ InstanceRef response =
+ await service.evaluateInFrame(isolateId, 0, '(c = .two).value')
+ as InstanceRef;
+ expect(response.valueAsString, '2');
+
+ response =
+ await service.evaluateInFrame(isolateId, 0, '(c = .three).value')
+ as InstanceRef;
+ expect(response.valueAsString, '3');
+
+ response =
+ await service.evaluateInFrame(isolateId, 0, '(c = .four()).value')
+ as InstanceRef;
+ expect(response.valueAsString, '4');
+ },
+
+ // Test interaction of breakpoints with dot shorthands.
+ (VmService service, IsolateRef isolateRef) async {
+ final isolateId = isolateRef.id!;
+ final isolate = await service.getIsolate(isolateId);
+ final lib =
+ (await service.getObject(isolateId, isolate.rootLib!.id!)) as Library;
+ final scriptId = lib.scripts!.first.id!;
+
+ Breakpoint breakpoint = await service.addBreakpoint(
+ isolateId,
+ scriptId,
+ LINE_D,
+ );
+ var (_, (line, column)) = await breakpoint.getLocation(service, isolateRef);
+ expect(breakpoint.enabled, true);
+ expect(line, LINE_D);
+ expect(column, 7); // on '.'
+
+ breakpoint = await service.addBreakpoint(isolateId, scriptId, LINE_E);
+ (_, (line, column)) = await breakpoint.getLocation(service, isolateRef);
+ expect(breakpoint.enabled, true);
+ expect(line, LINE_E);
+ expect(column, 7); // on '.'
+ await service.removeBreakpoint(isolateId, breakpoint.id!);
+
+ breakpoint = await service.addBreakpoint(isolateId, scriptId, LINE_F);
+ (_, (line, column)) = await breakpoint.getLocation(service, isolateRef);
+ expect(breakpoint.enabled, true);
+ expect(line, LINE_F);
+ expect(column, 7); // on '.'
+ await service.removeBreakpoint(isolateId, breakpoint.id!);
+ },
+
+ // Test interaction of single-stepping with dot shorthands.
+ runStepIntoThroughProgramRecordingStops(stops),
+ checkRecordedStops(stops, expected),
+];
+
+void main([args = const <String>[]]) => runIsolateTests(
+ args,
+ tests,
+ 'dot_shorthands_test.dart',
+ pauseOnExit: true,
+ testeeConcurrent: testeeMain,
+);