From e2fafb4bda9a6fb5be5fe473d027201d26c3b94c Mon Sep 17 00:00:00 2001 From: Jake Macdonald Date: Tue, 9 Jan 2024 20:55:05 +0000 Subject: [PATCH 1/2] fix a bug where test html files were not created in precompiled mode --- pkgs/test/CHANGELOG.md | 5 ++- .../browser/compilers/compiler_support.dart | 37 ++++++++++++++++++- .../src/runner/browser/compilers/dart2js.dart | 35 ++---------------- .../runner/browser/compilers/dart2wasm.dart | 21 +++++------ .../runner/browser/compilers/precompiled.dart | 21 +++++++---- .../test/lib/src/runner/browser/platform.dart | 2 + pkgs/test/pubspec.yaml | 2 +- 7 files changed, 68 insertions(+), 55 deletions(-) diff --git a/pkgs/test/CHANGELOG.md b/pkgs/test/CHANGELOG.md index 8940bd9b5..463c28b79 100644 --- a/pkgs/test/CHANGELOG.md +++ b/pkgs/test/CHANGELOG.md @@ -1,4 +1,7 @@ -## 1.25.1-wip +## 1.25.1 + +* Fix a bug where in precompiled mode, html files for tests were no longer + created. ## 1.25.0 diff --git a/pkgs/test/lib/src/runner/browser/compilers/compiler_support.dart b/pkgs/test/lib/src/runner/browser/compilers/compiler_support.dart index 4501e55e4..127142906 100644 --- a/pkgs/test/lib/src/runner/browser/compilers/compiler_support.dart +++ b/pkgs/test/lib/src/runner/browser/compilers/compiler_support.dart @@ -3,13 +3,26 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; +import 'package:path/path.dart' as p; +import 'package:shelf/shelf.dart' as shelf; import 'package:test_api/backend.dart' show StackTraceMapper, SuitePlatform; +import 'package:test_core/src/runner/configuration.dart'; // ignore: implementation_imports import 'package:test_core/src/runner/suite.dart'; // ignore: implementation_imports import 'package:web_socket_channel/web_socket_channel.dart'; // ignore: implementation_imports /// The shared interface for all compiler support libraries. -abstract interface class CompilerSupport { +abstract class CompilerSupport { + /// The global test runner configuration. + final Configuration config; + + /// The default template path. + final String defaultTemplatePath; + + CompilerSupport(this.config, this.defaultTemplatePath); + /// The URL at which this compiler serves its tests. /// /// Each compiler serves its tests under a different directory. @@ -34,4 +47,26 @@ abstract interface class CompilerSupport { /// Closes down anything necessary for this implementation. Future close(); + + /// A handler that serves html wrapper files used to bootstrap tests. + shelf.Response htmlWrapperHandler(shelf.Request request) { + var path = p.fromUri(request.url); + + if (path.endsWith('.html')) { + var test = p.setExtension(path, '.dart'); + var scriptBase = htmlEscape.convert(p.basename(test)); + var link = ''; + var testName = htmlEscape.convert(test); + var template = config.customHtmlTemplatePath ?? defaultTemplatePath; + var contents = File(template).readAsStringSync(); + var processedContents = contents + // Checked during loading phase that there is only one {{testScript}} placeholder. + .replaceFirst('{{testScript}}', link) + .replaceAll('{{testName}}', testName); + return shelf.Response.ok(processedContents, + headers: {'Content-Type': 'text/html'}); + } + + return shelf.Response.notFound('Not found.'); + } } diff --git a/pkgs/test/lib/src/runner/browser/compilers/dart2js.dart b/pkgs/test/lib/src/runner/browser/compilers/dart2js.dart index 5aa086149..b75e6eb7c 100644 --- a/pkgs/test/lib/src/runner/browser/compilers/dart2js.dart +++ b/pkgs/test/lib/src/runner/browser/compilers/dart2js.dart @@ -3,7 +3,6 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; -import 'dart:convert'; import 'dart:io'; import 'package:http_multi_server/http_multi_server.dart'; @@ -30,7 +29,7 @@ import '../../../util/path_handler.dart'; import 'compiler_support.dart'; /// Support for Dart2Js compiled tests. -class Dart2JsSupport implements CompilerSupport { +class Dart2JsSupport extends CompilerSupport { /// Whether [close] has been called. bool _closed = false; @@ -47,12 +46,6 @@ class Dart2JsSupport implements CompilerSupport { /// The [Dart2JsCompilerPool] managing active instances of `dart2js`. final _compilerPool = Dart2JsCompilerPool(); - /// The global test runner configuration. - final Configuration _config; - - /// The default template path. - final String _defaultTemplatePath; - /// Mappers for Dartifying stack traces, indexed by test path. final _mappers = {}; @@ -81,14 +74,14 @@ class Dart2JsSupport implements CompilerSupport { @override Uri get serverUrl => _server.url.resolve('$_secret/'); - Dart2JsSupport._(this._config, this._defaultTemplatePath, this._server, + Dart2JsSupport._(super.config, super.defaultTemplatePath, this._server, this._root, String faviconPath) { var cascade = shelf.Cascade() .add(_webSocketHandler.handler) .add(packagesDirHandler()) .add(_pathHandler.handler) .add(createStaticHandler(_root)) - .add(_wrapperHandler); + .add(htmlWrapperHandler); var pipeline = const shelf.Pipeline() .addMiddleware(PathHandler.nestedIn(_secret)) @@ -111,28 +104,6 @@ class Dart2JsSupport implements CompilerSupport { config, defaultTemplatePath, server, root, faviconPath); } - /// A handler that serves wrapper files used to bootstrap tests. - shelf.Response _wrapperHandler(shelf.Request request) { - var path = p.fromUri(request.url); - - if (path.endsWith('.html')) { - var test = p.setExtension(path, '.dart'); - var scriptBase = htmlEscape.convert(p.basename(test)); - var link = ''; - var testName = htmlEscape.convert(test); - var template = _config.customHtmlTemplatePath ?? _defaultTemplatePath; - var contents = File(template).readAsStringSync(); - var processedContents = contents - // Checked during loading phase that there is only one {{testScript}} placeholder. - .replaceFirst('{{testScript}}', link) - .replaceAll('{{testName}}', testName); - return shelf.Response.ok(processedContents, - headers: {'Content-Type': 'text/html'}); - } - - return shelf.Response.notFound('Not found.'); - } - @override Future compileSuite( String dartPath, SuiteConfiguration suiteConfig, SuitePlatform platform) { diff --git a/pkgs/test/lib/src/runner/browser/compilers/dart2wasm.dart b/pkgs/test/lib/src/runner/browser/compilers/dart2wasm.dart index 94a9d2048..621ba7d9d 100644 --- a/pkgs/test/lib/src/runner/browser/compilers/dart2wasm.dart +++ b/pkgs/test/lib/src/runner/browser/compilers/dart2wasm.dart @@ -29,7 +29,7 @@ import '../browser_manager.dart'; import 'compiler_support.dart'; /// Support for Dart2Wasm compiled tests. -class Dart2WasmSupport implements CompilerSupport { +class Dart2WasmSupport extends CompilerSupport { /// Whether [close] has been called. bool _closed = false; @@ -46,12 +46,6 @@ class Dart2WasmSupport implements CompilerSupport { /// The [WasmCompilerPool] managing active instances of `dart2wasm`. final _compilerPool = WasmCompilerPool(); - /// The global test runner configuration. - final Configuration _config; - - /// The default template path. - final String _defaultTemplatePath; - /// The `package:test` side wrapper for the Dart2Wasm runtime. final String _jsRuntimeWrapper; @@ -83,14 +77,14 @@ class Dart2WasmSupport implements CompilerSupport { @override Uri get serverUrl => _server.url.resolve('$_secret/'); - Dart2WasmSupport._(this._config, this._defaultTemplatePath, + Dart2WasmSupport._(super.config, super.defaultTemplatePath, this._jsRuntimeWrapper, this._server, this._root, String faviconPath) { var cascade = shelf.Cascade() .add(_webSocketHandler.handler) .add(packagesDirHandler()) .add(_pathHandler.handler) .add(createStaticHandler(_root)) - .add(_wrapperHandler); + .add(htmlWrapperHandler); var pipeline = const shelf.Pipeline() .addMiddleware(PathHandler.nestedIn(_secret)) @@ -114,8 +108,11 @@ class Dart2WasmSupport implements CompilerSupport { server, root, faviconPath); } - /// A handler that serves wrapper files used to bootstrap tests. - shelf.Response _wrapperHandler(shelf.Request request) { + /// A handler that serves wrapper html files used to bootstrap tests. + /// + /// This is slightly different from normal tests. + @override + shelf.Response htmlWrapperHandler(shelf.Request request) { var path = p.fromUri(request.url); if (path.endsWith('.html')) { @@ -123,7 +120,7 @@ class Dart2WasmSupport implements CompilerSupport { var scriptBase = htmlEscape.convert(p.basename(test)); var link = ''; var testName = htmlEscape.convert(test); - var template = _config.customHtmlTemplatePath ?? _defaultTemplatePath; + var template = config.customHtmlTemplatePath ?? defaultTemplatePath; var contents = File(template).readAsStringSync(); var jsRuntime = p.basename('$test.browser_test.dart.mjs'); var wasmData = '{}; - /// A [PathHandler] used to serve test specific artifacts. - final _pathHandler = PathHandler(); - /// The root directory served statically by the server. final String _root; @@ -60,12 +58,16 @@ class PrecompiledSupport implements CompilerSupport { @override Uri get serverUrl => _server.url.resolve('$_secret/'); - PrecompiledSupport._(this._server, this._root, String faviconPath) { + PrecompiledSupport._(super.config, super.defaultTemplatePath, this._server, + this._root, String faviconPath) { var cascade = shelf.Cascade() .add(_webSocketHandler.handler) + .add(createStaticHandler(_root, serveFilesOutsidePath: true)) + // TODO: This packages dir handler should not be necessary? .add(packagesDirHandler()) - .add(_pathHandler.handler) - .add(createStaticHandler(_root)); + // Even for precompiled tests, we will auto-create a bootstrap html file + // if none was present. + .add(htmlWrapperHandler); var pipeline = const shelf.Pipeline() .addMiddleware(PathHandler.nestedIn(_secret)) @@ -78,11 +80,14 @@ class PrecompiledSupport implements CompilerSupport { } static Future start({ + required Configuration config, + required String defaultTemplatePath, required String root, required String faviconPath, }) async { var server = shelf_io.IOServer(await HttpMultiServer.loopback(0)); - return PrecompiledSupport._(server, root, faviconPath); + return PrecompiledSupport._( + config, defaultTemplatePath, server, root, faviconPath); } /// Compiles [dartPath] using [suiteConfig] for [platform]. diff --git a/pkgs/test/lib/src/runner/browser/platform.dart b/pkgs/test/lib/src/runner/browser/platform.dart index 205df4474..93661939b 100644 --- a/pkgs/test/lib/src/runner/browser/platform.dart +++ b/pkgs/test/lib/src/runner/browser/platform.dart @@ -63,6 +63,8 @@ class BrowserPlatform extends PlatformPlugin _compilerSupport.putIfAbsent(compiler, () { if (_config.suiteDefaults.precompiledPath != null) { return PrecompiledSupport.start( + config: _config, + defaultTemplatePath: _defaultTemplatePath, root: _config.suiteDefaults.precompiledPath!, faviconPath: _faviconPath); } diff --git a/pkgs/test/pubspec.yaml b/pkgs/test/pubspec.yaml index 0a95dfaaf..dd05394a2 100644 --- a/pkgs/test/pubspec.yaml +++ b/pkgs/test/pubspec.yaml @@ -1,5 +1,5 @@ name: test -version: 1.25.1-wip +version: 1.25.1 description: >- A full featured library for writing and running Dart tests across platforms. repository: https://github.com/dart-lang/test/tree/master/pkgs/test From 51ebb1114c285f0dbac74833e7666eb0db5af819 Mon Sep 17 00:00:00 2001 From: Jake Macdonald Date: Wed, 10 Jan 2024 19:06:39 +0000 Subject: [PATCH 2/2] support wasm and js precompiled tests --- .../browser/compilers/compiler_support.dart | 33 +++++++++++++++++++ .../src/runner/browser/compilers/dart2js.dart | 2 +- .../runner/browser/compilers/dart2wasm.dart | 32 +----------------- .../runner/browser/compilers/precompiled.dart | 23 ++++++++++--- .../test/lib/src/runner/browser/platform.dart | 1 + 5 files changed, 55 insertions(+), 36 deletions(-) diff --git a/pkgs/test/lib/src/runner/browser/compilers/compiler_support.dart b/pkgs/test/lib/src/runner/browser/compilers/compiler_support.dart index 127142906..4fa1b88a9 100644 --- a/pkgs/test/lib/src/runner/browser/compilers/compiler_support.dart +++ b/pkgs/test/lib/src/runner/browser/compilers/compiler_support.dart @@ -49,6 +49,11 @@ abstract class CompilerSupport { Future close(); /// A handler that serves html wrapper files used to bootstrap tests. + shelf.Response htmlWrapperHandler(shelf.Request request); +} + +mixin JsHtmlWrapper on CompilerSupport { + @override shelf.Response htmlWrapperHandler(shelf.Request request) { var path = p.fromUri(request.url); @@ -70,3 +75,31 @@ abstract class CompilerSupport { return shelf.Response.notFound('Not found.'); } } + +mixin WasmHtmlWrapper on CompilerSupport { + @override + shelf.Response htmlWrapperHandler(shelf.Request request) { + var path = p.fromUri(request.url); + + if (path.endsWith('.html')) { + var test = '${p.withoutExtension(path)}.dart'; + var scriptBase = htmlEscape.convert(p.basename(test)); + var link = ''; + var testName = htmlEscape.convert(test); + var template = config.customHtmlTemplatePath ?? defaultTemplatePath; + var contents = File(template).readAsStringSync(); + var jsRuntime = p.basename('$test.browser_test.dart.mjs'); + var wasmData = ''; + var processedContents = contents + // Checked during loading phase that there is only one {{testScript}} placeholder. + .replaceFirst('{{testScript}}', '$link\n$wasmData') + .replaceAll('{{testName}}', testName); + return shelf.Response.ok(processedContents, + headers: {'Content-Type': 'text/html'}); + } + + return shelf.Response.notFound('Not found.'); + } +} diff --git a/pkgs/test/lib/src/runner/browser/compilers/dart2js.dart b/pkgs/test/lib/src/runner/browser/compilers/dart2js.dart index b75e6eb7c..6794c645e 100644 --- a/pkgs/test/lib/src/runner/browser/compilers/dart2js.dart +++ b/pkgs/test/lib/src/runner/browser/compilers/dart2js.dart @@ -29,7 +29,7 @@ import '../../../util/path_handler.dart'; import 'compiler_support.dart'; /// Support for Dart2Js compiled tests. -class Dart2JsSupport extends CompilerSupport { +class Dart2JsSupport extends CompilerSupport with JsHtmlWrapper { /// Whether [close] has been called. bool _closed = false; diff --git a/pkgs/test/lib/src/runner/browser/compilers/dart2wasm.dart b/pkgs/test/lib/src/runner/browser/compilers/dart2wasm.dart index 621ba7d9d..697a9c50b 100644 --- a/pkgs/test/lib/src/runner/browser/compilers/dart2wasm.dart +++ b/pkgs/test/lib/src/runner/browser/compilers/dart2wasm.dart @@ -3,7 +3,6 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; -import 'dart:convert'; import 'dart:io'; import 'package:http_multi_server/http_multi_server.dart'; @@ -29,7 +28,7 @@ import '../browser_manager.dart'; import 'compiler_support.dart'; /// Support for Dart2Wasm compiled tests. -class Dart2WasmSupport extends CompilerSupport { +class Dart2WasmSupport extends CompilerSupport with WasmHtmlWrapper { /// Whether [close] has been called. bool _closed = false; @@ -108,35 +107,6 @@ class Dart2WasmSupport extends CompilerSupport { server, root, faviconPath); } - /// A handler that serves wrapper html files used to bootstrap tests. - /// - /// This is slightly different from normal tests. - @override - shelf.Response htmlWrapperHandler(shelf.Request request) { - var path = p.fromUri(request.url); - - if (path.endsWith('.html')) { - var test = '${p.withoutExtension(path)}.dart'; - var scriptBase = htmlEscape.convert(p.basename(test)); - var link = ''; - var testName = htmlEscape.convert(test); - var template = config.customHtmlTemplatePath ?? defaultTemplatePath; - var contents = File(template).readAsStringSync(); - var jsRuntime = p.basename('$test.browser_test.dart.mjs'); - var wasmData = ''; - var processedContents = contents - // Checked during loading phase that there is only one {{testScript}} placeholder. - .replaceFirst('{{testScript}}', '$link\n$wasmData') - .replaceAll('{{testName}}', testName); - return shelf.Response.ok(processedContents, - headers: {'Content-Type': 'text/html'}); - } - - return shelf.Response.notFound('Not found.'); - } - @override Future compileSuite( String dartPath, SuiteConfiguration suiteConfig, SuitePlatform platform) { diff --git a/pkgs/test/lib/src/runner/browser/compilers/precompiled.dart b/pkgs/test/lib/src/runner/browser/compilers/precompiled.dart index 330abf50c..f4c6a7a7e 100644 --- a/pkgs/test/lib/src/runner/browser/compilers/precompiled.dart +++ b/pkgs/test/lib/src/runner/browser/compilers/precompiled.dart @@ -12,7 +12,8 @@ import 'package:shelf/shelf_io.dart' as shelf_io; import 'package:shelf_packages_handler/shelf_packages_handler.dart'; import 'package:shelf_static/shelf_static.dart'; import 'package:shelf_web_socket/shelf_web_socket.dart'; -import 'package:test_api/backend.dart' show StackTraceMapper, SuitePlatform; +import 'package:test_api/backend.dart' + show Compiler, StackTraceMapper, SuitePlatform; import 'package:test_core/src/runner/configuration.dart'; // ignore: implementation_imports import 'package:test_core/src/runner/suite.dart'; // ignore: implementation_imports import 'package:test_core/src/util/package_config.dart'; // ignore: implementation_imports @@ -25,8 +26,11 @@ import '../../../util/package_map.dart'; import '../../../util/path_handler.dart'; import 'compiler_support.dart'; +class JsPrecompiledSupport = PrecompiledSupport with JsHtmlWrapper; +class WasmPrecompiledSupport = PrecompiledSupport with WasmHtmlWrapper; + /// Support for precompiled test files. -class PrecompiledSupport extends CompilerSupport { +abstract class PrecompiledSupport extends CompilerSupport { /// Whether [close] has been called. bool _closed = false; @@ -80,14 +84,25 @@ class PrecompiledSupport extends CompilerSupport { } static Future start({ + required Compiler compiler, required Configuration config, required String defaultTemplatePath, required String root, required String faviconPath, }) async { var server = shelf_io.IOServer(await HttpMultiServer.loopback(0)); - return PrecompiledSupport._( - config, defaultTemplatePath, server, root, faviconPath); + + return switch (compiler) { + Compiler.dart2js => JsPrecompiledSupport._( + config, defaultTemplatePath, server, root, faviconPath), + Compiler.dart2wasm => WasmPrecompiledSupport._( + config, defaultTemplatePath, server, root, faviconPath), + Compiler.exe || + Compiler.kernel || + Compiler.source => + throw UnsupportedError( + 'The browser platform does not support $compiler'), + }; } /// Compiles [dartPath] using [suiteConfig] for [platform]. diff --git a/pkgs/test/lib/src/runner/browser/platform.dart b/pkgs/test/lib/src/runner/browser/platform.dart index 93661939b..c4df1b32c 100644 --- a/pkgs/test/lib/src/runner/browser/platform.dart +++ b/pkgs/test/lib/src/runner/browser/platform.dart @@ -63,6 +63,7 @@ class BrowserPlatform extends PlatformPlugin _compilerSupport.putIfAbsent(compiler, () { if (_config.suiteDefaults.precompiledPath != null) { return PrecompiledSupport.start( + compiler: compiler, config: _config, defaultTemplatePath: _defaultTemplatePath, root: _config.suiteDefaults.precompiledPath!,