| // 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. |
| |
| @Tags(['daily']) |
| @TestOn('vm') |
| @Timeout(Duration(minutes: 5)) |
| library; |
| |
| import 'package:dwds/dwds.dart'; |
| import 'package:test/test.dart'; |
| import 'package:test_common/logging.dart'; |
| import 'package:test_common/test_sdk_configuration.dart'; |
| import 'package:test_common/utilities.dart'; |
| import 'package:vm_service/vm_service.dart'; |
| |
| import 'fixtures/context.dart'; |
| import 'fixtures/project.dart'; |
| import 'fixtures/utilities.dart'; |
| |
| const originalString = 'variableToModifyToForceRecompile = 23'; |
| const newString = 'variableToModifyToForceRecompile = 45'; |
| |
| const constantSuccessString = 'ConstantEqualitySuccess'; |
| const constantFailureString = 'ConstantEqualityFailure'; |
| |
| void main() { |
| // set to true for debug logging. |
| final debug = false; |
| |
| final provider = TestSdkConfigurationProvider(verbose: debug); |
| tearDownAll(provider.dispose); |
| |
| final testHotRestart2 = TestProject.testHotRestart2; |
| final context = TestContext(testHotRestart2, provider); |
| |
| Future<void> makeEditAndWaitForRebuild() async { |
| context.makeEditToDartLibFile( |
| libFileName: 'library2.dart', |
| toReplace: originalString, |
| replaceWith: newString, |
| ); |
| await context.waitForSuccessfulBuild(propagateToBrowser: true); |
| } |
| |
| void undoEdit() { |
| context.makeEditToDartLibFile( |
| libFileName: 'library2.dart', |
| toReplace: newString, |
| replaceWith: originalString, |
| ); |
| } |
| |
| group( |
| 'Injected client', |
| () { |
| VmService? fakeClient; |
| |
| setUp(() async { |
| setCurrentLogWriter(debug: debug); |
| await context.setUp( |
| testSettings: TestSettings( |
| enableExpressionEvaluation: true, |
| ), |
| ); |
| |
| fakeClient = await context.connectFakeClient(); |
| }); |
| |
| tearDown(() async { |
| await context.tearDown(); |
| undoEdit(); |
| }); |
| |
| test( |
| 'properly compares constants after hot restart via the service extension', |
| () async { |
| final client = context.debugConnection.vmService; |
| await client.streamListen('Isolate'); |
| |
| var source = await context.webDriver.pageSource; |
| expect( |
| source, |
| contains( |
| 'ConstObject(reloadVariable: 23, ConstantEqualitySuccess)', |
| ), |
| ); |
| |
| await makeEditAndWaitForRebuild(); |
| |
| final eventsDone = expectLater( |
| client.onIsolateEvent, |
| emitsThrough( |
| emitsInOrder([ |
| _hasKind(EventKind.kIsolateExit), |
| _hasKind(EventKind.kIsolateStart), |
| _hasKind(EventKind.kIsolateRunnable), |
| ]), |
| ), |
| ); |
| |
| final hotRestart = context.getRegisteredServiceExtension('hotRestart'); |
| expect( |
| await fakeClient!.callServiceExtension(hotRestart!), |
| const TypeMatcher<Success>(), |
| ); |
| |
| await eventsDone; |
| |
| source = await context.webDriver.pageSource; |
| if (dartSdkIsAtLeast('3.4.0-61.0.dev')) { |
| expect( |
| source, |
| contains( |
| 'ConstObject(reloadVariable: 45, ConstantEqualitySuccess)', |
| ), |
| ); |
| } |
| }); |
| }, |
| timeout: Timeout.factor(2), |
| ); |
| |
| group( |
| 'Injected client with hot restart', |
| () { |
| group('and with debugging', () { |
| setUp(() async { |
| setCurrentLogWriter(debug: debug); |
| await context.setUp( |
| testSettings: TestSettings( |
| reloadConfiguration: ReloadConfiguration.hotRestart, |
| ), |
| ); |
| }); |
| |
| tearDown(() async { |
| await context.tearDown(); |
| undoEdit(); |
| }); |
| |
| test('properly compares constants after hot restart', () async { |
| var source = await context.webDriver.pageSource; |
| expect( |
| source, |
| contains( |
| 'ConstObject(reloadVariable: 23, ConstantEqualitySuccess)', |
| ), |
| ); |
| |
| await makeEditAndWaitForRebuild(); |
| |
| source = await context.webDriver.pageSource; |
| if (dartSdkIsAtLeast('3.4.0-61.0.dev')) { |
| expect( |
| source, |
| contains( |
| 'ConstObject(reloadVariable: 45, ConstantEqualitySuccess)', |
| ), |
| ); |
| } |
| }); |
| }); |
| |
| group('and without debugging', () { |
| setUp(() async { |
| setCurrentLogWriter(debug: debug); |
| await context.setUp( |
| testSettings: TestSettings( |
| reloadConfiguration: ReloadConfiguration.hotRestart, |
| ), |
| debugSettings: |
| TestDebugSettings.noDevTools().copyWith(enableDebugging: false), |
| ); |
| }); |
| |
| tearDown(() async { |
| await context.tearDown(); |
| undoEdit(); |
| }); |
| |
| test('properly compares constants after hot restart', () async { |
| var source = await context.webDriver.pageSource; |
| expect( |
| source, |
| contains( |
| 'ConstObject(reloadVariable: 23, ConstantEqualitySuccess)', |
| ), |
| ); |
| |
| await makeEditAndWaitForRebuild(); |
| |
| source = await context.webDriver.pageSource; |
| if (dartSdkIsAtLeast('3.4.0-61.0.dev')) { |
| expect( |
| source, |
| contains( |
| 'ConstObject(reloadVariable: 45, ConstantEqualitySuccess)', |
| ), |
| ); |
| } |
| }); |
| }); |
| }, |
| timeout: Timeout.factor(2), |
| ); |
| } |
| |
| TypeMatcher<Event> _hasKind(String kind) => |
| isA<Event>().having((e) => e.kind, 'kind', kind); |