Skip to content

Commit c709cde

Browse files
authored
fix a bug where test html files were not created in precompiled mode (#2170)
* fix a bug where test html files were not created in precompiled mode * support wasm and js precompiled tests
1 parent 0eddae4 commit c709cde

File tree

7 files changed

+112
-80
lines changed

7 files changed

+112
-80
lines changed

pkgs/test/CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
## 1.25.1-wip
1+
## 1.25.1
2+
3+
* Fix a bug where in precompiled mode, html files for tests were no longer
4+
created.
25

36
* Document the silent reporter in CLI help output.
47

pkgs/test/lib/src/runner/browser/compilers/compiler_support.dart

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,26 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'dart:async';
6+
import 'dart:convert';
7+
import 'dart:io';
68

9+
import 'package:path/path.dart' as p;
10+
import 'package:shelf/shelf.dart' as shelf;
711
import 'package:test_api/backend.dart' show StackTraceMapper, SuitePlatform;
12+
import 'package:test_core/src/runner/configuration.dart'; // ignore: implementation_imports
813
import 'package:test_core/src/runner/suite.dart'; // ignore: implementation_imports
914
import 'package:web_socket_channel/web_socket_channel.dart'; // ignore: implementation_imports
1015

1116
/// The shared interface for all compiler support libraries.
12-
abstract interface class CompilerSupport {
17+
abstract class CompilerSupport {
18+
/// The global test runner configuration.
19+
final Configuration config;
20+
21+
/// The default template path.
22+
final String defaultTemplatePath;
23+
24+
CompilerSupport(this.config, this.defaultTemplatePath);
25+
1326
/// The URL at which this compiler serves its tests.
1427
///
1528
/// Each compiler serves its tests under a different directory.
@@ -34,4 +47,59 @@ abstract interface class CompilerSupport {
3447

3548
/// Closes down anything necessary for this implementation.
3649
Future<void> close();
50+
51+
/// A handler that serves html wrapper files used to bootstrap tests.
52+
shelf.Response htmlWrapperHandler(shelf.Request request);
53+
}
54+
55+
mixin JsHtmlWrapper on CompilerSupport {
56+
@override
57+
shelf.Response htmlWrapperHandler(shelf.Request request) {
58+
var path = p.fromUri(request.url);
59+
60+
if (path.endsWith('.html')) {
61+
var test = p.setExtension(path, '.dart');
62+
var scriptBase = htmlEscape.convert(p.basename(test));
63+
var link = '<link rel="x-dart-test" href="$scriptBase">';
64+
var testName = htmlEscape.convert(test);
65+
var template = config.customHtmlTemplatePath ?? defaultTemplatePath;
66+
var contents = File(template).readAsStringSync();
67+
var processedContents = contents
68+
// Checked during loading phase that there is only one {{testScript}} placeholder.
69+
.replaceFirst('{{testScript}}', link)
70+
.replaceAll('{{testName}}', testName);
71+
return shelf.Response.ok(processedContents,
72+
headers: {'Content-Type': 'text/html'});
73+
}
74+
75+
return shelf.Response.notFound('Not found.');
76+
}
77+
}
78+
79+
mixin WasmHtmlWrapper on CompilerSupport {
80+
@override
81+
shelf.Response htmlWrapperHandler(shelf.Request request) {
82+
var path = p.fromUri(request.url);
83+
84+
if (path.endsWith('.html')) {
85+
var test = '${p.withoutExtension(path)}.dart';
86+
var scriptBase = htmlEscape.convert(p.basename(test));
87+
var link = '<link rel="x-dart-test" href="$scriptBase">';
88+
var testName = htmlEscape.convert(test);
89+
var template = config.customHtmlTemplatePath ?? defaultTemplatePath;
90+
var contents = File(template).readAsStringSync();
91+
var jsRuntime = p.basename('$test.browser_test.dart.mjs');
92+
var wasmData = '<data id="WasmBootstrapInfo" '
93+
'data-wasmurl="${p.basename('$test.browser_test.dart.wasm')}" '
94+
'data-jsruntimeurl="$jsRuntime"></data>';
95+
var processedContents = contents
96+
// Checked during loading phase that there is only one {{testScript}} placeholder.
97+
.replaceFirst('{{testScript}}', '$link\n$wasmData')
98+
.replaceAll('{{testName}}', testName);
99+
return shelf.Response.ok(processedContents,
100+
headers: {'Content-Type': 'text/html'});
101+
}
102+
103+
return shelf.Response.notFound('Not found.');
104+
}
37105
}

pkgs/test/lib/src/runner/browser/compilers/dart2js.dart

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'dart:async';
6-
import 'dart:convert';
76
import 'dart:io';
87

98
import 'package:http_multi_server/http_multi_server.dart';
@@ -30,7 +29,7 @@ import '../../../util/path_handler.dart';
3029
import 'compiler_support.dart';
3130

3231
/// Support for Dart2Js compiled tests.
33-
class Dart2JsSupport implements CompilerSupport {
32+
class Dart2JsSupport extends CompilerSupport with JsHtmlWrapper {
3433
/// Whether [close] has been called.
3534
bool _closed = false;
3635

@@ -47,12 +46,6 @@ class Dart2JsSupport implements CompilerSupport {
4746
/// The [Dart2JsCompilerPool] managing active instances of `dart2js`.
4847
final _compilerPool = Dart2JsCompilerPool();
4948

50-
/// The global test runner configuration.
51-
final Configuration _config;
52-
53-
/// The default template path.
54-
final String _defaultTemplatePath;
55-
5649
/// Mappers for Dartifying stack traces, indexed by test path.
5750
final _mappers = <String, StackTraceMapper>{};
5851

@@ -81,14 +74,14 @@ class Dart2JsSupport implements CompilerSupport {
8174
@override
8275
Uri get serverUrl => _server.url.resolve('$_secret/');
8376

84-
Dart2JsSupport._(this._config, this._defaultTemplatePath, this._server,
77+
Dart2JsSupport._(super.config, super.defaultTemplatePath, this._server,
8578
this._root, String faviconPath) {
8679
var cascade = shelf.Cascade()
8780
.add(_webSocketHandler.handler)
8881
.add(packagesDirHandler())
8982
.add(_pathHandler.handler)
9083
.add(createStaticHandler(_root))
91-
.add(_wrapperHandler);
84+
.add(htmlWrapperHandler);
9285

9386
var pipeline = const shelf.Pipeline()
9487
.addMiddleware(PathHandler.nestedIn(_secret))
@@ -111,28 +104,6 @@ class Dart2JsSupport implements CompilerSupport {
111104
config, defaultTemplatePath, server, root, faviconPath);
112105
}
113106

114-
/// A handler that serves wrapper files used to bootstrap tests.
115-
shelf.Response _wrapperHandler(shelf.Request request) {
116-
var path = p.fromUri(request.url);
117-
118-
if (path.endsWith('.html')) {
119-
var test = p.setExtension(path, '.dart');
120-
var scriptBase = htmlEscape.convert(p.basename(test));
121-
var link = '<link rel="x-dart-test" href="$scriptBase">';
122-
var testName = htmlEscape.convert(test);
123-
var template = _config.customHtmlTemplatePath ?? _defaultTemplatePath;
124-
var contents = File(template).readAsStringSync();
125-
var processedContents = contents
126-
// Checked during loading phase that there is only one {{testScript}} placeholder.
127-
.replaceFirst('{{testScript}}', link)
128-
.replaceAll('{{testName}}', testName);
129-
return shelf.Response.ok(processedContents,
130-
headers: {'Content-Type': 'text/html'});
131-
}
132-
133-
return shelf.Response.notFound('Not found.');
134-
}
135-
136107
@override
137108
Future<void> compileSuite(
138109
String dartPath, SuiteConfiguration suiteConfig, SuitePlatform platform) {

pkgs/test/lib/src/runner/browser/compilers/dart2wasm.dart

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'dart:async';
6-
import 'dart:convert';
76
import 'dart:io';
87

98
import 'package:http_multi_server/http_multi_server.dart';
@@ -29,7 +28,7 @@ import '../browser_manager.dart';
2928
import 'compiler_support.dart';
3029

3130
/// Support for Dart2Wasm compiled tests.
32-
class Dart2WasmSupport implements CompilerSupport {
31+
class Dart2WasmSupport extends CompilerSupport with WasmHtmlWrapper {
3332
/// Whether [close] has been called.
3433
bool _closed = false;
3534

@@ -46,12 +45,6 @@ class Dart2WasmSupport implements CompilerSupport {
4645
/// The [WasmCompilerPool] managing active instances of `dart2wasm`.
4746
final _compilerPool = WasmCompilerPool();
4847

49-
/// The global test runner configuration.
50-
final Configuration _config;
51-
52-
/// The default template path.
53-
final String _defaultTemplatePath;
54-
5548
/// The `package:test` side wrapper for the Dart2Wasm runtime.
5649
final String _jsRuntimeWrapper;
5750

@@ -83,14 +76,14 @@ class Dart2WasmSupport implements CompilerSupport {
8376
@override
8477
Uri get serverUrl => _server.url.resolve('$_secret/');
8578

86-
Dart2WasmSupport._(this._config, this._defaultTemplatePath,
79+
Dart2WasmSupport._(super.config, super.defaultTemplatePath,
8780
this._jsRuntimeWrapper, this._server, this._root, String faviconPath) {
8881
var cascade = shelf.Cascade()
8982
.add(_webSocketHandler.handler)
9083
.add(packagesDirHandler())
9184
.add(_pathHandler.handler)
9285
.add(createStaticHandler(_root))
93-
.add(_wrapperHandler);
86+
.add(htmlWrapperHandler);
9487

9588
var pipeline = const shelf.Pipeline()
9689
.addMiddleware(PathHandler.nestedIn(_secret))
@@ -114,32 +107,6 @@ class Dart2WasmSupport implements CompilerSupport {
114107
server, root, faviconPath);
115108
}
116109

117-
/// A handler that serves wrapper files used to bootstrap tests.
118-
shelf.Response _wrapperHandler(shelf.Request request) {
119-
var path = p.fromUri(request.url);
120-
121-
if (path.endsWith('.html')) {
122-
var test = '${p.withoutExtension(path)}.dart';
123-
var scriptBase = htmlEscape.convert(p.basename(test));
124-
var link = '<link rel="x-dart-test" href="$scriptBase">';
125-
var testName = htmlEscape.convert(test);
126-
var template = _config.customHtmlTemplatePath ?? _defaultTemplatePath;
127-
var contents = File(template).readAsStringSync();
128-
var jsRuntime = p.basename('$test.browser_test.dart.mjs');
129-
var wasmData = '<data id="WasmBootstrapInfo" '
130-
'data-wasmurl="${p.basename('$test.browser_test.dart.wasm')}" '
131-
'data-jsruntimeurl="$jsRuntime"></data>';
132-
var processedContents = contents
133-
// Checked during loading phase that there is only one {{testScript}} placeholder.
134-
.replaceFirst('{{testScript}}', '$link\n$wasmData')
135-
.replaceAll('{{testName}}', testName);
136-
return shelf.Response.ok(processedContents,
137-
headers: {'Content-Type': 'text/html'});
138-
}
139-
140-
return shelf.Response.notFound('Not found.');
141-
}
142-
143110
@override
144111
Future<void> compileSuite(
145112
String dartPath, SuiteConfiguration suiteConfig, SuitePlatform platform) {

pkgs/test/lib/src/runner/browser/compilers/precompiled.dart

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ import 'package:shelf/shelf_io.dart' as shelf_io;
1212
import 'package:shelf_packages_handler/shelf_packages_handler.dart';
1313
import 'package:shelf_static/shelf_static.dart';
1414
import 'package:shelf_web_socket/shelf_web_socket.dart';
15-
import 'package:test_api/backend.dart' show StackTraceMapper, SuitePlatform;
15+
import 'package:test_api/backend.dart'
16+
show Compiler, StackTraceMapper, SuitePlatform;
17+
import 'package:test_core/src/runner/configuration.dart'; // ignore: implementation_imports
1618
import 'package:test_core/src/runner/suite.dart'; // ignore: implementation_imports
1719
import 'package:test_core/src/util/package_config.dart'; // ignore: implementation_imports
1820
import 'package:test_core/src/util/stack_trace_mapper.dart'; // ignore: implementation_imports
@@ -24,17 +26,17 @@ import '../../../util/package_map.dart';
2426
import '../../../util/path_handler.dart';
2527
import 'compiler_support.dart';
2628

29+
class JsPrecompiledSupport = PrecompiledSupport with JsHtmlWrapper;
30+
class WasmPrecompiledSupport = PrecompiledSupport with WasmHtmlWrapper;
31+
2732
/// Support for precompiled test files.
28-
class PrecompiledSupport implements CompilerSupport {
33+
abstract class PrecompiledSupport extends CompilerSupport {
2934
/// Whether [close] has been called.
3035
bool _closed = false;
3136

3237
/// Mappers for Dartifying stack traces, indexed by test path.
3338
final _mappers = <String, StackTraceMapper>{};
3439

35-
/// A [PathHandler] used to serve test specific artifacts.
36-
final _pathHandler = PathHandler();
37-
3840
/// The root directory served statically by the server.
3941
final String _root;
4042

@@ -60,12 +62,16 @@ class PrecompiledSupport implements CompilerSupport {
6062
@override
6163
Uri get serverUrl => _server.url.resolve('$_secret/');
6264

63-
PrecompiledSupport._(this._server, this._root, String faviconPath) {
65+
PrecompiledSupport._(super.config, super.defaultTemplatePath, this._server,
66+
this._root, String faviconPath) {
6467
var cascade = shelf.Cascade()
6568
.add(_webSocketHandler.handler)
69+
.add(createStaticHandler(_root, serveFilesOutsidePath: true))
70+
// TODO: This packages dir handler should not be necessary?
6671
.add(packagesDirHandler())
67-
.add(_pathHandler.handler)
68-
.add(createStaticHandler(_root));
72+
// Even for precompiled tests, we will auto-create a bootstrap html file
73+
// if none was present.
74+
.add(htmlWrapperHandler);
6975

7076
var pipeline = const shelf.Pipeline()
7177
.addMiddleware(PathHandler.nestedIn(_secret))
@@ -78,11 +84,25 @@ class PrecompiledSupport implements CompilerSupport {
7884
}
7985

8086
static Future<PrecompiledSupport> start({
87+
required Compiler compiler,
88+
required Configuration config,
89+
required String defaultTemplatePath,
8190
required String root,
8291
required String faviconPath,
8392
}) async {
8493
var server = shelf_io.IOServer(await HttpMultiServer.loopback(0));
85-
return PrecompiledSupport._(server, root, faviconPath);
94+
95+
return switch (compiler) {
96+
Compiler.dart2js => JsPrecompiledSupport._(
97+
config, defaultTemplatePath, server, root, faviconPath),
98+
Compiler.dart2wasm => WasmPrecompiledSupport._(
99+
config, defaultTemplatePath, server, root, faviconPath),
100+
Compiler.exe ||
101+
Compiler.kernel ||
102+
Compiler.source =>
103+
throw UnsupportedError(
104+
'The browser platform does not support $compiler'),
105+
};
86106
}
87107

88108
/// Compiles [dartPath] using [suiteConfig] for [platform].

pkgs/test/lib/src/runner/browser/platform.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ class BrowserPlatform extends PlatformPlugin
6363
_compilerSupport.putIfAbsent(compiler, () {
6464
if (_config.suiteDefaults.precompiledPath != null) {
6565
return PrecompiledSupport.start(
66+
compiler: compiler,
67+
config: _config,
68+
defaultTemplatePath: _defaultTemplatePath,
6669
root: _config.suiteDefaults.precompiledPath!,
6770
faviconPath: _faviconPath);
6871
}

pkgs/test/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: test
2-
version: 1.25.1-wip
2+
version: 1.25.1
33
description: >-
44
A full featured library for writing and running Dart tests across platforms.
55
repository: https://github.com/dart-lang/test/tree/master/pkgs/test

0 commit comments

Comments
 (0)