[reload_test] Reformat pkg/reload_test
Change-Id: Idb0d35f552aad7c512fd7e19317c4cd1af1e9980 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/500241 Commit-Queue: Nicholas Shahan <nshahan@google.com> Reviewed-by: Bob Nystrom <rnystrom@google.com>
This commit is contained in:
committed by
dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent
c0df8bae2e
commit
3e0828907c
@@ -23,14 +23,20 @@ class D8Configuration {
|
||||
final Uri preamblesScript;
|
||||
final Uri sealNativeObjectScript;
|
||||
|
||||
D8Configuration._(this.sdkRoot, this.binary, this.preamblesScript,
|
||||
this.sealNativeObjectScript);
|
||||
D8Configuration._(
|
||||
this.sdkRoot,
|
||||
this.binary,
|
||||
this.preamblesScript,
|
||||
this.sealNativeObjectScript,
|
||||
);
|
||||
|
||||
factory D8Configuration(Uri sdkRoot) {
|
||||
final preamblesScript = sdkRoot
|
||||
.resolve('sdk/lib/_internal/js_dev_runtime/private/preambles/d8.js');
|
||||
final preamblesScript = sdkRoot.resolve(
|
||||
'sdk/lib/_internal/js_dev_runtime/private/preambles/d8.js',
|
||||
);
|
||||
final sealNativeObjectScript = sdkRoot.resolve(
|
||||
'sdk/lib/_internal/js_runtime/lib/preambles/seal_native_object.js');
|
||||
'sdk/lib/_internal/js_runtime/lib/preambles/seal_native_object.js',
|
||||
);
|
||||
final arch = Abi.current().toString().split('_')[1];
|
||||
final Uri binaryFromRoot;
|
||||
if (Platform.isWindows) {
|
||||
@@ -40,12 +46,18 @@ class D8Configuration {
|
||||
} else if (Platform.isMacOS) {
|
||||
binaryFromRoot = Uri.file('third_party/d8/macos/$arch/d8');
|
||||
} else {
|
||||
throw UnsupportedError('Unsupported platform for running d8: '
|
||||
'${Platform.operatingSystem}');
|
||||
throw UnsupportedError(
|
||||
'Unsupported platform for running d8: '
|
||||
'${Platform.operatingSystem}',
|
||||
);
|
||||
}
|
||||
final binary = sdkRoot.resolveUri(binaryFromRoot);
|
||||
return D8Configuration._(
|
||||
sdkRoot, binary, preamblesScript, sealNativeObjectScript);
|
||||
sdkRoot,
|
||||
binary,
|
||||
preamblesScript,
|
||||
sealNativeObjectScript,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +92,8 @@ String generateD8Bootstrapper({
|
||||
required List<Map<String, String?>> scriptDescriptors,
|
||||
required FileDataPerGeneration modifiedFilesPerGeneration,
|
||||
}) {
|
||||
final d8BootstrapJS = '''
|
||||
final d8BootstrapJS =
|
||||
'''
|
||||
load("$ddcModuleLoaderJsPath");
|
||||
load("$dartSdkJsPath");
|
||||
|
||||
@@ -343,7 +356,8 @@ String generateChromeBootstrapper({
|
||||
required List<Map<String, String?>> scriptDescriptors,
|
||||
required FileDataPerGeneration modifiedFilesPerGeneration,
|
||||
}) {
|
||||
final bootstrapJS = '''
|
||||
final bootstrapJS =
|
||||
'''
|
||||
var _currentDirectory = "$jsFileRoot";
|
||||
|
||||
window.\$dartCreateScript = (function() {
|
||||
|
||||
@@ -24,10 +24,7 @@ class CompilerOutput {
|
||||
|
||||
/// Output for a 'reject' response.
|
||||
factory CompilerOutput.rejectOutput() {
|
||||
return CompilerOutput(
|
||||
outputDillPath: '',
|
||||
errorCount: 0,
|
||||
);
|
||||
return CompilerOutput(outputDillPath: '', errorCount: 0);
|
||||
}
|
||||
|
||||
final String outputDillPath;
|
||||
@@ -102,16 +99,26 @@ class HotReloadFrontendServerController {
|
||||
|
||||
FrontendServerState _state = FrontendServerState.awaitingResult;
|
||||
|
||||
HotReloadFrontendServerController._(this.frontendServerArgs, this.input,
|
||||
this.output, this.compileCommandOutputChannel, this.synchronizer);
|
||||
HotReloadFrontendServerController._(
|
||||
this.frontendServerArgs,
|
||||
this.input,
|
||||
this.output,
|
||||
this.compileCommandOutputChannel,
|
||||
this.synchronizer,
|
||||
);
|
||||
|
||||
factory HotReloadFrontendServerController(List<String> frontendServerArgs) {
|
||||
var input = StreamController<List<int>>();
|
||||
var output = StreamController<List<int>>();
|
||||
var compileCommandOutputChannel = StreamController<CompilerOutput>();
|
||||
var synchronizer = StreamIterator(compileCommandOutputChannel.stream);
|
||||
return HotReloadFrontendServerController._(frontendServerArgs, input,
|
||||
output, compileCommandOutputChannel, synchronizer);
|
||||
return HotReloadFrontendServerController._(
|
||||
frontendServerArgs,
|
||||
input,
|
||||
output,
|
||||
compileCommandOutputChannel,
|
||||
synchronizer,
|
||||
);
|
||||
}
|
||||
|
||||
/// Runs the Frontend Server in-memory in incremental mode.
|
||||
@@ -126,70 +133,77 @@ class HotReloadFrontendServerController {
|
||||
.transform(utf8.decoder)
|
||||
.transform(const LineSplitter())
|
||||
.listen((String s) {
|
||||
if (debug) print('Frontend Server Response: $s');
|
||||
switch (_state) {
|
||||
case FrontendServerState.awaitingReject:
|
||||
if (!s.startsWith(frontEndResponsePrefix)) {
|
||||
throw Exception('Unexpected Frontend Server response: $s');
|
||||
if (debug) print('Frontend Server Response: $s');
|
||||
switch (_state) {
|
||||
case FrontendServerState.awaitingReject:
|
||||
if (!s.startsWith(frontEndResponsePrefix)) {
|
||||
throw Exception('Unexpected Frontend Server response: $s');
|
||||
}
|
||||
_boundaryKey = s.substring(frontEndResponsePrefix.length);
|
||||
_state = FrontendServerState.awaitingRejectKey;
|
||||
break;
|
||||
case FrontendServerState.awaitingRejectKey:
|
||||
if (s != _boundaryKey) {
|
||||
throw Exception(
|
||||
'Unexpected Frontend Server response for reject '
|
||||
'(expected just a key): $s',
|
||||
);
|
||||
}
|
||||
_state = FrontendServerState.finished;
|
||||
compileCommandOutputChannel.add(CompilerOutput.rejectOutput());
|
||||
_clearState();
|
||||
break;
|
||||
case FrontendServerState.awaitingResult:
|
||||
if (!s.startsWith(frontEndResponsePrefix)) {
|
||||
throw Exception('Unexpected Frontend Server response: $s');
|
||||
}
|
||||
_boundaryKey = s.substring(frontEndResponsePrefix.length);
|
||||
_state = FrontendServerState.awaitingKey;
|
||||
break;
|
||||
case FrontendServerState.awaitingKey:
|
||||
// Advance to the next state when we encounter a lone boundary
|
||||
// key.
|
||||
if (s == _boundaryKey) {
|
||||
_state = FrontendServerState.collectingResultSources;
|
||||
} else {
|
||||
accumulatedOutput.add(s);
|
||||
}
|
||||
case FrontendServerState.collectingResultSources:
|
||||
// Stop and record the result when we encounter a boundary key.
|
||||
if (s.startsWith(_boundaryKey)) {
|
||||
final compilationReportOutput = s.split(' ');
|
||||
final outputDillPath = compilationReportOutput[1];
|
||||
final errorCount = int.parse(compilationReportOutput[2]);
|
||||
// The FrontendServer accumulates all errors seen so far, so we
|
||||
// need to correct for errors from previous compilations.
|
||||
final actualErrorCount = errorCount - totalErrors;
|
||||
final compilerOutput = CompilerOutput(
|
||||
outputDillPath: outputDillPath,
|
||||
errorCount: actualErrorCount,
|
||||
sources: sources,
|
||||
outputText: accumulatedOutput.join('\n'),
|
||||
);
|
||||
totalErrors = errorCount;
|
||||
_state = FrontendServerState.finished;
|
||||
compileCommandOutputChannel.add(compilerOutput);
|
||||
_clearState();
|
||||
} else if (s.startsWith('+')) {
|
||||
sources.add(Uri.parse(s.substring(1)));
|
||||
} else if (s.startsWith('-')) {
|
||||
sources.remove(Uri.parse(s.substring(1)));
|
||||
} else {
|
||||
throw Exception(
|
||||
"Unexpected Frontend Server response "
|
||||
"(expected '+' or '-')'): $s",
|
||||
);
|
||||
}
|
||||
break;
|
||||
case FrontendServerState.finished:
|
||||
throw StateError(
|
||||
'Frontend Server reached an unexpected state: $s',
|
||||
);
|
||||
}
|
||||
_boundaryKey = s.substring(frontEndResponsePrefix.length);
|
||||
_state = FrontendServerState.awaitingRejectKey;
|
||||
break;
|
||||
case FrontendServerState.awaitingRejectKey:
|
||||
if (s != _boundaryKey) {
|
||||
throw Exception('Unexpected Frontend Server response for reject '
|
||||
'(expected just a key): $s');
|
||||
}
|
||||
_state = FrontendServerState.finished;
|
||||
compileCommandOutputChannel.add(CompilerOutput.rejectOutput());
|
||||
_clearState();
|
||||
break;
|
||||
case FrontendServerState.awaitingResult:
|
||||
if (!s.startsWith(frontEndResponsePrefix)) {
|
||||
throw Exception('Unexpected Frontend Server response: $s');
|
||||
}
|
||||
_boundaryKey = s.substring(frontEndResponsePrefix.length);
|
||||
_state = FrontendServerState.awaitingKey;
|
||||
break;
|
||||
case FrontendServerState.awaitingKey:
|
||||
// Advance to the next state when we encounter a lone boundary key.
|
||||
if (s == _boundaryKey) {
|
||||
_state = FrontendServerState.collectingResultSources;
|
||||
} else {
|
||||
accumulatedOutput.add(s);
|
||||
}
|
||||
case FrontendServerState.collectingResultSources:
|
||||
// Stop and record the result when we encounter a boundary key.
|
||||
if (s.startsWith(_boundaryKey)) {
|
||||
final compilationReportOutput = s.split(' ');
|
||||
final outputDillPath = compilationReportOutput[1];
|
||||
final errorCount = int.parse(compilationReportOutput[2]);
|
||||
// The FrontendServer accumulates all errors seen so far, so we
|
||||
// need to correct for errors from previous compilations.
|
||||
final actualErrorCount = errorCount - totalErrors;
|
||||
final compilerOutput = CompilerOutput(
|
||||
outputDillPath: outputDillPath,
|
||||
errorCount: actualErrorCount,
|
||||
sources: sources,
|
||||
outputText: accumulatedOutput.join('\n'),
|
||||
);
|
||||
totalErrors = errorCount;
|
||||
_state = FrontendServerState.finished;
|
||||
compileCommandOutputChannel.add(compilerOutput);
|
||||
_clearState();
|
||||
} else if (s.startsWith('+')) {
|
||||
sources.add(Uri.parse(s.substring(1)));
|
||||
} else if (s.startsWith('-')) {
|
||||
sources.remove(Uri.parse(s.substring(1)));
|
||||
} else {
|
||||
throw Exception("Unexpected Frontend Server response "
|
||||
"(expected '+' or '-')'): $s");
|
||||
}
|
||||
break;
|
||||
case FrontendServerState.finished:
|
||||
throw StateError('Frontend Server reached an unexpected state: $s');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
frontendServerExitCode = starter(
|
||||
frontendServerArgs,
|
||||
@@ -225,10 +239,12 @@ class HotReloadFrontendServerController {
|
||||
sendAccept();
|
||||
}
|
||||
|
||||
Future<CompilerOutput> sendRecompile(String entrypointPath,
|
||||
{List<String> invalidatedFiles = const [],
|
||||
String boundaryKey = fakeBoundaryKey,
|
||||
required bool recompileRestart}) async {
|
||||
Future<CompilerOutput> sendRecompile(
|
||||
String entrypointPath, {
|
||||
List<String> invalidatedFiles = const [],
|
||||
String boundaryKey = fakeBoundaryKey,
|
||||
required bool recompileRestart,
|
||||
}) async {
|
||||
// Currently the `FrontendCompiler` used in this test suite clears errors
|
||||
// before performing a recompile but not an initial compile. Since we reuse
|
||||
// the same instance and issue an initial compile request for each test we
|
||||
@@ -239,7 +255,8 @@ class HotReloadFrontendServerController {
|
||||
if (!started) throw Exception('Frontend Server has not been started yet.');
|
||||
_state = FrontendServerState.awaitingResult;
|
||||
final instruction = recompileRestart ? 'recompile-restart' : 'recompile';
|
||||
final command = '$instruction $entrypointPath $boundaryKey\n'
|
||||
final command =
|
||||
'$instruction $entrypointPath $boundaryKey\n'
|
||||
'${invalidatedFiles.join('\n')}\n$boundaryKey\n';
|
||||
if (debug) print('Sending instruction to Frontend Server:\n$command');
|
||||
input.add(command.codeUnits);
|
||||
@@ -247,14 +264,18 @@ class HotReloadFrontendServerController {
|
||||
return synchronizer.current;
|
||||
}
|
||||
|
||||
Future<void> sendRecompileAndAccept(String entrypointPath,
|
||||
{List<String> invalidatedFiles = const [],
|
||||
String boundaryKey = fakeBoundaryKey,
|
||||
required bool recompileRestart}) async {
|
||||
await sendRecompile(entrypointPath,
|
||||
invalidatedFiles: invalidatedFiles,
|
||||
boundaryKey: boundaryKey,
|
||||
recompileRestart: recompileRestart);
|
||||
Future<void> sendRecompileAndAccept(
|
||||
String entrypointPath, {
|
||||
List<String> invalidatedFiles = const [],
|
||||
String boundaryKey = fakeBoundaryKey,
|
||||
required bool recompileRestart,
|
||||
}) async {
|
||||
await sendRecompile(
|
||||
entrypointPath,
|
||||
invalidatedFiles: invalidatedFiles,
|
||||
boundaryKey: boundaryKey,
|
||||
recompileRestart: recompileRestart,
|
||||
);
|
||||
sendAccept();
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,8 @@ import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:dev_compiler/dev_compiler.dart' as ddc_names
|
||||
import 'package:dev_compiler/dev_compiler.dart'
|
||||
as ddc_names
|
||||
show libraryUriToJsIdentifier;
|
||||
|
||||
import 'package:reload_test/ddc_helpers.dart' show FileDataPerGeneration;
|
||||
@@ -48,13 +49,19 @@ class HotReloadMemoryFilesystem implements FileResolver {
|
||||
///
|
||||
/// [clearWritableState] clears generation-specific state so that old
|
||||
/// generations' files aren't rewritten.
|
||||
void writeToDisk(Uri outputDirectoryUri,
|
||||
{required String generation, bool clearWritableState = true}) {
|
||||
assert(Directory.fromUri(outputDirectoryUri).existsSync(),
|
||||
'$outputDirectoryUri does not exist.');
|
||||
void writeToDisk(
|
||||
Uri outputDirectoryUri, {
|
||||
required String generation,
|
||||
bool clearWritableState = true,
|
||||
}) {
|
||||
assert(
|
||||
Directory.fromUri(outputDirectoryUri).existsSync(),
|
||||
'$outputDirectoryUri does not exist.',
|
||||
);
|
||||
files.forEach((path, content) {
|
||||
final outputFileUri =
|
||||
outputDirectoryUri.resolve('generation$generation/').resolve(path);
|
||||
final outputFileUri = outputDirectoryUri
|
||||
.resolve('generation$generation/')
|
||||
.resolve(path);
|
||||
final outputFile = File.fromUri(outputFileUri);
|
||||
outputFile.createSync(recursive: true);
|
||||
outputFile.writeAsBytesSync(content);
|
||||
@@ -68,11 +75,11 @@ class HotReloadMemoryFilesystem implements FileResolver {
|
||||
|
||||
@override
|
||||
FileDataPerGeneration get generationsToModifiedFilePaths => {
|
||||
for (var e in generationChanges.entries)
|
||||
e.key: e.value
|
||||
.map((info) => [info.libraryName, info.jsSourcePath])
|
||||
.toList()
|
||||
};
|
||||
for (var e in generationChanges.entries)
|
||||
e.key: e.value
|
||||
.map((info) => [info.libraryName, info.jsSourcePath])
|
||||
.toList(),
|
||||
};
|
||||
|
||||
@override
|
||||
List<Map<String, String?>> get scriptDescriptorForBootstrap {
|
||||
@@ -103,17 +110,19 @@ class HotReloadMemoryFilesystem implements FileResolver {
|
||||
final codeBytes = codeFile.readAsBytesSync();
|
||||
final sourcemapBytes = sourcemapFile.readAsBytesSync();
|
||||
final manifest = Map.castFrom<dynamic, dynamic, String, Object?>(
|
||||
json.decode(manifestFile.readAsStringSync()) as Map);
|
||||
json.decode(manifestFile.readAsStringSync()) as Map,
|
||||
);
|
||||
|
||||
generationChanges[generation] = [];
|
||||
for (final filePath in manifest.keys) {
|
||||
final fileUri = Uri.file(filePath);
|
||||
final Map<String, dynamic> offsets =
|
||||
Map.castFrom<dynamic, dynamic, String, Object?>(
|
||||
manifest[filePath] as Map);
|
||||
manifest[filePath] as Map,
|
||||
);
|
||||
final codeOffsets = (offsets['code'] as List<dynamic>).cast<int>();
|
||||
final sourcemapOffsets =
|
||||
(offsets['sourcemap'] as List<dynamic>).cast<int>();
|
||||
final sourcemapOffsets = (offsets['sourcemap'] as List<dynamic>)
|
||||
.cast<int>();
|
||||
|
||||
if (codeOffsets.length != 2 || sourcemapOffsets.length != 2) {
|
||||
continue;
|
||||
@@ -129,19 +138,23 @@ class HotReloadMemoryFilesystem implements FileResolver {
|
||||
codeStart,
|
||||
codeEnd - codeStart,
|
||||
);
|
||||
final fileName =
|
||||
filePath.startsWith('/') ? filePath.substring(1) : filePath;
|
||||
final fileName = filePath.startsWith('/')
|
||||
? filePath.substring(1)
|
||||
: filePath;
|
||||
files[fileName] = byteView;
|
||||
final moduleName = ddc_names.libraryUriToJsIdentifier(fileUri);
|
||||
// TODO(markzipan): This is an overly simple heuristic to resolve the
|
||||
// original Dart file. Replace this if it no longer holds.
|
||||
var dartFileName = fileName;
|
||||
if (dartFileName.endsWith('.lib.js')) {
|
||||
dartFileName =
|
||||
fileName.substring(0, fileName.length - '.lib.js'.length);
|
||||
dartFileName = fileName.substring(
|
||||
0,
|
||||
fileName.length - '.lib.js'.length,
|
||||
);
|
||||
}
|
||||
final fullyResolvedFileUri =
|
||||
jsRootUri.resolve('generation$generation/$fileName');
|
||||
final fullyResolvedFileUri = jsRootUri.resolve(
|
||||
'generation$generation/$fileName',
|
||||
);
|
||||
// This is a simple hack to resolve kernel library URIs from JS files.
|
||||
// This should be safe for hot reload tests but won't generalize.
|
||||
var libraryName = dartFileName;
|
||||
@@ -152,10 +165,11 @@ class HotReloadMemoryFilesystem implements FileResolver {
|
||||
libraryName = 'hot-reload-test:///$libraryName';
|
||||
}
|
||||
final libraryInfo = LibraryInfo(
|
||||
moduleName: moduleName,
|
||||
libraryName: libraryName,
|
||||
dartSourcePath: dartFileName,
|
||||
jsSourcePath: fullyResolvedFileUri.toFilePath());
|
||||
moduleName: moduleName,
|
||||
libraryName: libraryName,
|
||||
dartSourcePath: dartFileName,
|
||||
jsSourcePath: fullyResolvedFileUri.toFilePath(),
|
||||
);
|
||||
libraries.add(libraryInfo);
|
||||
if (generation == '0') {
|
||||
firstGenerationLibraries.add(libraryInfo);
|
||||
@@ -187,11 +201,12 @@ class LibraryInfo {
|
||||
final String dartSourcePath;
|
||||
final String jsSourcePath;
|
||||
|
||||
LibraryInfo(
|
||||
{required this.moduleName,
|
||||
required this.libraryName,
|
||||
required this.dartSourcePath,
|
||||
required this.jsSourcePath});
|
||||
LibraryInfo({
|
||||
required this.moduleName,
|
||||
required this.libraryName,
|
||||
required this.dartSourcePath,
|
||||
required this.jsSourcePath,
|
||||
});
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
|
||||
@@ -4,11 +4,7 @@
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
enum Status {
|
||||
accepted,
|
||||
rejected,
|
||||
restarted;
|
||||
}
|
||||
enum Status { accepted, rejected, restarted }
|
||||
|
||||
/// Reports the result of a hot reload or restart at runtime for test validation
|
||||
/// purposes only.
|
||||
@@ -35,9 +31,9 @@ class HotReloadReceipt {
|
||||
String toString() => jsonEncode(toJson());
|
||||
|
||||
HotReloadReceipt.fromJson(Map<String, dynamic> json)
|
||||
: generation = json[_generationKey] as int,
|
||||
status = Status.values.byName(json[_statusKey] as String),
|
||||
rejectionMessage = json[_rejectionMessageKey] as String?;
|
||||
: generation = json[_generationKey] as int,
|
||||
status = Status.values.byName(json[_statusKey] as String),
|
||||
rejectionMessage = json[_rejectionMessageKey] as String?;
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
|
||||
@@ -36,7 +36,8 @@ external _DartDevEmbedder get _dartDevEmbedder;
|
||||
|
||||
@JS('\$injectedFilesAndLibrariesToReload')
|
||||
external JSArray<JSArray<JSString>>? injectedFilesAndLibrariesToReload(
|
||||
JSNumber requestedFileGeneration);
|
||||
JSNumber requestedFileGeneration,
|
||||
);
|
||||
|
||||
@JS('\$dartLoader')
|
||||
external _DartLoader get _dartLoader;
|
||||
@@ -51,8 +52,10 @@ Future<void> hotRestart() async {
|
||||
generation: _ddcLoader.intendedHotRestartGeneration,
|
||||
status: Status.restarted,
|
||||
);
|
||||
print('${HotReloadReceipt.hotReloadReceiptTag}'
|
||||
'${jsonEncode(restartReceipt.toJson())}');
|
||||
print(
|
||||
'${HotReloadReceipt.hotReloadReceiptTag}'
|
||||
'${jsonEncode(restartReceipt.toJson())}',
|
||||
);
|
||||
await _dartDevEmbedder.hotRestart().toDart;
|
||||
}
|
||||
|
||||
@@ -68,24 +71,29 @@ int _hotReloadFileGeneration = 0;
|
||||
|
||||
Future<void> hotReload({bool expectRejection = false}) async {
|
||||
_hotReloadFileGeneration++;
|
||||
final generationFileInfo =
|
||||
injectedFilesAndLibrariesToReload(_hotReloadFileGeneration.toJS);
|
||||
final generationFileInfo = injectedFilesAndLibrariesToReload(
|
||||
_hotReloadFileGeneration.toJS,
|
||||
);
|
||||
final HotReloadReceipt reloadStatus = expectRejection
|
||||
? _rejectNextGeneration(generationFileInfo)
|
||||
: await _reloadNextGeneration(generationFileInfo);
|
||||
// Write reload receipt with a leading tag to be recognized by the reload
|
||||
// suite runner and validated.
|
||||
print('${HotReloadReceipt.hotReloadReceiptTag}'
|
||||
'${jsonEncode(reloadStatus.toJson())}');
|
||||
print(
|
||||
'${HotReloadReceipt.hotReloadReceiptTag}'
|
||||
'${jsonEncode(reloadStatus.toJson())}',
|
||||
);
|
||||
}
|
||||
|
||||
HotReloadReceipt _rejectNextGeneration(
|
||||
JSArray<JSArray<JSString>>? generationFileInfo) {
|
||||
JSArray<JSArray<JSString>>? generationFileInfo,
|
||||
) {
|
||||
if (generationFileInfo != null) {
|
||||
throw Exception(
|
||||
'Generation $_hotReloadFileGeneration was not rejected at compile '
|
||||
'time. Verify the calls of `hotReload(expectRejection: true)` in the '
|
||||
'test source match the rejected generation files.');
|
||||
'Generation $_hotReloadFileGeneration was not rejected at compile '
|
||||
'time. Verify the calls of `hotReload(expectRejection: true)` in the '
|
||||
'test source match the rejected generation files.',
|
||||
);
|
||||
}
|
||||
// This reload wasn't expected to find any files so this is OK.
|
||||
// * The correct reason for rejection was already validated at compile time
|
||||
@@ -100,16 +108,19 @@ HotReloadReceipt _rejectNextGeneration(
|
||||
}
|
||||
|
||||
Future<HotReloadReceipt> _reloadNextGeneration(
|
||||
JSArray<JSArray<JSString>>? generationFileInfo) async {
|
||||
JSArray<JSArray<JSString>>? generationFileInfo,
|
||||
) async {
|
||||
if (generationFileInfo == null) {
|
||||
throw Exception(
|
||||
'No compiled files found for generation $_hotReloadFileGeneration. '
|
||||
'Verify the calls of `hotReload()` in the test match the accepted '
|
||||
'generation source files.');
|
||||
'No compiled files found for generation $_hotReloadFileGeneration. '
|
||||
'Verify the calls of `hotReload()` in the test match the accepted '
|
||||
'generation source files.',
|
||||
);
|
||||
}
|
||||
await (_dartDevEmbedder.hotReload(
|
||||
generationFileInfo[0], generationFileInfo[1]))
|
||||
.toDart;
|
||||
generationFileInfo[0],
|
||||
generationFileInfo[1],
|
||||
)).toDart;
|
||||
return HotReloadReceipt(
|
||||
generation: _hotReloadFileGeneration,
|
||||
status: Status.accepted,
|
||||
|
||||
@@ -34,8 +34,10 @@ Future<void> hotReload({bool expectRejection = false}) async {
|
||||
}
|
||||
// Write reload receipt with a leading tag to be recognized by the reload
|
||||
// suite runner and validated.
|
||||
print('${HotReloadReceipt.hotReloadReceiptTag}'
|
||||
'${jsonEncode(reloadReceipt.toJson())}');
|
||||
print(
|
||||
'${HotReloadReceipt.hotReloadReceiptTag}'
|
||||
'${jsonEncode(reloadReceipt.toJson())}',
|
||||
);
|
||||
}
|
||||
|
||||
/// Helper to mediate with the vm service protocol.
|
||||
@@ -70,26 +72,37 @@ class HotReloadHelper {
|
||||
/// The current generation being executed by the VM.
|
||||
int generation = 0;
|
||||
|
||||
HotReloadHelper._(this._vmService, this._id, this.testOutputDirUri,
|
||||
this.dillName, this.errorDillName);
|
||||
HotReloadHelper._(
|
||||
this._vmService,
|
||||
this._id,
|
||||
this.testOutputDirUri,
|
||||
this.dillName,
|
||||
this.errorDillName,
|
||||
);
|
||||
|
||||
/// 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 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`.');
|
||||
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 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];
|
||||
@@ -102,7 +115,12 @@ class HotReloadHelper {
|
||||
final errorDillName = dillName.replaceAll('.dill', '.error.dill');
|
||||
|
||||
return HotReloadHelper._(
|
||||
vmService, id, dillUri.resolve('../'), dillName, errorDillName);
|
||||
vmService,
|
||||
id,
|
||||
dillUri.resolve('../'),
|
||||
dillName,
|
||||
errorDillName,
|
||||
);
|
||||
}
|
||||
|
||||
/// Trigger a hot-reload on the current isolate for the next generation.
|
||||
@@ -111,14 +129,19 @@ class HotReloadHelper {
|
||||
/// is disconnected to allow the VM to complete.
|
||||
Future<HotReloadReceipt> _reloadNextGeneration() async {
|
||||
generation += 1;
|
||||
final nextGenerationDillUri =
|
||||
testOutputDirUri.resolve('generation$generation/$dillName');
|
||||
final nextGenerationDillUri = testOutputDirUri.resolve(
|
||||
'generation$generation/$dillName',
|
||||
);
|
||||
print('Reloading: $nextGenerationDillUri');
|
||||
var reloadReport = await _vmService.reloadSources(_id,
|
||||
rootLibUri: nextGenerationDillUri.path);
|
||||
var reloadReport = await _vmService.reloadSources(
|
||||
_id,
|
||||
rootLibUri: nextGenerationDillUri.path,
|
||||
);
|
||||
if (!reloadReport.success!) {
|
||||
throw Exception('Reload for generation $generation was rejected.\n'
|
||||
'${reloadReport.reasonForCancelling}');
|
||||
throw Exception(
|
||||
'Reload for generation $generation was rejected.\n'
|
||||
'${reloadReport.reasonForCancelling}',
|
||||
);
|
||||
}
|
||||
var reloadReceipt = HotReloadReceipt(
|
||||
generation: generation,
|
||||
@@ -132,24 +155,31 @@ class HotReloadHelper {
|
||||
generation += 1;
|
||||
HotReloadReceipt reloadReceipt;
|
||||
final errorDillFile = io.File.fromUri(
|
||||
testOutputDirUri.resolve('generation$generation/$errorDillName'));
|
||||
testOutputDirUri.resolve('generation$generation/$errorDillName'),
|
||||
);
|
||||
if (errorDillFile.existsSync()) {
|
||||
// This generation contained a compile time error that has already been
|
||||
// validated and should be rejected.
|
||||
reloadReceipt = HotReloadReceipt(
|
||||
generation: generation,
|
||||
status: Status.rejected,
|
||||
rejectionMessage: HotReloadReceipt.compileTimeErrorMessage);
|
||||
generation: generation,
|
||||
status: Status.rejected,
|
||||
rejectionMessage: HotReloadReceipt.compileTimeErrorMessage,
|
||||
);
|
||||
} else {
|
||||
final nextGenerationDillUri =
|
||||
testOutputDirUri.resolve('generation$generation/$dillName');
|
||||
final nextGenerationDillUri = testOutputDirUri.resolve(
|
||||
'generation$generation/$dillName',
|
||||
);
|
||||
print('Reloading (expecting rejection): $nextGenerationDillUri');
|
||||
final reloadReport = await _vmService.reloadSources(_id,
|
||||
rootLibUri: nextGenerationDillUri.path);
|
||||
final reloadReport = await _vmService.reloadSources(
|
||||
_id,
|
||||
rootLibUri: nextGenerationDillUri.path,
|
||||
);
|
||||
if (reloadReport.success!) {
|
||||
throw Exception('Generation $generation was not rejected. Verify the '
|
||||
'calls of `hotReload(expectRejection: true)` in the test source '
|
||||
'match the rejected generation files.');
|
||||
throw Exception(
|
||||
'Generation $generation was not rejected. Verify the '
|
||||
'calls of `hotReload(expectRejection: true)` in the test source '
|
||||
'match the rejected generation files.',
|
||||
);
|
||||
}
|
||||
reloadReceipt = HotReloadReceipt(
|
||||
generation: generation,
|
||||
@@ -162,8 +192,9 @@ class HotReloadHelper {
|
||||
}
|
||||
|
||||
bool get hasNextGeneration {
|
||||
final nextNextGenerationDirUri =
|
||||
testOutputDirUri.resolve('generation${generation + 1}');
|
||||
final nextNextGenerationDirUri = testOutputDirUri.resolve(
|
||||
'generation${generation + 1}',
|
||||
);
|
||||
return io.Directory.fromUri(nextNextGenerationDirUri).existsSync();
|
||||
}
|
||||
|
||||
|
||||
@@ -25,22 +25,22 @@ class TestResultOutcome {
|
||||
});
|
||||
|
||||
String toRecordJson() => _encoder.convert({
|
||||
'name': '$suiteName/$testName',
|
||||
'configuration': configuration,
|
||||
'suite': suiteName,
|
||||
'test_name': testName,
|
||||
'time_ms': elapsedTime.inMilliseconds,
|
||||
'expected': expectedResult,
|
||||
'result': matchedExpectations ? 'Pass' : 'Fail',
|
||||
'matches': matchedExpectations,
|
||||
});
|
||||
'name': '$suiteName/$testName',
|
||||
'configuration': configuration,
|
||||
'suite': suiteName,
|
||||
'test_name': testName,
|
||||
'time_ms': elapsedTime.inMilliseconds,
|
||||
'expected': expectedResult,
|
||||
'result': matchedExpectations ? 'Pass' : 'Fail',
|
||||
'matches': matchedExpectations,
|
||||
});
|
||||
|
||||
String toLogJson() => _encoder.convert({
|
||||
'name': '$suiteName/$testName',
|
||||
'configuration': configuration,
|
||||
'result': matchedExpectations ? 'Pass' : 'Fail',
|
||||
'log': testOutput,
|
||||
});
|
||||
'name': '$suiteName/$testName',
|
||||
'configuration': configuration,
|
||||
'result': matchedExpectations ? 'Pass' : 'Fail',
|
||||
'log': testOutput,
|
||||
});
|
||||
}
|
||||
|
||||
/// Escapes backslashes in [unescaped].
|
||||
@@ -83,11 +83,14 @@ class ReloadTestConfiguration {
|
||||
ReloadTestConfiguration._(this.excludedPlatforms, this.expectedErrors);
|
||||
|
||||
factory ReloadTestConfiguration() => ReloadTestConfiguration._(
|
||||
const <RuntimePlatforms>{}, const <int, String>{});
|
||||
const <RuntimePlatforms>{},
|
||||
const <int, String>{},
|
||||
);
|
||||
|
||||
factory ReloadTestConfiguration.fromJsonFile(Uri file) {
|
||||
final Map<String, dynamic> jsonData =
|
||||
jsonDecode(File.fromUri(file).readAsStringSync());
|
||||
final Map<String, dynamic> jsonData = jsonDecode(
|
||||
File.fromUri(file).readAsStringSync(),
|
||||
);
|
||||
final excludedPlatforms = <RuntimePlatforms>{};
|
||||
final rawExcludedPlatforms = jsonData['exclude'];
|
||||
if (rawExcludedPlatforms != null) {
|
||||
@@ -104,9 +107,6 @@ class ReloadTestConfiguration {
|
||||
expectedErrors[int.parse(entry.key)] = entry.value as String;
|
||||
}
|
||||
}
|
||||
return ReloadTestConfiguration._(
|
||||
excludedPlatforms,
|
||||
expectedErrors,
|
||||
);
|
||||
return ReloadTestConfiguration._(excludedPlatforms, expectedErrors);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,8 @@ void main() {
|
||||
final sourcemapFile = File.fromUri(testDirectory.uri.resolve('test.map'))
|
||||
..writeAsBytesSync(sourcemap);
|
||||
|
||||
final manifest = '''
|
||||
final manifest =
|
||||
'''
|
||||
{
|
||||
"/file1.ext": {
|
||||
"code": [0, ${source1.codeUnits.length}],
|
||||
@@ -61,50 +62,59 @@ void main() {
|
||||
}
|
||||
}
|
||||
'''
|
||||
.codeUnits;
|
||||
.codeUnits;
|
||||
final manifestFile = File.fromUri(testDirectory.uri.resolve('test.json'))
|
||||
..writeAsBytesSync(manifest);
|
||||
|
||||
var updatedFiles = filesystem
|
||||
.update(sourcesFile, manifestFile, sourcemapFile, generation: "0");
|
||||
|
||||
expect(updatedFiles, equals(['file1.ext', 'file2.ext']),
|
||||
reason: 'Updated files are correctly reported.');
|
||||
var updatedFiles = filesystem.update(
|
||||
sourcesFile,
|
||||
manifestFile,
|
||||
sourcemapFile,
|
||||
generation: "0",
|
||||
);
|
||||
|
||||
expect(
|
||||
filesystem.files,
|
||||
equals(
|
||||
{'file1.ext': source1.codeUnits, 'file2.ext': source2.codeUnits}),
|
||||
reason: 'Filesystem source files are correctly stored.');
|
||||
updatedFiles,
|
||||
equals(['file1.ext', 'file2.ext']),
|
||||
reason: 'Updated files are correctly reported.',
|
||||
);
|
||||
|
||||
expect(
|
||||
filesystem.sourcemaps,
|
||||
equals({
|
||||
'file1.ext.map': sourcemap1.codeUnits,
|
||||
'file2.ext.map': sourcemap2.codeUnits,
|
||||
}),
|
||||
reason: 'Filesystem sourcemaps are correctly stored.');
|
||||
filesystem.files,
|
||||
equals({'file1.ext': source1.codeUnits, 'file2.ext': source2.codeUnits}),
|
||||
reason: 'Filesystem source files are correctly stored.',
|
||||
);
|
||||
|
||||
expect(
|
||||
filesystem.generationsToModifiedFilePaths,
|
||||
equals({
|
||||
'0': [
|
||||
[
|
||||
'hot-reload-test:///file1.ext',
|
||||
jsOutputUri.resolve('generation0/file1.ext').toFilePath()
|
||||
],
|
||||
[
|
||||
'hot-reload-test:///file2.ext',
|
||||
jsOutputUri.resolve('generation0/file2.ext').toFilePath()
|
||||
]
|
||||
]
|
||||
}),
|
||||
reason:
|
||||
'Filesystem emits correct generation to modfied files mapping.');
|
||||
filesystem.sourcemaps,
|
||||
equals({
|
||||
'file1.ext.map': sourcemap1.codeUnits,
|
||||
'file2.ext.map': sourcemap2.codeUnits,
|
||||
}),
|
||||
reason: 'Filesystem sourcemaps are correctly stored.',
|
||||
);
|
||||
|
||||
expect(
|
||||
filesystem.generationsToModifiedFilePaths,
|
||||
equals({
|
||||
'0': [
|
||||
[
|
||||
'hot-reload-test:///file1.ext',
|
||||
jsOutputUri.resolve('generation0/file1.ext').toFilePath(),
|
||||
],
|
||||
[
|
||||
'hot-reload-test:///file2.ext',
|
||||
jsOutputUri.resolve('generation0/file2.ext').toFilePath(),
|
||||
],
|
||||
],
|
||||
}),
|
||||
reason: 'Filesystem emits correct generation to modfied files mapping.',
|
||||
);
|
||||
|
||||
// Update the filesystem with two more files in the next generation.
|
||||
|
||||
final manifest2 = '''
|
||||
final manifest2 =
|
||||
'''
|
||||
{
|
||||
"/file3.ext": {
|
||||
"code": [0, ${source1.codeUnits.length}],
|
||||
@@ -122,140 +132,184 @@ void main() {
|
||||
}
|
||||
}
|
||||
'''
|
||||
.codeUnits;
|
||||
.codeUnits;
|
||||
manifestFile.writeAsBytesSync(manifest2);
|
||||
|
||||
updatedFiles = filesystem.update(sourcesFile, manifestFile, sourcemapFile,
|
||||
generation: "1");
|
||||
|
||||
expect(updatedFiles, equals(['file3.ext', 'file4.ext']),
|
||||
reason: 'Updated files are correctly reported.');
|
||||
updatedFiles = filesystem.update(
|
||||
sourcesFile,
|
||||
manifestFile,
|
||||
sourcemapFile,
|
||||
generation: "1",
|
||||
);
|
||||
|
||||
expect(
|
||||
filesystem.files,
|
||||
equals({
|
||||
'file1.ext': source1.codeUnits,
|
||||
'file2.ext': source2.codeUnits,
|
||||
'file3.ext': source1.codeUnits,
|
||||
'file4.ext': source2.codeUnits,
|
||||
}),
|
||||
reason: 'Filesystem source files are correctly stored.');
|
||||
updatedFiles,
|
||||
equals(['file3.ext', 'file4.ext']),
|
||||
reason: 'Updated files are correctly reported.',
|
||||
);
|
||||
|
||||
expect(
|
||||
filesystem.sourcemaps,
|
||||
equals({
|
||||
'file1.ext.map': sourcemap1.codeUnits,
|
||||
'file2.ext.map': sourcemap2.codeUnits,
|
||||
'file3.ext.map': sourcemap1.codeUnits,
|
||||
'file4.ext.map': sourcemap2.codeUnits,
|
||||
}),
|
||||
reason: 'Filesystem sourcemaps are correctly stored.');
|
||||
filesystem.files,
|
||||
equals({
|
||||
'file1.ext': source1.codeUnits,
|
||||
'file2.ext': source2.codeUnits,
|
||||
'file3.ext': source1.codeUnits,
|
||||
'file4.ext': source2.codeUnits,
|
||||
}),
|
||||
reason: 'Filesystem source files are correctly stored.',
|
||||
);
|
||||
|
||||
expect(
|
||||
filesystem.generationsToModifiedFilePaths,
|
||||
equals({
|
||||
'0': [
|
||||
[
|
||||
'hot-reload-test:///file1.ext',
|
||||
jsOutputUri.resolve('generation0/file1.ext').toFilePath()
|
||||
],
|
||||
[
|
||||
'hot-reload-test:///file2.ext',
|
||||
jsOutputUri.resolve('generation0/file2.ext').toFilePath()
|
||||
]
|
||||
filesystem.sourcemaps,
|
||||
equals({
|
||||
'file1.ext.map': sourcemap1.codeUnits,
|
||||
'file2.ext.map': sourcemap2.codeUnits,
|
||||
'file3.ext.map': sourcemap1.codeUnits,
|
||||
'file4.ext.map': sourcemap2.codeUnits,
|
||||
}),
|
||||
reason: 'Filesystem sourcemaps are correctly stored.',
|
||||
);
|
||||
|
||||
expect(
|
||||
filesystem.generationsToModifiedFilePaths,
|
||||
equals({
|
||||
'0': [
|
||||
[
|
||||
'hot-reload-test:///file1.ext',
|
||||
jsOutputUri.resolve('generation0/file1.ext').toFilePath(),
|
||||
],
|
||||
'1': [
|
||||
[
|
||||
'hot-reload-test:///file3.ext',
|
||||
jsOutputUri.resolve('generation1/file3.ext').toFilePath()
|
||||
],
|
||||
[
|
||||
'hot-reload-test:///file4.ext',
|
||||
jsOutputUri.resolve('generation1/file4.ext').toFilePath()
|
||||
],
|
||||
[
|
||||
'hot-reload-test:///file2.ext',
|
||||
jsOutputUri.resolve('generation0/file2.ext').toFilePath(),
|
||||
],
|
||||
}),
|
||||
reason:
|
||||
'Filesystem emits correct generation to modfied files mapping.');
|
||||
],
|
||||
'1': [
|
||||
[
|
||||
'hot-reload-test:///file3.ext',
|
||||
jsOutputUri.resolve('generation1/file3.ext').toFilePath(),
|
||||
],
|
||||
[
|
||||
'hot-reload-test:///file4.ext',
|
||||
jsOutputUri.resolve('generation1/file4.ext').toFilePath(),
|
||||
],
|
||||
],
|
||||
}),
|
||||
reason: 'Filesystem emits correct generation to modfied files mapping.',
|
||||
);
|
||||
|
||||
expect(
|
||||
filesystem.scriptDescriptorForBootstrap,
|
||||
equals([
|
||||
{
|
||||
'id': 'hot-reload-test:///file1.ext',
|
||||
'src': jsOutputUri.resolve('generation0/file1.ext').toFilePath(),
|
||||
},
|
||||
{
|
||||
'id': 'hot-reload-test:///file2.ext',
|
||||
'src': jsOutputUri.resolve('generation0/file2.ext').toFilePath(),
|
||||
},
|
||||
]),
|
||||
reason: 'Filesystem emits correct script descriptors.');
|
||||
filesystem.scriptDescriptorForBootstrap,
|
||||
equals([
|
||||
{
|
||||
'id': 'hot-reload-test:///file1.ext',
|
||||
'src': jsOutputUri.resolve('generation0/file1.ext').toFilePath(),
|
||||
},
|
||||
{
|
||||
'id': 'hot-reload-test:///file2.ext',
|
||||
'src': jsOutputUri.resolve('generation0/file2.ext').toFilePath(),
|
||||
},
|
||||
]),
|
||||
reason: 'Filesystem emits correct script descriptors.',
|
||||
);
|
||||
|
||||
// Write files and check that the filesystem's state is properly cleared.
|
||||
expect(
|
||||
File(jsOutputUri.resolve('generation3/file1.ext').toFilePath())
|
||||
.existsSync(),
|
||||
isFalse);
|
||||
File(
|
||||
jsOutputUri.resolve('generation3/file1.ext').toFilePath(),
|
||||
).existsSync(),
|
||||
isFalse,
|
||||
);
|
||||
expect(
|
||||
File(jsOutputUri.resolve('generation3/file2.ext').toFilePath())
|
||||
.existsSync(),
|
||||
isFalse);
|
||||
File(
|
||||
jsOutputUri.resolve('generation3/file2.ext').toFilePath(),
|
||||
).existsSync(),
|
||||
isFalse,
|
||||
);
|
||||
expect(
|
||||
File(jsOutputUri.resolve('generation3/file3.ext').toFilePath())
|
||||
.existsSync(),
|
||||
isFalse);
|
||||
File(
|
||||
jsOutputUri.resolve('generation3/file3.ext').toFilePath(),
|
||||
).existsSync(),
|
||||
isFalse,
|
||||
);
|
||||
expect(
|
||||
File(jsOutputUri.resolve('generation3/file4.ext').toFilePath())
|
||||
.existsSync(),
|
||||
isFalse);
|
||||
File(
|
||||
jsOutputUri.resolve('generation3/file4.ext').toFilePath(),
|
||||
).existsSync(),
|
||||
isFalse,
|
||||
);
|
||||
filesystem.writeToDisk(jsOutputUri, generation: "3");
|
||||
expect(
|
||||
File(jsOutputUri.resolve('generation3/file1.ext').toFilePath())
|
||||
.existsSync(),
|
||||
isTrue);
|
||||
File(
|
||||
jsOutputUri.resolve('generation3/file1.ext').toFilePath(),
|
||||
).existsSync(),
|
||||
isTrue,
|
||||
);
|
||||
expect(
|
||||
File(jsOutputUri.resolve('generation3/file2.ext').toFilePath())
|
||||
.existsSync(),
|
||||
isTrue);
|
||||
File(
|
||||
jsOutputUri.resolve('generation3/file2.ext').toFilePath(),
|
||||
).existsSync(),
|
||||
isTrue,
|
||||
);
|
||||
expect(
|
||||
File(jsOutputUri.resolve('generation3/file3.ext').toFilePath())
|
||||
.existsSync(),
|
||||
isTrue);
|
||||
File(
|
||||
jsOutputUri.resolve('generation3/file3.ext').toFilePath(),
|
||||
).existsSync(),
|
||||
isTrue,
|
||||
);
|
||||
expect(
|
||||
File(jsOutputUri.resolve('generation3/file4.ext').toFilePath())
|
||||
.existsSync(),
|
||||
isTrue);
|
||||
expect(filesystem.files, isEmpty,
|
||||
reason: 'Filesystem clears files after writing to disk.');
|
||||
expect(filesystem.sourcemaps, isEmpty,
|
||||
reason: 'Filesystem clears sourcemaps after writing to disk.');
|
||||
File(
|
||||
jsOutputUri.resolve('generation3/file4.ext').toFilePath(),
|
||||
).existsSync(),
|
||||
isTrue,
|
||||
);
|
||||
expect(
|
||||
filesystem.files,
|
||||
isEmpty,
|
||||
reason: 'Filesystem clears files after writing to disk.',
|
||||
);
|
||||
expect(
|
||||
filesystem.sourcemaps,
|
||||
isEmpty,
|
||||
reason: 'Filesystem clears sourcemaps after writing to disk.',
|
||||
);
|
||||
|
||||
// Check that subsequent writes don't emit already-emitted files.
|
||||
File(jsOutputUri.resolve('generation3/file1.ext').toFilePath())
|
||||
.deleteSync();
|
||||
File(jsOutputUri.resolve('generation3/file2.ext').toFilePath())
|
||||
.deleteSync();
|
||||
File(jsOutputUri.resolve('generation3/file3.ext').toFilePath())
|
||||
.deleteSync();
|
||||
File(jsOutputUri.resolve('generation3/file4.ext').toFilePath())
|
||||
.deleteSync();
|
||||
File(
|
||||
jsOutputUri.resolve('generation3/file1.ext').toFilePath(),
|
||||
).deleteSync();
|
||||
File(
|
||||
jsOutputUri.resolve('generation3/file2.ext').toFilePath(),
|
||||
).deleteSync();
|
||||
File(
|
||||
jsOutputUri.resolve('generation3/file3.ext').toFilePath(),
|
||||
).deleteSync();
|
||||
File(
|
||||
jsOutputUri.resolve('generation3/file4.ext').toFilePath(),
|
||||
).deleteSync();
|
||||
filesystem.writeToDisk(jsOutputUri, generation: "3");
|
||||
expect(
|
||||
File(jsOutputUri.resolve('generation3/file1.ext').toFilePath())
|
||||
.existsSync(),
|
||||
isFalse);
|
||||
File(
|
||||
jsOutputUri.resolve('generation3/file1.ext').toFilePath(),
|
||||
).existsSync(),
|
||||
isFalse,
|
||||
);
|
||||
expect(
|
||||
File(jsOutputUri.resolve('generation3/file2.ext').toFilePath())
|
||||
.existsSync(),
|
||||
isFalse);
|
||||
File(
|
||||
jsOutputUri.resolve('generation3/file2.ext').toFilePath(),
|
||||
).existsSync(),
|
||||
isFalse,
|
||||
);
|
||||
expect(
|
||||
File(jsOutputUri.resolve('generation3/file3.ext').toFilePath())
|
||||
.existsSync(),
|
||||
isFalse);
|
||||
File(
|
||||
jsOutputUri.resolve('generation3/file3.ext').toFilePath(),
|
||||
).existsSync(),
|
||||
isFalse,
|
||||
);
|
||||
expect(
|
||||
File(jsOutputUri.resolve('generation3/file4.ext').toFilePath())
|
||||
.existsSync(),
|
||||
isFalse);
|
||||
File(
|
||||
jsOutputUri.resolve('generation3/file4.ext').toFilePath(),
|
||||
).existsSync(),
|
||||
isFalse,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user