mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 18:49:37 +00:00
[reload_test] Adding support for VM hot reload tests.
VM hot reload are run via: 1) We first emit a dill for every generation ahead of time (full dill on gen 0, incremental deltas subsequently). 2) We start a VM process at generation 0. 3) The VM process runs until it hits a `hotReload` command. It then uses the VM service protocol to connect to itself and reload the next generation. 4) The VM exits when the next generation isn't found. * Adds config files to reload tests that allow runtime filtering. * Implements VM-side hot reloading * Adds several VM-specific hot reload tests Change-Id: I1c6ad5c4eed426a0189c1b4af31297c9c1dba717 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/359200 Reviewed-by: Nicholas Shahan <nshahan@google.com> Commit-Queue: Mark Zhou <markzipan@google.com> Reviewed-by: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
parent
6c2819d8ba
commit
df75a619c8
|
@ -17,14 +17,10 @@ import 'package:reload_test/frontend_server_controller.dart';
|
|||
import 'package:reload_test/hot_reload_memory_filesystem.dart';
|
||||
import 'package:reload_test/test_helpers.dart';
|
||||
|
||||
enum RuntimePlatforms {
|
||||
chrome('chrome'),
|
||||
d8('d8'),
|
||||
vm('vm');
|
||||
// Set an arbitrary cap on generations.
|
||||
final globalMaxGenerations = 100;
|
||||
|
||||
const RuntimePlatforms(this.text);
|
||||
final String text;
|
||||
}
|
||||
final testTimeoutSeconds = 10;
|
||||
|
||||
final argParser = ArgParser()
|
||||
..addOption('runtime',
|
||||
|
@ -65,6 +61,7 @@ Future<void> main(List<String> args) async {
|
|||
final buildRootUri = fe.computePlatformBinariesLocation(forceBuildDir: true);
|
||||
// We can use the outline instead of the full SDK dill here.
|
||||
final ddcPlatformDillUri = buildRootUri.resolve('ddc_outline.dill');
|
||||
final vmPlatformDillUri = buildRootUri.resolve('vm_platform_strong.dill');
|
||||
|
||||
final sdkRoot = Platform.script.resolve('../../../');
|
||||
final packageConfigUri = sdkRoot.resolve('.dart_tool/package_config.json');
|
||||
|
@ -88,6 +85,7 @@ Future<void> main(List<String> args) async {
|
|||
|
||||
// Contains files emitted from Frontend Server compiles and recompiles.
|
||||
final frontendServerEmittedFilesDirUri = generatedCodeUri.resolve('.fes/');
|
||||
Directory.fromUri(frontendServerEmittedFilesDirUri).createSync();
|
||||
final outputDillUri = frontendServerEmittedFilesDirUri.resolve('output.dill');
|
||||
final outputIncrementalDillUri =
|
||||
frontendServerEmittedFilesDirUri.resolve('output_incremental.dill');
|
||||
|
@ -100,24 +98,44 @@ Future<void> main(List<String> args) async {
|
|||
filesystemRootUri, snapshotEntrypointUri, fe_shared.isWindows);
|
||||
final snapshotEntrypointWithScheme =
|
||||
'$filesystemScheme:///$snapshotEntrypointLibraryName';
|
||||
final ddcPlatformDillFromSdkRoot =
|
||||
fe_shared.relativizeUri(sdkRoot, ddcPlatformDillUri, fe_shared.isWindows);
|
||||
final ddcArgs = [
|
||||
'--dartdevc-module-format=ddc',
|
||||
|
||||
_print('Initializing the Frontend Server.');
|
||||
HotReloadFrontendServerController controller;
|
||||
final commonArgs = [
|
||||
'--incremental',
|
||||
'--filesystem-root=${snapshotUri.toFilePath()}',
|
||||
'--filesystem-scheme=$filesystemScheme',
|
||||
'--output-dill=${outputDillUri.toFilePath()}',
|
||||
'--output-incremental-dill=${outputIncrementalDillUri.toFilePath()}',
|
||||
'--packages=${packageConfigUri.toFilePath()}',
|
||||
'--platform=$ddcPlatformDillFromSdkRoot',
|
||||
'--sdk-root=${sdkRoot.toFilePath()}',
|
||||
'--target=dartdevc',
|
||||
'--verbosity=${verbose ? 'all' : 'info'}',
|
||||
];
|
||||
|
||||
_print('Initializing the Frontend Server.');
|
||||
var controller = HotReloadFrontendServerController(ddcArgs);
|
||||
switch (runtimePlatform) {
|
||||
case RuntimePlatforms.d8:
|
||||
final ddcPlatformDillFromSdkRoot = fe_shared.relativizeUri(
|
||||
sdkRoot, ddcPlatformDillUri, fe_shared.isWindows);
|
||||
final fesArgs = [
|
||||
...commonArgs,
|
||||
'--dartdevc-module-format=ddc',
|
||||
'--platform=$ddcPlatformDillFromSdkRoot',
|
||||
'--target=dartdevc',
|
||||
];
|
||||
controller = HotReloadFrontendServerController(fesArgs);
|
||||
break;
|
||||
case RuntimePlatforms.chrome:
|
||||
throw Exception('Unsupported platform: $runtimePlatform');
|
||||
case RuntimePlatforms.vm:
|
||||
final vmPlatformDillFromSdkRoot = fe_shared.relativizeUri(
|
||||
sdkRoot, vmPlatformDillUri, fe_shared.isWindows);
|
||||
final fesArgs = [
|
||||
...commonArgs,
|
||||
'--platform=$vmPlatformDillFromSdkRoot',
|
||||
'--target=vm',
|
||||
];
|
||||
controller = HotReloadFrontendServerController(fesArgs);
|
||||
break;
|
||||
}
|
||||
controller.start();
|
||||
|
||||
Future<void> shutdown() async {
|
||||
|
@ -130,6 +148,7 @@ Future<void> main(List<String> args) async {
|
|||
}
|
||||
|
||||
final testOutcomes = <TestResultOutcome>[];
|
||||
final validTestSourceName = RegExp(r'.*[a-zA-Z0-9]+.[0-9]+.dart');
|
||||
for (var testDir in Directory.fromUri(allTestsUri).listSync()) {
|
||||
if (testDir is! Directory) {
|
||||
if (testDir is File) {
|
||||
|
@ -157,16 +176,25 @@ Future<void> main(List<String> args) async {
|
|||
|
||||
var filesystem = HotReloadMemoryFilesystem(tempUri);
|
||||
|
||||
var maxGenerations = 0;
|
||||
// Count the number of generations for this test.
|
||||
//
|
||||
// Assumes all files are named like '$name.$integer.dart', where 0 is the
|
||||
// first generation.
|
||||
//
|
||||
// TODO(markzipan): Account for subdirectories.
|
||||
var maxGenerations = 0;
|
||||
var testConfig = ReloadTestConfiguration();
|
||||
for (var file in testDir.listSync()) {
|
||||
if (file is File) {
|
||||
if (file.path.endsWith('.dart')) {
|
||||
final fileName = file.uri.pathSegments.last;
|
||||
// Process config files.
|
||||
if (fileName == 'config.json') {
|
||||
testConfig = ReloadTestConfiguration.fromJsonFile(file.uri);
|
||||
} else if (fileName.endsWith('.dart')) {
|
||||
if (!validTestSourceName.hasMatch(fileName)) {
|
||||
throw Exception('Invalid test source file name: $fileName\n'
|
||||
'Valid names look like "file_name.10.dart".');
|
||||
}
|
||||
var strippedName =
|
||||
file.path.substring(0, file.path.length - '.dart'.length);
|
||||
var parts = strippedName.split('.');
|
||||
|
@ -175,6 +203,17 @@ Future<void> main(List<String> args) async {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (maxGenerations > globalMaxGenerations) {
|
||||
throw Exception('Too many generations specified in test '
|
||||
'(requested: $maxGenerations, max: $globalMaxGenerations).');
|
||||
}
|
||||
|
||||
// Skip this test directory if this platform is excluded.
|
||||
if (testConfig.excludedPlaforms.contains(runtimePlatform)) {
|
||||
_print('Skipping test on platform: ${runtimePlatform.text}',
|
||||
label: testName);
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO(markzipan): replace this with a test-configurable main entrypoint.
|
||||
final mainDartFilePath = testDir.uri.resolve('main.dart').toFilePath();
|
||||
|
@ -248,26 +287,40 @@ Future<void> main(List<String> args) async {
|
|||
'$outputDirectoryPath',
|
||||
label: testName);
|
||||
|
||||
// Update the memory filesystem with the newly-created JS files
|
||||
_print(
|
||||
'Loading generation $currentGeneration files '
|
||||
'into the memory filesystem.',
|
||||
label: testName);
|
||||
final codeFile = File('$outputDirectoryPath.sources');
|
||||
final manifestFile = File('$outputDirectoryPath.json');
|
||||
final sourcemapFile = File('$outputDirectoryPath.map');
|
||||
filesystem.update(
|
||||
codeFile,
|
||||
manifestFile,
|
||||
sourcemapFile,
|
||||
generation: '$currentGeneration',
|
||||
);
|
||||
if (runtimePlatform.emitsJS) {
|
||||
// Update the memory filesystem with the newly-created JS files
|
||||
_print(
|
||||
'Loading generation $currentGeneration files '
|
||||
'into the memory filesystem.',
|
||||
label: testName);
|
||||
final codeFile = File('$outputDirectoryPath.sources');
|
||||
final manifestFile = File('$outputDirectoryPath.json');
|
||||
final sourcemapFile = File('$outputDirectoryPath.map');
|
||||
filesystem.update(
|
||||
codeFile,
|
||||
manifestFile,
|
||||
sourcemapFile,
|
||||
generation: '$currentGeneration',
|
||||
);
|
||||
|
||||
// Write JS files and sourcemaps to their respective generation.
|
||||
_print('Writing generation $currentGeneration assets.', label: testName);
|
||||
_debugPrint('Writing JS assets to ${tempUri.toFilePath()}',
|
||||
label: testName);
|
||||
filesystem.writeToDisk(tempUri, generation: '$currentGeneration');
|
||||
// Write JS files and sourcemaps to their respective generation.
|
||||
_print('Writing generation $currentGeneration assets.',
|
||||
label: testName);
|
||||
_debugPrint('Writing JS assets to ${tempUri.toFilePath()}',
|
||||
label: testName);
|
||||
filesystem.writeToDisk(tempUri, generation: '$currentGeneration');
|
||||
} else {
|
||||
final dillOutputDir =
|
||||
Directory.fromUri(tempUri.resolve('generation$currentGeneration'));
|
||||
dillOutputDir.createSync();
|
||||
final dillOutputUri = dillOutputDir.uri.resolve('$testName.dill');
|
||||
File(outputDirectoryPath).copySync(dillOutputUri.toFilePath());
|
||||
// Write dills their respective generation.
|
||||
_print('Writing generation $currentGeneration assets.',
|
||||
label: testName);
|
||||
_debugPrint('Writing dill to ${dillOutputUri.toFilePath()}',
|
||||
label: testName);
|
||||
}
|
||||
currentGeneration++;
|
||||
}
|
||||
|
||||
|
@ -305,7 +358,44 @@ Future<void> main(List<String> args) async {
|
|||
break;
|
||||
case RuntimePlatforms.chrome:
|
||||
case RuntimePlatforms.vm:
|
||||
throw Exception('Unsupported platform: $runtimePlatform');
|
||||
final firstGenerationDillUri =
|
||||
tempUri.resolve('generation0/$testName.dill');
|
||||
// Start the VM at generation 0.
|
||||
final vmArgs = [
|
||||
'--enable-vm-service=0', // 0 avoids port collisions.
|
||||
'--disable-service-auth-codes',
|
||||
'--disable-dart-dev',
|
||||
firstGenerationDillUri.toFilePath(),
|
||||
];
|
||||
final vm = await Process.start(Platform.executable, vmArgs);
|
||||
_debugPrint(
|
||||
'Starting VM with command: ${Platform.executable} ${vmArgs.join(" ")}',
|
||||
label: testName);
|
||||
vm.stdout
|
||||
.transform(utf8.decoder)
|
||||
.transform(LineSplitter())
|
||||
.listen((String line) {
|
||||
_debugPrint('VM stdout: $line', label: testName);
|
||||
testOutputBuffer.writeln(line);
|
||||
});
|
||||
vm.stderr
|
||||
.transform(utf8.decoder)
|
||||
.transform(LineSplitter())
|
||||
.listen((String err) {
|
||||
_debugPrint('VM stderr: $err', label: testName);
|
||||
testOutputBuffer.writeln(err);
|
||||
});
|
||||
_print('Executing VM test.', label: testName);
|
||||
final vmExitCode = await vm.exitCode
|
||||
.timeout(Duration(seconds: testTimeoutSeconds), onTimeout: () {
|
||||
final timeoutText =
|
||||
'Test timed out after $testTimeoutSeconds seconds.';
|
||||
_print(timeoutText, label: testName);
|
||||
testOutputBuffer.writeln(timeoutText);
|
||||
vm.kill();
|
||||
return 1;
|
||||
});
|
||||
testPassed = vmExitCode == 0;
|
||||
}
|
||||
|
||||
stopwatch.stop();
|
||||
|
|
|
@ -4,12 +4,104 @@
|
|||
|
||||
// Helper functions for the hot reload test suite.
|
||||
|
||||
import 'dart:developer' show Service;
|
||||
import 'dart:io' as io;
|
||||
import 'package:vm_service/vm_service.dart' show VmService, ReloadReport;
|
||||
import 'package:vm_service/vm_service_io.dart' as vm_service_io;
|
||||
|
||||
int get hotRestartGeneration =>
|
||||
throw Exception('Not implemented on this platform.');
|
||||
|
||||
void hotRestart() => throw Exception('Not implemented on this platform.');
|
||||
|
||||
int get hotReloadGeneration =>
|
||||
throw Exception('Not implemented on this platform.');
|
||||
int _reloadCounter = 0;
|
||||
int get hotReloadGeneration => _reloadCounter;
|
||||
|
||||
void hotReload() => throw Exception('Not implemented on this platform.');
|
||||
HotReloadHelper? _hotReloadHelper;
|
||||
|
||||
Future<void> hotReload() async {
|
||||
_hotReloadHelper ??= await HotReloadHelper.create();
|
||||
_reloadCounter++;
|
||||
await _hotReloadHelper!.reloadNextGeneration();
|
||||
}
|
||||
|
||||
/// Helper to mediate with the vm service protocol.
|
||||
///
|
||||
/// Contains logic to initiate a connection with the vm service protocol on the
|
||||
/// Dart VM running the current program and for requesting a hot-reload request
|
||||
/// on the current isolate.
|
||||
///
|
||||
/// Adapted from:
|
||||
/// https://github.com/dart-lang/sdk/blob/dbcf24cedbe4d3a8eccaa51712f0c98b92173ad2/pkg/dev_compiler/tool/hotreload/hot_reload_helper.dart#L77
|
||||
class HotReloadHelper {
|
||||
/// ID for the isolate running the test.
|
||||
final String _id;
|
||||
final VmService _vmService;
|
||||
|
||||
/// The output directory under which generation directories are saved.
|
||||
final Uri testOutputDirUri;
|
||||
|
||||
/// File name of the dill (full or fragment) to be reloaded.
|
||||
///
|
||||
/// We assume that:
|
||||
/// * Every generation only loads one dill
|
||||
/// * All dill files have the same name across every generation
|
||||
final String dillName;
|
||||
|
||||
/// The current generation being executed by the VM.
|
||||
int generation = 0;
|
||||
|
||||
HotReloadHelper._(
|
||||
this._vmService, this._id, this.testOutputDirUri, this.dillName);
|
||||
|
||||
/// Create a helper that is bound to the current VM and isolate.
|
||||
static Future<HotReloadHelper> create() async {
|
||||
final info =
|
||||
await Service.controlWebServer(enable: true, silenceOutput: true);
|
||||
final observatoryUri = info.serverUri;
|
||||
if (observatoryUri == null) {
|
||||
print('Error: no VM service found. '
|
||||
'Please invoke dart with `--enable-vm-service`.');
|
||||
io.exit(1);
|
||||
}
|
||||
final wsUri = 'ws://${observatoryUri.authority}${observatoryUri.path}ws';
|
||||
final vmService = await vm_service_io.vmServiceConnectUri(wsUri);
|
||||
final vm = await vmService.getVM();
|
||||
final id =
|
||||
vm.isolates!.firstWhere((isolate) => !isolate.isSystemIsolate!).id!;
|
||||
final currentIsolateGroup = vm.isolateGroups!
|
||||
.firstWhere((isolateGroup) => !isolateGroup.isSystemIsolateGroup!);
|
||||
final dillUri = Uri.file(currentIsolateGroup.name!);
|
||||
final generationPart =
|
||||
dillUri.pathSegments[dillUri.pathSegments.length - 2];
|
||||
|
||||
if (!generationPart.startsWith('generation')) {
|
||||
print('Error: Unable to find generation in dill file: $dillUri.');
|
||||
io.exit(1);
|
||||
}
|
||||
|
||||
return HotReloadHelper._(
|
||||
vmService, id, dillUri.resolve('../'), dillUri.pathSegments.last);
|
||||
}
|
||||
|
||||
/// Trigger a hot-reload on the current isolate for the next generation.
|
||||
///
|
||||
/// Also checks that the generation aftewards exists. If not, the VM service
|
||||
/// is disconnected to allow the VM to complete.
|
||||
Future<ReloadReport> reloadNextGeneration() async {
|
||||
generation += 1;
|
||||
final nextGenerationDillUri =
|
||||
testOutputDirUri.resolve('generation$generation/$dillName');
|
||||
print('Reloading: $nextGenerationDillUri');
|
||||
var reloadReport = await _vmService.reloadSources(_id,
|
||||
rootLibUri: nextGenerationDillUri.path);
|
||||
final nextNextGenerationDillUri =
|
||||
testOutputDirUri.resolve('generation${generation + 1}/$dillName');
|
||||
final hasNextNextGeneration =
|
||||
io.File.fromUri(nextNextGenerationDillUri).existsSync();
|
||||
if (!hasNextNextGeneration) {
|
||||
await _vmService.dispose();
|
||||
}
|
||||
return reloadReport;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
class TestResultOutcome {
|
||||
// This encoder must generate each output element on its own line.
|
||||
|
@ -48,3 +49,47 @@ class TestResultOutcome {
|
|||
String escapedString(String unescaped) {
|
||||
return unescaped.replaceAll(r'\', r'\\');
|
||||
}
|
||||
|
||||
enum RuntimePlatforms {
|
||||
chrome('chrome', true),
|
||||
d8('d8', true),
|
||||
vm('vm', false);
|
||||
|
||||
const RuntimePlatforms(this.text, this.emitsJS);
|
||||
final String text;
|
||||
final bool emitsJS;
|
||||
}
|
||||
|
||||
/// Encodes information provided in a hot_reload test's configuration file.
|
||||
///
|
||||
/// Example structure:
|
||||
/// {
|
||||
/// "exclude": ["vm", "chrome"]
|
||||
/// }
|
||||
class ReloadTestConfiguration {
|
||||
final Map<String, dynamic> _values;
|
||||
final Set<RuntimePlatforms> excludedPlaforms;
|
||||
|
||||
ReloadTestConfiguration._(this._values, this.excludedPlaforms);
|
||||
|
||||
factory ReloadTestConfiguration() => ReloadTestConfiguration._(
|
||||
const <String, dynamic>{}, <RuntimePlatforms>{});
|
||||
|
||||
factory ReloadTestConfiguration.fromJsonFile(Uri file) {
|
||||
final Map<String, dynamic> jsonData =
|
||||
jsonDecode(File.fromUri(file).readAsStringSync());
|
||||
final excludedPlaforms = <RuntimePlatforms>{};
|
||||
var rawExcludedPlatforms = jsonData['exclude'];
|
||||
if (rawExcludedPlatforms != null) {
|
||||
for (final String platform in rawExcludedPlatforms) {
|
||||
final runtimePlatform = RuntimePlatforms.values.byName(platform);
|
||||
excludedPlaforms.add(runtimePlatform);
|
||||
}
|
||||
}
|
||||
return ReloadTestConfiguration._(jsonData, excludedPlaforms);
|
||||
}
|
||||
|
||||
String toJson() {
|
||||
return JsonEncoder().convert(_values);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ environment:
|
|||
dependencies:
|
||||
dev_compiler: any
|
||||
frontend_server: any
|
||||
vm_service: any
|
||||
|
||||
# Use 'any' constraints here; we get our versions from the DEPS file.
|
||||
dev_dependencies:
|
||||
|
|
3
tests/hot_reload/add_library_imports/config.json
Normal file
3
tests/hot_reload/add_library_imports/config.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"exclude": ["d8", "chrome"]
|
||||
}
|
17
tests/hot_reload/add_library_imports/main.0.dart
Normal file
17
tests/hot_reload/add_library_imports/main.0.dart
Normal file
|
@ -0,0 +1,17 @@
|
|||
import 'package:expect/expect.dart';
|
||||
import 'package:reload_test/reload_test_utils.dart';
|
||||
|
||||
import 'dart:math';
|
||||
|
||||
void validate() {
|
||||
// Initial program is valid. Symbols in 'dart:math' are visible.
|
||||
Expect.equals(0, hotReloadGeneration);
|
||||
Expect.equals(e, 2.718281828459045);
|
||||
Expect.type<double>(e);
|
||||
}
|
||||
|
||||
Future<void> main() async {
|
||||
validate();
|
||||
await hotReload();
|
||||
validate();
|
||||
}
|
20
tests/hot_reload/add_library_imports/main.1.dart
Normal file
20
tests/hot_reload/add_library_imports/main.1.dart
Normal file
|
@ -0,0 +1,20 @@
|
|||
import 'package:expect/expect.dart';
|
||||
import 'package:reload_test/reload_test_utils.dart';
|
||||
|
||||
import 'dart:math';
|
||||
import 'dart:convert';
|
||||
|
||||
void validate() {
|
||||
// Symbols in 'dart:convert' are visible after hot reload.
|
||||
Expect.equals(1, hotReloadGeneration);
|
||||
Expect.equals(e, 2.718281828459045);
|
||||
Expect.type<double>(e);
|
||||
Expect.type<Codec>(utf8);
|
||||
Expect.type<Function>(jsonEncode);
|
||||
}
|
||||
|
||||
Future<void> main() async {
|
||||
validate();
|
||||
await hotReload();
|
||||
validate();
|
||||
}
|
3
tests/hot_reload/framework_timing_test/config.json
Normal file
3
tests/hot_reload/framework_timing_test/config.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"exclude": ["vm"]
|
||||
}
|
1
tests/hot_reload/general_test/b.0.dart
Normal file
1
tests/hot_reload/general_test/b.0.dart
Normal file
|
@ -0,0 +1 @@
|
|||
get line => "part1";
|
1
tests/hot_reload/general_test/b.1.dart
Normal file
1
tests/hot_reload/general_test/b.1.dart
Normal file
|
@ -0,0 +1 @@
|
|||
get line => "part3";
|
1
tests/hot_reload/general_test/b.3.dart
Normal file
1
tests/hot_reload/general_test/b.3.dart
Normal file
|
@ -0,0 +1 @@
|
|||
get line => "part5";
|
1
tests/hot_reload/general_test/b.4.dart
Normal file
1
tests/hot_reload/general_test/b.4.dart
Normal file
|
@ -0,0 +1 @@
|
|||
get line => "part4";
|
1
tests/hot_reload/general_test/c.0.dart
Normal file
1
tests/hot_reload/general_test/c.0.dart
Normal file
|
@ -0,0 +1 @@
|
|||
String g() => "";
|
10
tests/hot_reload/general_test/c.4.dart
Normal file
10
tests/hot_reload/general_test/c.4.dart
Normal file
|
@ -0,0 +1,10 @@
|
|||
String g() {
|
||||
return bField.a("a");
|
||||
}
|
||||
|
||||
class B {
|
||||
dynamic a;
|
||||
B({this.a});
|
||||
}
|
||||
|
||||
var bField = B(a: (String s) => "$s");
|
11
tests/hot_reload/general_test/c.5.dart
Normal file
11
tests/hot_reload/general_test/c.5.dart
Normal file
|
@ -0,0 +1,11 @@
|
|||
String g() {
|
||||
return bField.a("a") + (bField.b ?? "c");
|
||||
}
|
||||
|
||||
class B {
|
||||
dynamic a;
|
||||
dynamic b;
|
||||
B({this.a});
|
||||
}
|
||||
|
||||
var bField = B(a: (String s) => "$s");
|
3
tests/hot_reload/general_test/config.json
Normal file
3
tests/hot_reload/general_test/config.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"exclude": ["d8", "chrome"]
|
||||
}
|
55
tests/hot_reload/general_test/main.0.dart
Normal file
55
tests/hot_reload/general_test/main.0.dart
Normal file
|
@ -0,0 +1,55 @@
|
|||
// 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.
|
||||
|
||||
// Adapted from:
|
||||
// https://github.com/dart-lang/sdk/blob/8df8de82b38fae8e9ae1c310fef4f8b735649fd4/pkg/front_end/test/hot_reload_e2e_test.dart
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:reload_test/reload_test_utils.dart';
|
||||
|
||||
import 'b.dart';
|
||||
import 'c.dart';
|
||||
|
||||
f() => "$line part2";
|
||||
|
||||
Future<void> main() async {
|
||||
// Initial program is valid.
|
||||
var last = f();
|
||||
Expect.equals('part1 part2', last);
|
||||
Expect.equals(0, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload after leaf library modification.
|
||||
last = f();
|
||||
Expect.equals('part3 part2', last);
|
||||
Expect.equals(1, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload after non-leaf library modification.
|
||||
last = f();
|
||||
Expect.equals('part3 part4', last);
|
||||
Expect.equals(2, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload after whole program modification.
|
||||
last = f();
|
||||
Expect.equals('part5 part6', last);
|
||||
Expect.equals(3, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload top-level field.
|
||||
last = f();
|
||||
var topLevel = g();
|
||||
Expect.equals('part4 part6', last);
|
||||
Expect.equals('a', topLevel);
|
||||
Expect.equals(4, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload top-level field.
|
||||
last = f();
|
||||
topLevel = g();
|
||||
Expect.equals('part4 part6', last);
|
||||
Expect.equals('ac', topLevel);
|
||||
Expect.equals(5, hotReloadGeneration);
|
||||
}
|
55
tests/hot_reload/general_test/main.1.dart
Normal file
55
tests/hot_reload/general_test/main.1.dart
Normal file
|
@ -0,0 +1,55 @@
|
|||
// 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.
|
||||
|
||||
// Adapted from:
|
||||
// https://github.com/dart-lang/sdk/blob/8df8de82b38fae8e9ae1c310fef4f8b735649fd4/pkg/front_end/test/hot_reload_e2e_test.dart
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:reload_test/reload_test_utils.dart';
|
||||
|
||||
import 'b.dart';
|
||||
import 'c.dart';
|
||||
|
||||
f() => "$line part2";
|
||||
|
||||
Future<void> main() async {
|
||||
// Initial program is valid.
|
||||
var last = f();
|
||||
Expect.equals('part1 part2', last);
|
||||
Expect.equals(0, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload after leaf library modification.
|
||||
last = f();
|
||||
Expect.equals('part3 part2', last);
|
||||
Expect.equals(1, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload after non-leaf library modification.
|
||||
last = f();
|
||||
Expect.equals('part3 part4', last);
|
||||
Expect.equals(2, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload after whole program modification.
|
||||
last = f();
|
||||
Expect.equals('part5 part6', last);
|
||||
Expect.equals(3, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload top-level field.
|
||||
last = f();
|
||||
var topLevel = g();
|
||||
Expect.equals('part4 part6', last);
|
||||
Expect.equals('a', topLevel);
|
||||
Expect.equals(4, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload top-level field.
|
||||
last = f();
|
||||
topLevel = g();
|
||||
Expect.equals('part4 part6', last);
|
||||
Expect.equals('ac', topLevel);
|
||||
Expect.equals(5, hotReloadGeneration);
|
||||
}
|
55
tests/hot_reload/general_test/main.2.dart
Normal file
55
tests/hot_reload/general_test/main.2.dart
Normal file
|
@ -0,0 +1,55 @@
|
|||
// 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.
|
||||
|
||||
// Adapted from:
|
||||
// https://github.com/dart-lang/sdk/blob/8df8de82b38fae8e9ae1c310fef4f8b735649fd4/pkg/front_end/test/hot_reload_e2e_test.dart
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:reload_test/reload_test_utils.dart';
|
||||
|
||||
import 'b.dart';
|
||||
import 'c.dart';
|
||||
|
||||
f() => "$line part4";
|
||||
|
||||
Future<void> main() async {
|
||||
// Initial program is valid.
|
||||
var last = f();
|
||||
Expect.equals('part1 part2', last);
|
||||
Expect.equals(0, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload after leaf library modification.
|
||||
last = f();
|
||||
Expect.equals('part3 part2', last);
|
||||
Expect.equals(1, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload after non-leaf library modification.
|
||||
last = f();
|
||||
Expect.equals('part3 part4', last);
|
||||
Expect.equals(2, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload after whole program modification.
|
||||
last = f();
|
||||
Expect.equals('part5 part6', last);
|
||||
Expect.equals(3, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload top-level field.
|
||||
last = f();
|
||||
var topLevel = g();
|
||||
Expect.equals('part4 part6', last);
|
||||
Expect.equals('a', topLevel);
|
||||
Expect.equals(4, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload top-level field.
|
||||
last = f();
|
||||
topLevel = g();
|
||||
Expect.equals('part4 part6', last);
|
||||
Expect.equals('ac', topLevel);
|
||||
Expect.equals(5, hotReloadGeneration);
|
||||
}
|
55
tests/hot_reload/general_test/main.3.dart
Normal file
55
tests/hot_reload/general_test/main.3.dart
Normal file
|
@ -0,0 +1,55 @@
|
|||
// 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.
|
||||
|
||||
// Adapted from:
|
||||
// https://github.com/dart-lang/sdk/blob/8df8de82b38fae8e9ae1c310fef4f8b735649fd4/pkg/front_end/test/hot_reload_e2e_test.dart
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:reload_test/reload_test_utils.dart';
|
||||
|
||||
import 'b.dart';
|
||||
import 'c.dart';
|
||||
|
||||
f() => "$line part6";
|
||||
|
||||
Future<void> main() async {
|
||||
// Initial program is valid.
|
||||
var last = f();
|
||||
Expect.equals('part1 part2', last);
|
||||
Expect.equals(0, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload after leaf library modification.
|
||||
last = f();
|
||||
Expect.equals('part3 part2', last);
|
||||
Expect.equals(1, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload after non-leaf library modification.
|
||||
last = f();
|
||||
Expect.equals('part3 part4', last);
|
||||
Expect.equals(2, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload after whole program modification.
|
||||
last = f();
|
||||
Expect.equals('part5 part6', last);
|
||||
Expect.equals(3, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload top-level field.
|
||||
last = f();
|
||||
var topLevel = g();
|
||||
Expect.equals('part4 part6', last);
|
||||
Expect.equals('a', topLevel);
|
||||
Expect.equals(4, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload top-level field.
|
||||
last = f();
|
||||
topLevel = g();
|
||||
Expect.equals('part4 part6', last);
|
||||
Expect.equals('ac', topLevel);
|
||||
Expect.equals(5, hotReloadGeneration);
|
||||
}
|
55
tests/hot_reload/general_test/main.4.dart
Normal file
55
tests/hot_reload/general_test/main.4.dart
Normal file
|
@ -0,0 +1,55 @@
|
|||
// 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.
|
||||
|
||||
// Adapted from:
|
||||
// https://github.com/dart-lang/sdk/blob/8df8de82b38fae8e9ae1c310fef4f8b735649fd4/pkg/front_end/test/hot_reload_e2e_test.dart
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:reload_test/reload_test_utils.dart';
|
||||
|
||||
import 'b.dart';
|
||||
import 'c.dart';
|
||||
|
||||
f() => "$line part6";
|
||||
|
||||
Future<void> main() async {
|
||||
// Initial program is valid.
|
||||
var last = f();
|
||||
Expect.equals('part1 part2', last);
|
||||
Expect.equals(0, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload after leaf library modification.
|
||||
last = f();
|
||||
Expect.equals('part3 part2', last);
|
||||
Expect.equals(1, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload after non-leaf library modification.
|
||||
last = f();
|
||||
Expect.equals('part3 part4', last);
|
||||
Expect.equals(2, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload after whole program modification.
|
||||
last = f();
|
||||
Expect.equals('part5 part6', last);
|
||||
Expect.equals(3, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload top-level field.
|
||||
last = f();
|
||||
var topLevel = g();
|
||||
Expect.equals('part4 part6', last);
|
||||
Expect.equals('a', topLevel);
|
||||
Expect.equals(4, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload top-level field.
|
||||
last = f();
|
||||
topLevel = g();
|
||||
Expect.equals('part4 part6', last);
|
||||
Expect.equals('ac', topLevel);
|
||||
Expect.equals(5, hotReloadGeneration);
|
||||
}
|
55
tests/hot_reload/general_test/main.5.dart
Normal file
55
tests/hot_reload/general_test/main.5.dart
Normal file
|
@ -0,0 +1,55 @@
|
|||
// 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.
|
||||
|
||||
// Adapted from:
|
||||
// https://github.com/dart-lang/sdk/blob/8df8de82b38fae8e9ae1c310fef4f8b735649fd4/pkg/front_end/test/hot_reload_e2e_test.dart
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:reload_test/reload_test_utils.dart';
|
||||
|
||||
import 'b.dart';
|
||||
import 'c.dart';
|
||||
|
||||
f() => "$line part6";
|
||||
|
||||
Future<void> main() async {
|
||||
// Initial program is valid.
|
||||
var last = f();
|
||||
Expect.equals('part1 part2', last);
|
||||
Expect.equals(0, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload after leaf library modification.
|
||||
last = f();
|
||||
Expect.equals('part3 part2', last);
|
||||
Expect.equals(1, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload after non-leaf library modification.
|
||||
last = f();
|
||||
Expect.equals('part3 part4', last);
|
||||
Expect.equals(2, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload after whole program modification.
|
||||
last = f();
|
||||
Expect.equals('part5 part6', last);
|
||||
Expect.equals(3, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload top-level field.
|
||||
last = f();
|
||||
var topLevel = g();
|
||||
Expect.equals('part4 part6', last);
|
||||
Expect.equals('a', topLevel);
|
||||
Expect.equals(4, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// Reload top-level field.
|
||||
last = f();
|
||||
topLevel = g();
|
||||
Expect.equals('part4 part6', last);
|
||||
Expect.equals('ac', topLevel);
|
||||
Expect.equals(5, hotReloadGeneration);
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"exclude": ["vm"]
|
||||
}
|
3
tests/hot_reload/lazy_static_initializers/config.json
Normal file
3
tests/hot_reload/lazy_static_initializers/config.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"exclude": ["d8", "chrome", "vm"]
|
||||
}
|
27
tests/hot_reload/lazy_static_initializers/main.0.dart
Normal file
27
tests/hot_reload/lazy_static_initializers/main.0.dart
Normal file
|
@ -0,0 +1,27 @@
|
|||
// 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.
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:reload_test/reload_test_utils.dart';
|
||||
|
||||
var value = "unused";
|
||||
|
||||
Future<void> main() async {
|
||||
// Declare an unreferenced lazy static field.
|
||||
Expect.equals(0, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// The lazy static field changes value but remains unread.
|
||||
Expect.equals(1, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// The lazy static is now read and contains the updated value.
|
||||
Expect.equals(2, hotReloadGeneration);
|
||||
Expect.equals("before", value);
|
||||
await hotReload();
|
||||
|
||||
// The lazy static is updated and read but retains the old value.
|
||||
Expect.equals(3, hotReloadGeneration);
|
||||
Expect.equals("before", value);
|
||||
}
|
27
tests/hot_reload/lazy_static_initializers/main.1.dart
Normal file
27
tests/hot_reload/lazy_static_initializers/main.1.dart
Normal file
|
@ -0,0 +1,27 @@
|
|||
// 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.
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:reload_test/reload_test_utils.dart';
|
||||
|
||||
var value = "before";
|
||||
|
||||
Future<void> main() async {
|
||||
// Declare an unreferenced lazy static field.
|
||||
Expect.equals(0, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// The lazy static field changes value but remains unread.
|
||||
Expect.equals(1, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// The lazy static is now read and contains the updated value.
|
||||
Expect.equals(2, hotReloadGeneration);
|
||||
Expect.equals("before", value);
|
||||
await hotReload();
|
||||
|
||||
// The lazy static is updated and read but retains the old value.
|
||||
Expect.equals(3, hotReloadGeneration);
|
||||
Expect.equals("before", value);
|
||||
}
|
28
tests/hot_reload/lazy_static_initializers/main.2.dart
Normal file
28
tests/hot_reload/lazy_static_initializers/main.2.dart
Normal file
|
@ -0,0 +1,28 @@
|
|||
// 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.
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:reload_test/reload_test_utils.dart';
|
||||
|
||||
var value = "before";
|
||||
|
||||
Future<void> main() async {
|
||||
// Declare an unreferenced lazy static field.
|
||||
Expect.equals(0, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// The lazy static field changes value but remains unread.
|
||||
Expect.equals(1, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// The lazy static is now read and contains the updated value.
|
||||
print(value);
|
||||
Expect.equals(2, hotReloadGeneration);
|
||||
Expect.equals("before", value);
|
||||
await hotReload();
|
||||
|
||||
// The lazy static is updated and read but retains the old value.
|
||||
Expect.equals(3, hotReloadGeneration);
|
||||
Expect.equals("before", value);
|
||||
}
|
27
tests/hot_reload/lazy_static_initializers/main.3.dart
Normal file
27
tests/hot_reload/lazy_static_initializers/main.3.dart
Normal file
|
@ -0,0 +1,27 @@
|
|||
// 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.
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:reload_test/reload_test_utils.dart';
|
||||
|
||||
var value = "after";
|
||||
|
||||
Future<void> main() async {
|
||||
// Declare an unreferenced lazy static field.
|
||||
Expect.equals(0, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// The lazy static field changes value but remains unread.
|
||||
Expect.equals(1, hotReloadGeneration);
|
||||
await hotReload();
|
||||
|
||||
// The lazy static is now read and contains the updated value.
|
||||
Expect.equals(2, hotReloadGeneration);
|
||||
Expect.equals("before", value);
|
||||
await hotReload();
|
||||
|
||||
// The lazy static is updated and read but retains the old value.
|
||||
Expect.equals(3, hotReloadGeneration);
|
||||
Expect.equals("before", value);
|
||||
}
|
3
tests/hot_reload/run_lazy_field_initializers/config.json
Normal file
3
tests/hot_reload/run_lazy_field_initializers/config.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"exclude": ["d8", "chrome"]
|
||||
}
|
33
tests/hot_reload/run_lazy_field_initializers/main.0.dart
Normal file
33
tests/hot_reload/run_lazy_field_initializers/main.0.dart
Normal file
|
@ -0,0 +1,33 @@
|
|||
// 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.
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:reload_test/reload_test_utils.dart';
|
||||
|
||||
// Adapted from:
|
||||
// https://github.com/dart-lang/sdk/blob/36c0788137d55c6c77f4b9a8be12e557bc764b1c/runtime/vm/isolate_reload_test.cc#L4810
|
||||
|
||||
int myInitialValue = 8 * 7;
|
||||
|
||||
class Foo {
|
||||
int x = 4;
|
||||
}
|
||||
|
||||
late Foo value;
|
||||
late Foo value1;
|
||||
|
||||
void validate() {
|
||||
Expect.equals(0, hotReloadGeneration);
|
||||
value = Foo();
|
||||
value1 = Foo();
|
||||
Expect.equals(4, value.x);
|
||||
Expect.equals(4, value1.x);
|
||||
Expect.equals(56, myInitialValue);
|
||||
}
|
||||
|
||||
Future<void> main() async {
|
||||
validate();
|
||||
await hotReload();
|
||||
validate();
|
||||
}
|
36
tests/hot_reload/run_lazy_field_initializers/main.1.dart
Normal file
36
tests/hot_reload/run_lazy_field_initializers/main.1.dart
Normal file
|
@ -0,0 +1,36 @@
|
|||
// 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.
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:reload_test/reload_test_utils.dart';
|
||||
|
||||
// Adapted from:
|
||||
// https://github.com/dart-lang/sdk/blob/36c0788137d55c6c77f4b9a8be12e557bc764b1c/runtime/vm/isolate_reload_test.cc#L4810
|
||||
|
||||
int myInitialValue = 8 * 7;
|
||||
|
||||
class Foo {
|
||||
int x = 4;
|
||||
int y = myInitialValue++;
|
||||
}
|
||||
|
||||
late Foo value;
|
||||
late Foo value1;
|
||||
|
||||
void validate() {
|
||||
// Add field 'y' with side effects and verify that initializers ran lazily.
|
||||
Expect.equals(1, hotReloadGeneration);
|
||||
Expect.equals(4, value.x);
|
||||
Expect.equals(4, value1.x);
|
||||
Expect.equals(56, myInitialValue);
|
||||
Expect.equals(56, value.y);
|
||||
Expect.equals(57, value1.y);
|
||||
Expect.equals(58, myInitialValue);
|
||||
}
|
||||
|
||||
Future<void> main() async {
|
||||
validate();
|
||||
await hotReload();
|
||||
validate();
|
||||
}
|
3
tests/hot_reload/timer_test/config.json
Normal file
3
tests/hot_reload/timer_test/config.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"exclude": ["d8", "chrome"]
|
||||
}
|
47
tests/hot_reload/timer_test/main.0.dart
Normal file
47
tests/hot_reload/timer_test/main.0.dart
Normal file
|
@ -0,0 +1,47 @@
|
|||
// 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.
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:reload_test/reload_test_utils.dart';
|
||||
import 'dart:async';
|
||||
|
||||
var counter = 0;
|
||||
|
||||
Future<void> main() async {
|
||||
final periodicTimerDone = Completer();
|
||||
|
||||
Expect.equals(0, hotReloadGeneration);
|
||||
Expect.equals(0, counter++);
|
||||
Timer.periodic(Duration(milliseconds: 400), (timer) {
|
||||
// Runs in the final generation.
|
||||
Expect.equals(2, hotReloadGeneration);
|
||||
periodicTimerDone.complete();
|
||||
timer.cancel();
|
||||
});
|
||||
|
||||
await Future.delayed(Duration(milliseconds: 20), () {
|
||||
Expect.equals(1, counter++);
|
||||
});
|
||||
|
||||
Expect.equals(0, hotReloadGeneration);
|
||||
Expect.isFalse(periodicTimerDone.isCompleted);
|
||||
|
||||
await hotReload();
|
||||
|
||||
Expect.equals(1, hotReloadGeneration);
|
||||
Expect.equals(2, counter++);
|
||||
await Future.delayed(Duration(milliseconds: 20), () {
|
||||
Expect.equals(3, counter++);
|
||||
});
|
||||
Expect.equals(1, hotReloadGeneration);
|
||||
Expect.isFalse(periodicTimerDone.isCompleted);
|
||||
|
||||
await hotReload();
|
||||
|
||||
Expect.isFalse(periodicTimerDone.isCompleted);
|
||||
Expect.equals(2, hotReloadGeneration);
|
||||
Expect.equals(4, counter++);
|
||||
|
||||
await periodicTimerDone.future;
|
||||
}
|
47
tests/hot_reload/timer_test/main.1.dart
Normal file
47
tests/hot_reload/timer_test/main.1.dart
Normal file
|
@ -0,0 +1,47 @@
|
|||
// 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.
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:reload_test/reload_test_utils.dart';
|
||||
import 'dart:async';
|
||||
|
||||
var counter = 0;
|
||||
|
||||
Future<void> main() async {
|
||||
final periodicTimerDone = Completer();
|
||||
|
||||
Expect.equals(0, hotReloadGeneration);
|
||||
Expect.equals(0, counter++);
|
||||
Timer.periodic(Duration(milliseconds: 400), (timer) {
|
||||
// Runs in the final generation.
|
||||
Expect.equals(2, hotReloadGeneration);
|
||||
periodicTimerDone.complete();
|
||||
timer.cancel();
|
||||
});
|
||||
|
||||
await Future.delayed(Duration(milliseconds: 20), () {
|
||||
Expect.equals(1, counter++);
|
||||
});
|
||||
|
||||
Expect.equals(0, hotReloadGeneration);
|
||||
Expect.isFalse(periodicTimerDone.isCompleted);
|
||||
|
||||
await hotReload();
|
||||
|
||||
Expect.equals(1, hotReloadGeneration);
|
||||
Expect.equals(2, counter++);
|
||||
await Future.delayed(Duration(milliseconds: 20), () {
|
||||
Expect.equals(3, counter++);
|
||||
});
|
||||
Expect.equals(1, hotReloadGeneration);
|
||||
Expect.isFalse(periodicTimerDone.isCompleted);
|
||||
|
||||
await hotReload();
|
||||
|
||||
Expect.isFalse(periodicTimerDone.isCompleted);
|
||||
Expect.equals(2, hotReloadGeneration);
|
||||
Expect.equals(4, counter++);
|
||||
|
||||
await periodicTimerDone.future;
|
||||
}
|
47
tests/hot_reload/timer_test/main.2.dart
Normal file
47
tests/hot_reload/timer_test/main.2.dart
Normal file
|
@ -0,0 +1,47 @@
|
|||
// 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.
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:reload_test/reload_test_utils.dart';
|
||||
import 'dart:async';
|
||||
|
||||
var counter = 0;
|
||||
|
||||
Future<void> main() async {
|
||||
final periodicTimerDone = Completer();
|
||||
|
||||
Expect.equals(0, hotReloadGeneration);
|
||||
Expect.equals(0, counter++);
|
||||
Timer.periodic(Duration(milliseconds: 400), (timer) {
|
||||
// Runs in the final generation.
|
||||
Expect.equals(2, hotReloadGeneration);
|
||||
periodicTimerDone.complete();
|
||||
timer.cancel();
|
||||
});
|
||||
|
||||
await Future.delayed(Duration(milliseconds: 20), () {
|
||||
Expect.equals(1, counter++);
|
||||
});
|
||||
|
||||
Expect.equals(0, hotReloadGeneration);
|
||||
Expect.isFalse(periodicTimerDone.isCompleted);
|
||||
|
||||
await hotReload();
|
||||
|
||||
Expect.equals(1, hotReloadGeneration);
|
||||
Expect.equals(2, counter++);
|
||||
await Future.delayed(Duration(milliseconds: 20), () {
|
||||
Expect.equals(3, counter++);
|
||||
});
|
||||
Expect.equals(1, hotReloadGeneration);
|
||||
Expect.isFalse(periodicTimerDone.isCompleted);
|
||||
|
||||
await hotReload();
|
||||
|
||||
Expect.isFalse(periodicTimerDone.isCompleted);
|
||||
Expect.equals(2, hotReloadGeneration);
|
||||
Expect.equals(4, counter++);
|
||||
|
||||
await periodicTimerDone.future;
|
||||
}
|
Loading…
Reference in a new issue