diff --git a/dwds/lib/src/debugging/debugger.dart b/dwds/lib/src/debugging/debugger.dart index 05540f7aa..4de9d1568 100644 --- a/dwds/lib/src/debugging/debugger.dart +++ b/dwds/lib/src/debugging/debugger.dart @@ -197,7 +197,7 @@ class Debugger extends Domain { }); handleErrorIfPresent(await _remoteDebugger.enablePage()); - handleErrorIfPresent(await _remoteDebugger.enable() as WipResponse); + await _remoteDebugger.enable(); // Enable collecting information about async frames when paused. handleErrorIfPresent(await _remoteDebugger diff --git a/dwds/test/debugger_test.dart b/dwds/test/debugger_test.dart index b251eb51a..06992d43f 100644 --- a/dwds/test/debugger_test.dart +++ b/dwds/test/debugger_test.dart @@ -2,8 +2,6 @@ // 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. -// @dart = 2.9 - @TestOn('vm') import 'dart:async'; @@ -13,8 +11,9 @@ import 'package:dwds/src/debugging/inspector.dart'; import 'package:dwds/src/debugging/location.dart'; import 'package:dwds/src/debugging/skip_list.dart'; import 'package:dwds/src/loaders/strategy.dart'; +import 'package:logging/logging.dart'; import 'package:test/test.dart'; -import 'package:vm_service/vm_service.dart'; +import 'package:vm_service/vm_service.dart' hide LogRecord; import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart' show CallFrame, DebuggerPausedEvent, StackTrace, WipCallFrame, WipScript; @@ -23,12 +22,12 @@ import 'fixtures/debugger_data.dart'; import 'fixtures/fakes.dart'; final context = TestContext(); -AppInspector inspector; -Debugger debugger; -FakeWebkitDebugger webkitDebugger; -StreamController pausedController; -Locations locations; -SkipLists skipLists; +late AppInspector inspector; +late Debugger debugger; +late FakeWebkitDebugger webkitDebugger; +late StreamController pausedController; +late Locations locations; +late SkipLists skipLists; class TestStrategy extends FakeStrategy { @override @@ -92,7 +91,7 @@ void main() async { skipLists = SkipLists(); debugger = await Debugger.create( webkitDebugger, - null, + (_, __) {}, locations, skipLists, root, @@ -109,8 +108,8 @@ void main() async { expect(frames, isNotNull); expect(frames, isNotEmpty); - final firstFrame = frames[0]; - final frame1Variables = firstFrame.vars.map((each) => each.name).toList(); + final firstFrameVars = frames[0].vars!; + final frame1Variables = firstFrameVars.map((each) => each.name).toList(); expect(frame1Variables, ['a', 'b']); }); @@ -164,6 +163,13 @@ void main() async { expect(frames[4].kind, FrameKind.kAsyncCausal); }); + setUp(() { + // We need to provide an Isolate so that the code doesn't bail out on a null + // check before it has a chance to throw. + inspector = FakeInspector(fakeIsolate: simpleIsolate); + debugger.updateInspector(inspector); + }); + group('errors', () { setUp(() { // We need to provide an Isolate so that the code doesn't bail out on a null @@ -175,17 +181,18 @@ void main() async { test('errors in the zone are caught and logged', () async { // Add a DebuggerPausedEvent with a null parameter to provoke an error. pausedController.sink.add(DebuggerPausedEvent({ + 'method': '', 'params': { 'reason': 'other', 'callFrames': [ - null, + {'callFrameId': '', 'functionName': ''}, ], } })); expect( Debugger.logger.onRecord, - emitsThrough(predicate( - (log) => log.message == 'Error calculating Dart frames'))); + emitsThrough(predicate((LogRecord log) => + log.message == 'Error calculating Dart frames'))); }); }); } diff --git a/dwds/test/fixtures/fakes.dart b/dwds/test/fixtures/fakes.dart index be02a6f65..525fb129b 100644 --- a/dwds/test/fixtures/fakes.dart +++ b/dwds/test/fixtures/fakes.dart @@ -182,10 +182,10 @@ class FakeWebkitDebugger implements WebkitDebugger { Stream get onTargetCrashed => Stream.empty(); @override - Future pause() async => WipResponse({}); + Future pause() async => fakeWipResponse; @override - Future resume() async => WipResponse({}); + Future resume() async => fakeWipResponse; @override Map get scripts => _scripts!; @@ -200,27 +200,27 @@ class FakeWebkitDebugger implements WebkitDebugger { if (command == 'Runtime.getProperties') { return results[resultsReturned++]; } - return WipResponse({}); + return fakeWipResponse; } @override Future setPauseOnExceptions(PauseState state) async => - WipResponse({}); + fakeWipResponse; @override Future removeBreakpoint(String breakpointId) async => - WipResponse({}); + fakeWipResponse; @override Future stepInto({Map? params}) async => - WipResponse({}); + fakeWipResponse; @override - Future stepOut() async => WipResponse({}); + Future stepOut() async => fakeWipResponse; @override Future stepOver({Map? params}) async => - WipResponse({}); + fakeWipResponse; @override Stream get onConsoleAPICalled => Stream.empty(); @@ -251,10 +251,10 @@ class FakeWebkitDebugger implements WebkitDebugger { []; @override - Future enablePage() async => WipResponse({}); + Future enablePage() async => fakeWipResponse; @override - Future pageReload() async => WipResponse({}); + Future pageReload() async => fakeWipResponse; } /// Fake execution context that is needed for id only @@ -365,3 +365,8 @@ class FakeAssetReader implements AssetReader { return contents; } } + +final fakeWipResponse = WipResponse({ + 'id': 1, + 'result': {'fake': ''} +}); diff --git a/dwds/test/instance_test.dart b/dwds/test/instance_test.dart index 9d44aa9fa..a5c64c74c 100644 --- a/dwds/test/instance_test.dart +++ b/dwds/test/instance_test.dart @@ -2,7 +2,7 @@ // 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. -// @dart = 2.9 +import 'dart:async'; import 'package:dwds/src/connections/debug_connection.dart'; import 'package:dwds/src/debugging/debugger.dart'; @@ -20,8 +20,8 @@ final context = TestContext( WipConnection get tabConnection => context.tabConnection; void main() { - AppInspector inspector; - Debugger debugger; + late AppInspector inspector; + late Debugger debugger; setUpAll(() async { await context.setUp(); @@ -54,9 +54,9 @@ void main() { final remoteObject = await libraryPublicFinal(); final nullVariable = await inspector.loadField(remoteObject, 'notFinal'); final ref = await inspector.instanceRefFor(nullVariable); - expect(ref.valueAsString, 'null'); + expect(ref!.valueAsString, 'null'); expect(ref.kind, InstanceKind.kNull); - final classRef = ref.classRef; + final classRef = ref.classRef!; expect(classRef.name, 'Null'); expect(classRef.id, 'classes|dart:core|Null'); }); @@ -65,9 +65,9 @@ void main() { final remoteObject = await libraryPublicFinal(); final count = await inspector.loadField(remoteObject, 'count'); final ref = await inspector.instanceRefFor(count); - expect(ref.valueAsString, '0'); + expect(ref!.valueAsString, '0'); expect(ref.kind, InstanceKind.kDouble); - final classRef = ref.classRef; + final classRef = ref.classRef!; expect(classRef.name, 'Double'); expect(classRef.id, 'classes|dart:core|Double'); }); @@ -76,8 +76,8 @@ void main() { final remoteObject = await libraryPublicFinal(); final count = await inspector.loadField(remoteObject, 'myselfField'); final ref = await inspector.instanceRefFor(count); - expect(ref.kind, InstanceKind.kPlainInstance); - final classRef = ref.classRef; + expect(ref!.kind, InstanceKind.kPlainInstance); + final classRef = ref.classRef!; expect(classRef.name, 'MyTestClass'); expect( classRef.id, @@ -87,11 +87,11 @@ void main() { test('for closure', () async { final remoteObject = await libraryPublicFinal(); - final properties = await debugger.getProperties(remoteObject.objectId); + final properties = await debugger.getProperties(remoteObject.objectId!); final closure = properties.firstWhere((property) => property.name == 'closure'); - final instanceRef = await inspector.instanceRefFor(closure.value); - final functionName = instanceRef.closureFunction.name; + final instanceRef = await inspector.instanceRefFor(closure.value!); + final functionName = instanceRef!.closureFunction!.name; // Older SDKs do not contain function names if (functionName != 'Closure') { expect(functionName, 'someFunction'); @@ -102,27 +102,27 @@ void main() { test('for a list', () async { final remoteObject = await libraryPublic(); final ref = await inspector.instanceRefFor(remoteObject); - expect(ref.length, greaterThan(0)); + expect(ref!.length, greaterThan(0)); expect(ref.kind, InstanceKind.kList); - expect(ref.classRef.name, 'List'); + expect(ref.classRef!.name, 'List'); }); test('for map', () async { final remoteObject = await inspector.jsEvaluate(libraryVariableExpression('map')); final ref = await inspector.instanceRefFor(remoteObject); - expect(ref.length, 2); + expect(ref!.length, 2); expect(ref.kind, InstanceKind.kMap); - expect(ref.classRef.name, 'LinkedMap'); + expect(ref.classRef!.name, 'LinkedMap'); }); test('for an IdentityMap', () async { final remoteObject = await inspector.jsEvaluate(libraryVariableExpression('identityMap')); final ref = await inspector.instanceRefFor(remoteObject); - expect(ref.length, 2); + expect(ref!.length, 2); expect(ref.kind, InstanceKind.kMap); - expect(ref.classRef.name, 'IdentityMap'); + expect(ref.classRef!.name, 'IdentityMap'); }); }); @@ -130,12 +130,12 @@ void main() { test('for class object', () async { final remoteObject = await libraryPublicFinal(); final instance = await inspector.instanceFor(remoteObject); - expect(instance.kind, InstanceKind.kPlainInstance); - final classRef = instance.classRef; + expect(instance!.kind, InstanceKind.kPlainInstance); + final classRef = instance.classRef!; expect(classRef, isNotNull); expect(classRef.name, 'MyTestClass'); final fieldNames = - instance.fields.map((boundField) => boundField.decl.name).toList(); + instance.fields!.map((boundField) => boundField.decl!.name).toList(); expect(fieldNames, [ '_privateField', 'abstractField', @@ -146,19 +146,19 @@ void main() { 'notFinal', 'tornOff', ]); - for (var field in instance.fields) { - expect(field.decl.declaredType, isNotNull); + for (var field in instance.fields!) { + expect(field.decl!.declaredType, isNotNull); } }); test('for closure', () async { final remoteObject = await libraryPublicFinal(); - final properties = await debugger.getProperties(remoteObject.objectId); + final properties = await debugger.getProperties(remoteObject.objectId!); final closure = properties.firstWhere((property) => property.name == 'closure'); - final instance = await inspector.instanceFor(closure.value); - expect(instance.kind, InstanceKind.kClosure); - expect(instance.classRef.name, 'Closure'); + final instance = await inspector.instanceFor(closure.value!); + expect(instance!.kind, InstanceKind.kClosure); + expect(instance.classRef!.name, 'Closure'); }); test('for a nested class', () async { @@ -166,8 +166,8 @@ void main() { final fieldRemoteObject = await inspector.loadField(libraryRemoteObject, 'myselfField'); final instance = await inspector.instanceFor(fieldRemoteObject); - expect(instance.kind, InstanceKind.kPlainInstance); - final classRef = instance.classRef; + expect(instance!.kind, InstanceKind.kPlainInstance); + final classRef = instance.classRef!; expect(classRef, isNotNull); expect(classRef.name, 'MyTestClass'); }); @@ -175,11 +175,11 @@ void main() { test('for a list', () async { final remote = await libraryPublic(); final instance = await inspector.instanceFor(remote); - expect(instance.kind, InstanceKind.kList); - final classRef = instance.classRef; + expect(instance!.kind, InstanceKind.kList); + final classRef = instance.classRef!; expect(classRef, isNotNull); expect(classRef.name, 'List'); - final first = instance.elements[0]; + final first = instance.elements![0]; expect(first.valueAsString, 'library'); }); @@ -187,13 +187,13 @@ void main() { final remote = await inspector.jsEvaluate(libraryVariableExpression('map')); final instance = await inspector.instanceFor(remote); - expect(instance.kind, InstanceKind.kMap); - final classRef = instance.classRef; + expect(instance!.kind, InstanceKind.kMap); + final classRef = instance.classRef!; expect(classRef.name, 'LinkedMap'); - final first = instance.associations[0].value as InstanceRef; + final first = instance.associations![0].value as InstanceRef; expect(first.kind, InstanceKind.kList); expect(first.length, 3); - final second = instance.associations[1].value as InstanceRef; + final second = instance.associations![1].value as InstanceRef; expect(second.kind, InstanceKind.kString); expect(second.valueAsString, 'something'); }); @@ -202,10 +202,10 @@ void main() { final remote = await inspector.jsEvaluate(libraryVariableExpression('identityMap')); final instance = await inspector.instanceFor(remote); - expect(instance.kind, InstanceKind.kMap); - final classRef = instance.classRef; + expect(instance!.kind, InstanceKind.kMap); + final classRef = instance.classRef!; expect(classRef.name, 'IdentityMap'); - final first = instance.associations[0].value; + final first = instance.associations![0].value; expect(first.valueAsString, '1'); }); @@ -214,12 +214,12 @@ void main() { final remote = await inspector.jsEvaluate(libraryVariableExpression('notAList')); final instance = await inspector.instanceFor(remote); - expect(instance.kind, InstanceKind.kPlainInstance); - final classRef = instance.classRef; + expect(instance!.kind, InstanceKind.kPlainInstance); + final classRef = instance.classRef!; expect(classRef.name, 'NotReallyAList'); expect(instance.elements, isNull); - final field = instance.fields.first; - expect(field.decl.name, '_internal'); + final field = instance.fields!.first; + expect(field.decl!.name, '_internal'); }); }); }