From f7a14c80277b7b87e5fafff7af8be22b6535f7e0 Mon Sep 17 00:00:00 2001 From: Jake Macdonald Date: Thu, 4 Sep 2025 21:39:37 +0000 Subject: [PATCH 1/2] get version from a hard coded value --- pkgs/test/CHANGELOG.md | 2 + pkgs/test/lib/src/executable.dart | 3 +- pkgs/test/lib/src/version.dart | 9 +++ pkgs/test/pubspec.yaml | 1 + .../test/test/runner/json_reporter_utils.dart | 2 +- pkgs/test/test/version_test.dart | 22 +++++++ pkgs/test_core/CHANGELOG.md | 2 + pkgs/test_core/lib/src/executable.dart | 16 ++--- pkgs/test_core/lib/src/runner.dart | 59 ++++++++++-------- .../src/runner/configuration/reporters.dart | 12 ++-- pkgs/test_core/lib/src/runner/engine.dart | 8 ++- .../lib/src/runner/reporter/json.dart | 3 +- pkgs/test_core/lib/src/runner/version.dart | 61 ------------------- 13 files changed, 93 insertions(+), 107 deletions(-) create mode 100644 pkgs/test/lib/src/version.dart create mode 100644 pkgs/test/test/version_test.dart delete mode 100644 pkgs/test_core/lib/src/runner/version.dart diff --git a/pkgs/test/CHANGELOG.md b/pkgs/test/CHANGELOG.md index 2a9474861..45f59a2bb 100644 --- a/pkgs/test/CHANGELOG.md +++ b/pkgs/test/CHANGELOG.md @@ -4,6 +4,8 @@ * Require Dart 3.7 * Add `--coverage-path` and `--branch-coverage` options to `dart test`. * Serve dart2wasm source map files. +* Change `--version` to use a hard coded value instead of reading it from the + pubspec.lock, this is more efficient and supports workspaces. ## 1.26.3 diff --git a/pkgs/test/lib/src/executable.dart b/pkgs/test/lib/src/executable.dart index 5780694aa..a9464c507 100644 --- a/pkgs/test/lib/src/executable.dart +++ b/pkgs/test/lib/src/executable.dart @@ -9,6 +9,7 @@ import 'package:test_core/src/runner/hack_register_platform.dart'; // ignore: im import 'runner/browser/platform.dart'; import 'runner/node/platform.dart'; +import 'version.dart'; Future main(List args) async { registerPlatformPlugin([Runtime.nodeJS], NodePlatform.new); @@ -19,5 +20,5 @@ Future main(List args) async { Runtime.safari, ], BrowserPlatform.start); - await executable.main(args); + await executable.main(args, testVersion: testVersion); } diff --git a/pkgs/test/lib/src/version.dart b/pkgs/test/lib/src/version.dart new file mode 100644 index 000000000..ab6fd6a21 --- /dev/null +++ b/pkgs/test/lib/src/version.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2025, 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. + +/// The version of the `test` package. +/// +/// Must match what is in the pubspec.yaml, and enforced by +/// test/version_test.dart. +const String testVersion = '1.27.0-wip'; diff --git a/pkgs/test/pubspec.yaml b/pkgs/test/pubspec.yaml index 7c167d764..4f8a7e20d 100644 --- a/pkgs/test/pubspec.yaml +++ b/pkgs/test/pubspec.yaml @@ -47,6 +47,7 @@ dependencies: dev_dependencies: fake_async: ^1.0.0 glob: ^2.0.0 + pubspec_parse: ^1.2.0 test_descriptor: ^2.0.0 test_process: ^2.0.0 diff --git a/pkgs/test/test/runner/json_reporter_utils.dart b/pkgs/test/test/runner/json_reporter_utils.dart index 7416c0a4a..6a7f07f57 100644 --- a/pkgs/test/test/runner/json_reporter_utils.dart +++ b/pkgs/test/test/runner/json_reporter_utils.dart @@ -5,8 +5,8 @@ import 'dart:convert'; import 'package:path/path.dart' as p; +import 'package:test/src/version.dart'; import 'package:test/test.dart'; -import 'package:test_core/src/runner/version.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; /// Asserts that the outputs from running tests with a JSON reporter match the diff --git a/pkgs/test/test/version_test.dart b/pkgs/test/test/version_test.dart new file mode 100644 index 000000000..be608fe7a --- /dev/null +++ b/pkgs/test/test/version_test.dart @@ -0,0 +1,22 @@ +// Copyright (c) 2023, 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. + +@TestOn('vm') +library; + +import 'dart:io'; + +import 'package:pubspec_parse/pubspec_parse.dart'; +import 'package:test/src/version.dart'; +import 'package:test/test.dart'; + +void main() { + test('testVersion is up to date', () { + final pubspec = Pubspec.parse( + File('pkgs/test/pubspec.yaml').readAsStringSync(), + sourceUrl: Uri.file('pkgs/test/pubspec.yaml'), + ); + expect(pubspec.version.toString(), testVersion); + }); +} diff --git a/pkgs/test_core/CHANGELOG.md b/pkgs/test_core/CHANGELOG.md index 74d7fb713..9526ef637 100644 --- a/pkgs/test_core/CHANGELOG.md +++ b/pkgs/test_core/CHANGELOG.md @@ -3,6 +3,8 @@ * Restrict to latest version of analyzer package. * Require Dart 3.7 * Add `--coverage-path` and `--branch-coverage` options to `dart test`. +* Change `--version` to use a hard coded value instead of reading it from the + pubspec.lock, this is more efficient and supports workspaces. ## 0.6.12 diff --git a/pkgs/test_core/lib/src/executable.dart b/pkgs/test_core/lib/src/executable.dart index 0a3dc4409..93861f5cd 100644 --- a/pkgs/test_core/lib/src/executable.dart +++ b/pkgs/test_core/lib/src/executable.dart @@ -15,7 +15,6 @@ import 'runner.dart'; import 'runner/application_exception.dart'; import 'runner/configuration.dart'; import 'runner/no_tests_found_exception.dart'; -import 'runner/version.dart'; import 'util/errors.dart'; import 'util/exit_codes.dart' as exit_codes; import 'util/io.dart'; @@ -34,8 +33,10 @@ final String _globalConfigPath = () { } }(); -Future main(List args) async { - await _execute(args); +/// Main entrypoint for the executable, the [version] is the version of the +/// test runner executing this function. +Future main(List args, {String? testVersion}) async { + await _execute(args, testVersion: testVersion); completeShutdown(); } @@ -54,7 +55,7 @@ void completeShutdown() { cancelStdinLines(); } -Future _execute(List args) async { +Future _execute(List args, {String? testVersion}) async { /// A merged stream of all signals that tell the test runner to shut down /// gracefully. /// @@ -87,12 +88,11 @@ Future _execute(List args) async { } if (configuration.version) { - var version = testVersion; - if (version == null) { + if (testVersion == null) { stderr.writeln("Couldn't find version number."); exitCode = exit_codes.data; } else { - print(version); + print(testVersion); } return; } @@ -157,7 +157,7 @@ Future _execute(List args) async { }); try { - runner = Runner(configuration); + runner = Runner(configuration, testVersion: testVersion); exitCode = (await runner.run()) ? 0 : 1; } on ApplicationException catch (error) { stderr.writeln(error.message); diff --git a/pkgs/test_core/lib/src/runner.dart b/pkgs/test_core/lib/src/runner.dart index 7aedabbdb..aa82e854f 100644 --- a/pkgs/test_core/lib/src/runner.dart +++ b/pkgs/test_core/lib/src/runner.dart @@ -72,35 +72,40 @@ class Runner { /// Sinks created for each file reporter (if there are any). final List _sinks; - /// Creates a new runner based on [configuration]. - factory Runner(Configuration config) => config.asCurrent(() { - var engine = Engine( - concurrency: config.concurrency, - coverage: config.coverage, - coverageLcov: config.coverageLcov, - testRandomizeOrderingSeed: config.testRandomizeOrderingSeed, - stopOnFirstFailure: config.stopOnFirstFailure, - ); + /// Creates a new runner based on [config]. + /// + /// The [testVersion] is the test runner version. + factory Runner(Configuration config, {String? testVersion}) => + config.asCurrent(() { + var engine = Engine( + concurrency: config.concurrency, + coverage: config.coverage, + coverageLcov: config.coverageLcov, + testRandomizeOrderingSeed: config.testRandomizeOrderingSeed, + stopOnFirstFailure: config.stopOnFirstFailure, + testVersion: testVersion, + ); - var sinks = []; - Reporter createFileReporter(String reporterName, String filepath) { - final sink = (File(filepath)..createSync(recursive: true)).openWrite(); - sinks.add(sink); - return allReporters[reporterName]!.factory(config, engine, sink); - } + var sinks = []; + Reporter createFileReporter(String reporterName, String filepath) { + final sink = + (File(filepath)..createSync(recursive: true)).openWrite(); + sinks.add(sink); + return allReporters[reporterName]!.factory(config, engine, sink); + } - return Runner._( - engine, - MultiplexReporter([ - // Standard reporter. - allReporters[config.reporter]!.factory(config, engine, stdout), - // File reporters. - for (var reporter in config.fileReporters.keys) - createFileReporter(reporter, config.fileReporters[reporter]!), - ]), - sinks, - ); - }); + return Runner._( + engine, + MultiplexReporter([ + // Standard reporter. + allReporters[config.reporter]!.factory(config, engine, stdout), + // File reporters. + for (var reporter in config.fileReporters.keys) + createFileReporter(reporter, config.fileReporters[reporter]!), + ]), + sinks, + ); + }); Runner._(this._engine, this._reporter, this._sinks); diff --git a/pkgs/test_core/lib/src/runner/configuration/reporters.dart b/pkgs/test_core/lib/src/runner/configuration/reporters.dart index 35768ce84..46ba11204 100644 --- a/pkgs/test_core/lib/src/runner/configuration/reporters.dart +++ b/pkgs/test_core/lib/src/runner/configuration/reporters.dart @@ -33,7 +33,7 @@ final UnmodifiableMapView allReporters = final _allReporters = { 'compact': ReporterDetails( 'A single line, updated continuously.', - (config, engine, sink) => CompactReporter.watch( + (config, engine, sink, {version}) => CompactReporter.watch( engine, sink, color: config.color, @@ -47,7 +47,7 @@ final _allReporters = { ), 'expanded': ReporterDetails( 'A separate line for each update.', - (config, engine, sink) => ExpandedReporter.watch( + (config, engine, sink, {version}) => ExpandedReporter.watch( engine, sink, color: config.color, @@ -61,7 +61,7 @@ final _allReporters = { ), 'failures-only': ReporterDetails( 'A separate line for failing tests with no output for passing tests', - (config, engine, sink) => FailuresOnlyReporter.watch( + (config, engine, sink, {version}) => FailuresOnlyReporter.watch( engine, sink, color: config.color, @@ -76,7 +76,7 @@ final _allReporters = { 'github': ReporterDetails( 'A custom reporter for GitHub Actions ' '(the default reporter when running on GitHub Actions).', - (config, engine, sink) => GithubReporter.watch( + (config, engine, sink, {version}) => GithubReporter.watch( engine, sink, printPath: @@ -90,13 +90,13 @@ final _allReporters = { 'json': ReporterDetails( 'A machine-readable format (see ' 'https://dart.dev/go/test-docs/json_reporter.md).', - (config, engine, sink) => + (config, engine, sink, {version}) => JsonReporter.watch(engine, sink, isDebugRun: config.debug), ), 'silent': ReporterDetails( 'A reporter with no output. ' 'May be useful when only the exit code is meaningful.', - (config, engine, sink) => SilentReporter(), + (config, engine, sink, {version}) => SilentReporter(), ), }; diff --git a/pkgs/test_core/lib/src/runner/engine.dart b/pkgs/test_core/lib/src/runner/engine.dart index 5d96369f4..2edd605ec 100644 --- a/pkgs/test_core/lib/src/runner/engine.dart +++ b/pkgs/test_core/lib/src/runner/engine.dart @@ -205,6 +205,11 @@ class Engine { /// `false` to `true`. Stream get onIdle => _group.onIdle; + /// The version of the test reporter (generally, the `test` package). + /// + /// Can be `null` if not running using the test runner. + final String? testVersion; + /// Creates an [Engine] that will run all tests provided via [suiteSink]. /// /// [concurrency] controls how many suites are loaded and ran at once, and @@ -218,13 +223,14 @@ class Engine { /// [coverage] specifies a directory to output coverage information. /// /// If [stopOnFirstFailure] then a single failing test will cause the engine - /// to [close] and stop ruunning further tests. + /// to [close] and stop running further tests. Engine({ int? concurrency, String? coverage, String? coverageLcov, this.testRandomizeOrderingSeed, bool stopOnFirstFailure = false, + this.testVersion, }) : _runPool = Pool(concurrency ?? 1), _stopOnFirstFailure = stopOnFirstFailure, _coverage = coverage, diff --git a/pkgs/test_core/lib/src/runner/reporter/json.dart b/pkgs/test_core/lib/src/runner/reporter/json.dart index 13f834fa8..cd81df78e 100644 --- a/pkgs/test_core/lib/src/runner/reporter/json.dart +++ b/pkgs/test_core/lib/src/runner/reporter/json.dart @@ -22,7 +22,6 @@ import '../../platform.dart'; import '../engine.dart'; import '../load_suite.dart'; import '../reporter.dart'; -import '../version.dart'; /// A reporter that prints machine-readable JSON-formatted test results. class JsonReporter implements Reporter { @@ -89,7 +88,7 @@ class JsonReporter implements Reporter { _emit('start', { 'protocolVersion': '0.1.1', - 'runnerVersion': testVersion, + 'runnerVersion': _engine.testVersion, 'pid': pid, }); } diff --git a/pkgs/test_core/lib/src/runner/version.dart b/pkgs/test_core/lib/src/runner/version.dart deleted file mode 100644 index aff679111..000000000 --- a/pkgs/test_core/lib/src/runner/version.dart +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2015, 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 'dart:io'; - -import 'package:yaml/yaml.dart'; - -/// The version number of the test runner, or `null` if it couldn't be loaded. -/// -/// This is a semantic version, optionally followed by a space and additional -/// data about its source. -final String? testVersion = - (() { - dynamic lockfile; - try { - lockfile = loadYaml(File('pubspec.lock').readAsStringSync()); - } on FormatException catch (_) { - return null; - } on IOException catch (_) { - return null; - } - - if (lockfile is! Map) return null; - var packages = lockfile['packages']; - if (packages is! Map) return null; - var package = packages['test']; - if (package is! Map) return null; - - var source = package['source']; - if (source is! String) return null; - - switch (source) { - case 'hosted': - var version = package['version']; - return (version is String) ? version : null; - - case 'git': - var version = package['version']; - if (version is! String) return null; - var description = package['description']; - if (description is! Map) return null; - var ref = description['resolved-ref']; - if (ref is! String) return null; - - return '$version (${ref.substring(0, 7)})'; - - case 'path': - var version = package['version']; - if (version is! String) return null; - var description = package['description']; - if (description is! Map) return null; - var path = description['path']; - if (path is! String) return null; - - return '$version (from $path)'; - - default: - return null; - } - })(); From 2a3de9c1cb807a9d212f044590fab5b5d697bd5a Mon Sep 17 00:00:00 2001 From: Jake Macdonald Date: Thu, 4 Sep 2025 21:49:50 +0000 Subject: [PATCH 2/2] fix test path --- pkgs/test/test/version_test.dart | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pkgs/test/test/version_test.dart b/pkgs/test/test/version_test.dart index be608fe7a..59898215d 100644 --- a/pkgs/test/test/version_test.dart +++ b/pkgs/test/test/version_test.dart @@ -13,10 +13,8 @@ import 'package:test/test.dart'; void main() { test('testVersion is up to date', () { - final pubspec = Pubspec.parse( - File('pkgs/test/pubspec.yaml').readAsStringSync(), - sourceUrl: Uri.file('pkgs/test/pubspec.yaml'), - ); + final file = File('pubspec.yaml'); + final pubspec = Pubspec.parse(file.readAsStringSync(), sourceUrl: file.uri); expect(pubspec.version.toString(), testVersion); }); }