Tweak test_runner.
Clean up and optimize some RegExps, and fix uses of `.group`.
Switch to a newer language version, to be able to use newer features.
Add a little documentation about why some RegExps are as they are.
Add (tentative) warning for multitests.
Change-Id: I59f73b87ce30caaeca1c0e0aa7954af1b97abd1b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/382620
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Lasse Nielsen <lrn@google.com>
diff --git a/pkg/test_runner/lib/src/android.dart b/pkg/test_runner/lib/src/android.dart
index 417d643..3bc3bb4 100644
--- a/pkg/test_runner/lib/src/android.dart
+++ b/pkg/test_runner/lib/src/android.dart
@@ -341,7 +341,7 @@
/// Helper to list all adb devices available.
class AdbHelper {
static final RegExp _deviceLineRegexp =
- RegExp(r'^(([a-zA-Z0-9:_-]|\.)+)[ \t]+device$', multiLine: true);
+ RegExp(r'^([a-zA-Z0-9:_.\-]+)[ \t]+device$', multiLine: true);
static Future<List<String>> listDevices() {
return Process.run('adb', ['devices']).then((ProcessResult result) {
@@ -351,7 +351,7 @@
}
return _deviceLineRegexp
.allMatches(result.stdout as String)
- .map((Match m) => m.group(1)!)
+ .map((Match m) => m[1]!)
.toList();
});
}
diff --git a/pkg/test_runner/lib/src/browser.dart b/pkg/test_runner/lib/src/browser.dart
index 32316af..f0964ca 100644
--- a/pkg/test_runner/lib/src/browser.dart
+++ b/pkg/test_runner/lib/src/browser.dart
@@ -60,24 +60,26 @@
.replaceAll('-', '_'));
}
+final _digitPattern = RegExp(r'\d');
+
/// Escape [name] to make it into a valid identifier.
String _toJSIdentifier(String name) {
if (name.isEmpty) return r'$';
// Escape any invalid characters
- var result = name.replaceAllMapped(_invalidCharInIdentifier,
- (match) => '\$${match.group(0)!.codeUnits.join("")}');
+ var result = name.replaceAllMapped(
+ _invalidCharInIdentifier, (match) => '\$${match[0]!.codeUnits.join("")}');
// Ensure the identifier first character is not numeric and that the whole
// identifier is not a keyword.
- if (result.startsWith(RegExp('[0-9]')) || _invalidVariableName(result)) {
+ if (result.startsWith(_digitPattern) || _invalidVariableName(result)) {
return '\$$result';
}
return result;
}
// Invalid characters for identifiers, which would need to be escaped.
-final _invalidCharInIdentifier = RegExp(r'[^A-Za-z_0-9]');
+final _invalidCharInIdentifier = RegExp(r'[^A-Za-z_\d]');
bool _invalidVariableName(String keyword, {bool strictMode = true}) {
switch (keyword) {
diff --git a/pkg/test_runner/lib/src/co19_test_config.dart b/pkg/test_runner/lib/src/co19_test_config.dart
index 68042956..66cc6d5 100644
--- a/pkg/test_runner/lib/src/co19_test_config.dart
+++ b/pkg/test_runner/lib/src/co19_test_config.dart
@@ -7,7 +7,7 @@
import 'test_suite.dart';
class Co19TestSuite extends StandardTestSuite {
- static final _testRegExp = RegExp(r"t[0-9]{2,3}.dart$");
+ static final _testRegExp = RegExp(r"t\d{2,3}.dart$");
Co19TestSuite(TestConfiguration configuration, String selector)
: super(configuration, selector, Path("tests/$selector/src"), [
diff --git a/pkg/test_runner/lib/src/command_output.dart b/pkg/test_runner/lib/src/command_output.dart
index 7a100aa..adc4a4a 100644
--- a/pkg/test_runner/lib/src/command_output.dart
+++ b/pkg/test_runner/lib/src/command_output.dart
@@ -339,7 +339,7 @@
@override
void describe(TestCase testCase, Progress progress, OutputWriter output) {
if (_jsonResult != null) {
- _describeEvents(progress, output);
+ _describeEvents(progress, output, _jsonResult);
} else {
// We couldn't parse the events, so fallback to showing the last message.
output.section("Last message");
@@ -359,7 +359,8 @@
}
}
- void _describeEvents(Progress progress, OutputWriter output) {
+ void _describeEvents(Progress progress, OutputWriter output,
+ BrowserTestJsonResult jsonResult) {
// Always show the error events since those are most useful.
var errorShown = false;
@@ -374,19 +375,19 @@
// Skip deobfuscation if there is no indication that there is a stack
// trace in the string value.
- if (!value!.contains(RegExp('\\.js:'))) return;
+ if (!value!.contains('.js:')) return;
var stringStack = value
// Convert `http:` URIs to relative `file:` URIs.
- .replaceAll(RegExp('http://[^/]*/root_build/'), '$_buildDirectory/')
- .replaceAll(RegExp('http://[^/]*/root_dart/'), '')
+ .replaceAll(RegExp(r'http://[^/]*/root_build/'), '$_buildDirectory/')
+ .replaceAll(RegExp(r'http://[^/]*/root_dart/'), '')
// Remove query parameters (seen in .html URIs).
- .replaceAll(RegExp('\\?[^:\n]*:'), ':');
+ .replaceAll(RegExp(r'\?[^:\n]*:'), ':');
// TODO(sigmund): change internal deobfuscation code to avoid spurious
// error messages when files do not have a corresponding source-map.
_deobfuscateAndWriteStack(stringStack, output);
}
- for (var event in _jsonResult!.events) {
+ for (var event in jsonResult.events) {
if (event["type"] == "sync_exception") {
showError("Runtime error", event);
} else if (event["type"] == "window_onerror") {
@@ -401,7 +402,7 @@
}
output.subsection("Events");
- for (var event in _jsonResult!.events) {
+ for (var event in jsonResult.events) {
switch (event["type"] as String?) {
case "debug":
output.write('- debug "${event["value"]}"');
diff --git a/pkg/test_runner/lib/src/compiler_configuration.dart b/pkg/test_runner/lib/src/compiler_configuration.dart
index 0278dcd..9ebb610 100644
--- a/pkg/test_runner/lib/src/compiler_configuration.dart
+++ b/pkg/test_runner/lib/src/compiler_configuration.dart
@@ -801,7 +801,7 @@
.replaceAll('/', '__')
.replaceAll('-', '_')
.replaceAll('.dart', '')
- .replaceAllMapped(RegExp(r'[^A-Za-z_$0-9]'),
+ .replaceAllMapped(RegExp(r'[^A-Za-z_$\d]'),
(Match m) => '\$${m[0]!.codeUnits.join('')}');
var testPackageLoadStatements = [
for (var package in testPackages) 'load("$pkgJsDir/$package.js");'
@@ -1421,7 +1421,7 @@
}
}
-abstract class VMKernelCompilerMixin {
+abstract mixin class VMKernelCompilerMixin {
TestConfiguration get _configuration;
bool get _useSdk;
diff --git a/pkg/test_runner/lib/src/multitest.dart b/pkg/test_runner/lib/src/multitest.dart
index cae39d3..f81bb49 100644
--- a/pkg/test_runner/lib/src/multitest.dart
+++ b/pkg/test_runner/lib/src/multitest.dart
@@ -92,7 +92,7 @@
var lineSeparator =
(firstNewline == 0 || contents[firstNewline - 1] != '\r') ? '\n' : '\r\n';
var lines = contents.split(lineSeparator);
- if (lines.last == '') lines.removeLast();
+ if (lines.last.isEmpty) lines.removeLast();
// Create the set of multitests, which will have a new test added each
// time we see a multitest line with a new key.
@@ -108,16 +108,16 @@
var annotation = Annotation.tryParse(line);
if (annotation != null) {
testsAsLines.putIfAbsent(
- annotation.key, () => List<String>.from(testsAsLines["none"]!));
+ annotation.key, () => List<String>.of(testsAsLines["none"]!));
// Add line to test with annotation.key as key, empty line to the rest.
for (var entry in testsAsLines.entries) {
entry.value.add(annotation.key == entry.key ? line : "");
}
- outcomes.putIfAbsent(annotation.key, () => <String>{});
+ var outcome = outcomes.putIfAbsent(annotation.key, () => <String>{});
if (annotation.rest != 'continued') {
for (var nextOutcome in annotation.outcomes) {
if (_multitestOutcomes.contains(nextOutcome)) {
- outcomes[annotation.key]!.add(nextOutcome);
+ outcome.add(nextOutcome);
} else {
DebugLogger.warning(
"${filePath.toNativePath()}: Invalid expectation "
@@ -277,20 +277,20 @@
Set<String> _findAllRelativeImports(Path topLibrary) {
var found = <String>{};
var libraryDir = topLibrary.directoryPath;
- var relativeImportRegExp = RegExp(
- '^(?:@.*\\s+)?' // Allow for a meta-data annotation.
- '(import|part)'
- '\\s+["\']'
- '(?!(dart:|dart-ext:|data:|package:|/))' // Look-ahead: not in package.
- '([^"\']*)' // The path to the imported file.
- '["\']');
+ var relativeImportRegExp =
+ RegExp(r'^(?:@.*\s+)?' // Allow for a meta-data annotation.
+ r'(?:import|part)\s+'
+ r'''["']'''
+ r'(?!dart:|dart-ext:|data:|package:|/)' // Look-ahead: not in package.
+ r'([^]*?)' // The path to the imported file.
+ r'''["']''');
processFile(Path filePath) {
var file = File(filePath.toNativePath());
for (var line in file.readAsLinesSync()) {
var match = relativeImportRegExp.firstMatch(line);
if (match == null) continue;
- var relativePath = match.group(3)!;
+ var relativePath = match[1]!;
// If a multitest deliberately imports a nonexistent file, don't try to
// include it.
diff --git a/pkg/test_runner/lib/src/options.dart b/pkg/test_runner/lib/src/options.dart
index 35f1034..1733112 100644
--- a/pkg/test_runner/lib/src/options.dart
+++ b/pkg/test_runner/lib/src/options.dart
@@ -509,7 +509,7 @@
// Remove the `src/` subdirectories from the co19 directories that do
// not appear in the test names.
if (selector.startsWith('co19')) {
- selector = selector.replaceFirst(RegExp('src/'), '');
+ selector = selector.replaceFirst('src/', '');
}
break;
}
@@ -858,7 +858,7 @@
var pattern = selectors[i];
var suite = pattern;
var slashLocation = pattern.indexOf('/');
- if (slashLocation != -1) {
+ if (slashLocation >= 0) {
suite = pattern.substring(0, slashLocation);
pattern = pattern.substring(slashLocation + 1);
pattern = pattern.replaceAll('*', '.*');
diff --git a/pkg/test_runner/lib/src/static_error.dart b/pkg/test_runner/lib/src/static_error.dart
index ef8b5ea..dd30e53e 100644
--- a/pkg/test_runner/lib/src/static_error.dart
+++ b/pkg/test_runner/lib/src/static_error.dart
@@ -13,7 +13,7 @@
/// A front end that can report static errors.
class ErrorSource {
static const analyzer = ErrorSource._("analyzer");
- static const cfe = ErrorSource._("CFE");
+ static const cfe = ErrorSource._("CFE", marker: "cfe");
static const web = ErrorSource._("web");
/// Pseudo-front end for context messages.
@@ -41,9 +41,16 @@
final String name;
/// The string used to mark errors from this source in test files.
- String get marker => name.toLowerCase();
+ ///
+ /// Always lower-case.
+ final String marker;
- const ErrorSource._(this.name);
+ /// Creates error source.
+ ///
+ /// If [name] is not all lower-case, then a [marker] must be passed with
+ /// an all lower-case name. If `name` is lower-case, `marker` can be omitted
+ /// and then defaults to `name`.
+ const ErrorSource._(this.name, {String? marker}) : marker = marker ?? name;
}
/// Describes a single static error reported by a single front end at a specific
@@ -465,7 +472,7 @@
/// // ^^^
///
/// We look for a line that starts with a line comment followed by spaces and
- /// carets.
+ /// carets. Only used on single lines.
static final _caretLocationRegExp = RegExp(r"^\s*//\s*(\^+)\s*$");
/// Matches an explicit error location with a length, like:
@@ -475,29 +482,26 @@
/// or implicitly on the previous line
///
/// // [error column 17, length 3]
- static final _explicitLocationAndLengthRegExp = RegExp(
- r"^\s*//\s*\[\s*error (?:line\s+(\d+)\s*,)?\s*column\s+(\d+)\s*,\s*"
- r"length\s+(\d+)\s*\]\s*$");
-
- /// Matches an explicit error location without a length, like:
+ ///
+ /// or either without a length:
///
/// // [error line 1, column 17]
- ///
- /// or implicitly on the previous line.
- ///
/// // [error column 17]
+ ///
+ /// Only used on single lines.
static final _explicitLocationRegExp = RegExp(
- r"^\s*//\s*\[\s*error (?:line\s+(\d+)\s*,)?\s*column\s+(\d+)\s*\]\s*$");
+ r"^\s*//\s*\[\s*error (?:line\s+(\d+)\s*,)?\s*column\s+(\d+)\s*(?:,\s*"
+ r"length\s+(\d+)\s*)?\]\s*$");
/// Matches the beginning of an error message, like `// [analyzer]`.
///
/// May have an optional number like `// [cfe 32]`.
static final _errorMessageRegExp =
- RegExp(r"^\s*// \[(\w+)(\s+\d+)?\]\s*(.*)");
+ RegExp(r"^\s*// \[(\w+)(?:\s+(\d+))?\]\s*(.*)");
/// An analyzer error code is a dotted identifier or the magic string
/// "unspecified".
- static final _errorCodeRegExp = RegExp(r"^\w+\.\w+|unspecified$");
+ static final _errorCodeRegExp = RegExp(r"^(?:\w+\.\w+|unspecified)$");
/// Any line-comment-only lines after the first line of a CFE error message
/// are part of it.
@@ -535,40 +539,29 @@
while (_canPeek(0)) {
var sourceLine = _peek(0);
- var match = _caretLocationRegExp.firstMatch(sourceLine);
- if (match != null) {
+ if (_caretLocationRegExp.firstMatch(sourceLine) case var match?) {
if (_lastRealLine == -1) {
_fail("An error expectation must follow some code.");
}
-
+ var markerMatch = match[1]!;
_parseErrors(
path: path,
line: _lastRealLine,
column: sourceLine.indexOf("^") + 1,
- length: match[1]!.length);
+ length: markerMatch.length);
_advance();
continue;
}
- match = _explicitLocationAndLengthRegExp.firstMatch(sourceLine);
- if (match != null) {
+ if (_explicitLocationRegExp.firstMatch(sourceLine) case var match?) {
var lineCapture = match[1];
+ var columnCapture = match[2]!;
+ var lengthCapture = match[3];
_parseErrors(
path: path,
line: lineCapture == null ? _lastRealLine : int.parse(lineCapture),
- column: int.parse(match[2]!),
- length: int.parse(match[3]!));
- _advance();
- continue;
- }
-
- match = _explicitLocationRegExp.firstMatch(sourceLine);
- if (match != null) {
- var lineCapture = match[1];
- _parseErrors(
- path: path,
- line: lineCapture == null ? _lastRealLine : int.parse(lineCapture),
- column: int.parse(match[2]!));
+ column: int.parse(columnCapture),
+ length: lengthCapture == null ? 0 : int.parse(lengthCapture));
_advance();
continue;
}
@@ -604,7 +597,7 @@
_fail("Context messages must have an error number.");
}
- var message = match[3]!;
+ var message = StringBuffer(match[3]!);
_advance();
var sourceLines = {locationLine, _currentLine};
@@ -614,7 +607,6 @@
// A location line shouldn't be treated as part of the message.
if (_caretLocationRegExp.hasMatch(nextLine)) break;
- if (_explicitLocationAndLengthRegExp.hasMatch(nextLine)) break;
if (_explicitLocationRegExp.hasMatch(nextLine)) break;
// The next source should not be treated as part of the message.
@@ -623,13 +615,15 @@
var messageMatch = _errorMessageRestRegExp.firstMatch(nextLine);
if (messageMatch == null) break;
- message += "\n${messageMatch[1]!}";
+ message
+ ..write("\n")
+ ..write(messageMatch[1]!);
_advance();
sourceLines.add(_currentLine);
}
if (source == ErrorSource.analyzer &&
- !_errorCodeRegExp.hasMatch(message)) {
+ !_errorCodeRegExp.hasMatch(message.toString())) {
_fail("An analyzer error expectation should be a dotted identifier.");
}
@@ -644,7 +638,7 @@
errorLength = 0;
}
- var error = StaticError(source, message,
+ var error = StaticError(source, message.toString(),
path: path,
line: line,
column: column,
@@ -654,9 +648,9 @@
if (number != null) {
// Make sure two errors don't claim the same number.
if (source != ErrorSource.context) {
- var existingError = _errors
- .firstWhereOrNull((error) => _errorNumbers[error] == number);
- if (existingError != null) {
+ var existingError =
+ _errors.any((error) => _errorNumbers[error] == number);
+ if (existingError) {
_fail("Already have an error with number $number.");
}
}
@@ -700,9 +694,9 @@
var number = _errorNumbers[error];
if (number == null) continue;
- var context = _contextMessages
- .firstWhereOrNull((context) => _errorNumbers[context] == number);
- if (context == null) {
+ var hasContext =
+ _contextMessages.any((context) => _errorNumbers[context] == number);
+ if (!hasContext) {
throw FormatException("Missing context for numbered error $number "
"'${error.message}'.");
}
diff --git a/pkg/test_runner/lib/src/test_file.dart b/pkg/test_runner/lib/src/test_file.dart
index e5706c7..f9a90e1 100644
--- a/pkg/test_runner/lib/src/test_file.dart
+++ b/pkg/test_runner/lib/src/test_file.dart
@@ -6,28 +6,33 @@
import 'feature.dart';
import 'path.dart';
import 'static_error.dart';
+import 'utils.dart';
-final _multitestRegExp = RegExp(r"//# \w+:(.*)");
+final _multitestRegExp = RegExp(r"//# \w+:");
-final _vmOptionsRegExp = RegExp(r"// VMOptions=(.*)");
-final _environmentRegExp = RegExp(r"// Environment=(.*)");
-final _packagesRegExp = RegExp(r"// Packages=(.*)");
+final _vmOptionsRegExp = RegExp(r"^[ \t]*// VMOptions=(.*)", multiLine: true);
+final _environmentRegExp =
+ RegExp(r"^[ \t]*// Environment=(.*)", multiLine: true);
+final _packagesRegExp = RegExp(r"^[ \t]*// Packages=(.*)", multiLine: true);
final _experimentRegExp = RegExp(r"^--enable-experiment=([a-z0-9,-]+)$");
final _localFileRegExp = RegExp(
- r"""^\s*(?:import(?: augment)?|part) """
- r"""['"](?!package:|dart:)(.*)['"]"""
- r"""(?: deferred as \w+)?;""",
+ r"""^[ \t]*(?:import(?: augment)?|part)\s*"""
+ r"""['"](?!package:|dart:)(.*?)['"]\s*"""
+ r"""(?:(?:deferred\s+)?as\s+\w+\s*)?"""
+ r"""(?:(?:show|hide)\s+\w+\s*(?:,\s*\w+\s*))*;""",
multiLine: true);
List<String> _splitWords(String s) =>
- s.split(' ').where((e) => e != '').toList();
+ s.split(' ')..removeWhere((s) => s.isEmpty);
List<T> _parseOption<T>(
String filePath, String contents, String name, T Function(String) convert,
{bool allowMultiple = false}) {
- var matches = RegExp('// $name=(.*)').allMatches(contents);
+ var matches = RegExp('^[ \t]*// $name=(.*)', multiLine: true)
+ .allMatches(contents)
+ .toList();
if (!allowMultiple && matches.length > 1) {
- throw Exception('More than one "// $name=" line in test $filePath');
+ throw FormatException('More than one "// $name=" line in test $filePath');
}
var options = <T>[];
@@ -99,7 +104,7 @@
return path.toString().hashCode;
}
- return originPath.relativeTo(_suiteDirectory!).toString().hashCode;
+ return originPath.relativeTo(_suiteDirectory).toString().hashCode;
}
_TestFileBase(this._suiteDirectory, this.path, this.expectedErrors) {
@@ -117,15 +122,15 @@
var directory = testNamePath.directoryPath;
var filenameWithoutExt = testNamePath.filenameWithoutExtension;
- String concat(String base, String part) {
- if (base == "") return part;
- if (part == "") return base;
+ String join(String base, String part) {
+ if (base.isEmpty) return part;
+ if (part.isEmpty) return base;
return "$base/$part";
}
var result = "$directory";
- result = concat(result, filenameWithoutExt);
- result = concat(result, multitestKey);
+ result = join(result, filenameWithoutExt);
+ result = join(result, multitestKey);
return result;
}
}
@@ -255,7 +260,7 @@
"flags. Was:\n$sharedOption");
}
- experiments.addAll(match.group(1)!.split(","));
+ experiments.addAll(match[1]!.split(","));
sharedOptions.removeAt(i);
i--;
}
@@ -266,9 +271,13 @@
matches = _environmentRegExp.allMatches(contents);
for (var match in matches) {
var envDef = match[1]!;
+ var name = envDef;
+ var value = '';
var pos = envDef.indexOf('=');
- var name = (pos < 0) ? envDef : envDef.substring(0, pos);
- var value = (pos < 0) ? '' : envDef.substring(pos + 1);
+ if (pos >= 0) {
+ name = envDef.substring(0, pos);
+ value = envDef.substring(pos + 1);
+ }
environment[name] = value;
}
@@ -278,18 +287,23 @@
matches = _packagesRegExp.allMatches(contents);
for (var match in matches) {
if (packages != null) {
- throw Exception('More than one "// Package..." line in test $filePath');
+ throw FormatException(
+ 'More than one "// Package..." line in test $filePath');
}
- packages = match[1];
+ packages = match[1]!;
if (packages != 'none') {
// Packages=none means that no packages option should be given. Any
// other value overrides packages.
packages =
- Uri.file(filePath).resolveUri(Uri.file(packages!)).toFilePath();
+ Uri.file(filePath).resolveUri(Uri.file(packages)).toFilePath();
}
}
var isMultitest = _multitestRegExp.hasMatch(contents);
+ if (isMultitest) {
+ DebugLogger.warning(
+ "${Path(filePath).toNativePath()} is a legacy multi-test file.");
+ }
var errorExpectations = <StaticError>[];
try {
@@ -323,12 +337,12 @@
{Set<String>? alreadyParsed}) {
alreadyParsed ??= {};
var file = File(path);
-
+ var pathUri = Uri.parse(path);
// Missing files set no expectations.
if (!file.existsSync()) return [];
// Catch import loops.
- if (!alreadyParsed.add(Uri.parse(path).toString())) return [];
+ if (!alreadyParsed.add(pathUri.toString())) return [];
// Parse one file.
var contents = File(path).readAsStringSync();
@@ -340,7 +354,7 @@
var localPath = Uri.tryParse(match[1]!);
// Broken import paths set no expectations.
if (localPath == null) continue;
- var uriString = Uri.parse(path).resolve(localPath.path).toString();
+ var uriString = pathUri.resolve(localPath.path).toString();
result
.addAll(_parseExpectations(uriString, alreadyParsed: alreadyParsed));
}
diff --git a/pkg/test_runner/lib/src/update_errors.dart b/pkg/test_runner/lib/src/update_errors.dart
index bcff57e..f8068c4 100644
--- a/pkg/test_runner/lib/src/update_errors.dart
+++ b/pkg/test_runner/lib/src/update_errors.dart
@@ -3,10 +3,14 @@
// BSD-style license that can be found in the LICENSE file.
import 'static_error.dart';
-/// Matches leading indentation in a string.
-final _indentationRegExp = RegExp(r"^(\s*)");
+/// Matches end of leading indentation in a line.
+///
+/// Only used on single lines.
+final _indentationRegExp = RegExp(r"(?=\S|$)");
/// Matches a line that contains only a line comment.
+///
+/// Only used on single lines.
final _lineCommentRegExp = RegExp(r"^\s*//");
/// Removes existing static error marker comments in [source] and adds markers
@@ -190,5 +194,5 @@
/// Returns the number of characters of leading spaces in [line].
int _countIndentation(String line) {
var match = _indentationRegExp.firstMatch(line)!;
- return match.group(1)!.length;
+ return match.start;
}
diff --git a/pkg/test_runner/lib/test_runner.dart b/pkg/test_runner/lib/test_runner.dart
index 2e68d78..028a7ab 100644
--- a/pkg/test_runner/lib/test_runner.dart
+++ b/pkg/test_runner/lib/test_runner.dart
@@ -34,7 +34,7 @@
/// bar becomes 'foo
/// bar'
String shellSingleQuote(String string) {
- return "'${string.replaceAll("'", "'\\''")}'";
+ return "'${string.replaceAll("'", r"'\''")}'";
}
/// Like [shellSingleQuote], but if the string only contains safe ASCII
@@ -43,7 +43,7 @@
/// a shell keyword or a shell builtin in the first argument in a command. It
/// should be safe to use this for the second argument onwards in a command.
String simpleShellSingleQuote(String string) {
- return RegExp(r"^[a-zA-Z0-9%+,./:_-]*$").hasMatch(string)
+ return RegExp(r"^[a-zA-Z\d%+,./:_\-]*$").hasMatch(string)
? string
: shellSingleQuote(string);
}
diff --git a/pkg/test_runner/pubspec.yaml b/pkg/test_runner/pubspec.yaml
index 31396d4..3ce5bf7 100644
--- a/pkg/test_runner/pubspec.yaml
+++ b/pkg/test_runner/pubspec.yaml
@@ -7,7 +7,7 @@
publish_to: none
environment:
- sdk: '>=2.19.0 <3.0.0'
+ sdk: '>=3.4.0 <4.0.0'
# Use 'any' constraints here; we get our versions from the DEPS file.
dependencies:
diff --git a/runtime/tests/vm/dart/regress_46790_test.dart b/runtime/tests/vm/dart/regress_46790_test.dart
index ba2cfa5..8846059 100644
--- a/runtime/tests/vm/dart/regress_46790_test.dart
+++ b/runtime/tests/vm/dart/regress_46790_test.dart
@@ -2,7 +2,7 @@
// 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.
-/// VMOptions=--stacktrace_every=137 --deterministic
+// VMOptions=--stacktrace_every=137 --deterministic
// Reduced from
// The Dart Project Fuzz Tester (1.91).
diff --git a/tests/language/deferred/prefix_importer_tree_shaken_test.dart b/tests/language/deferred/prefix_importer_tree_shaken_test.dart
index ccb0246..242302e 100644
--- a/tests/language/deferred/prefix_importer_tree_shaken_test.dart
+++ b/tests/language/deferred/prefix_importer_tree_shaken_test.dart
@@ -2,8 +2,8 @@
// 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.
-/// VMOptions=--dwarf_stack_traces=true
-/// VMOptions=--dwarf_stack_traces=false
+// VMOptions=--dwarf_stack_traces=true
+// VMOptions=--dwarf_stack_traces=false
import "prefix_importer_tree_shaken_immediate.dart" as i;
diff --git a/tests/language/vm/fuzzer_unsigned_shift_right_test.dart b/tests/language/vm/fuzzer_unsigned_shift_right_test.dart
index 01e935a..42660ed 100644
--- a/tests/language/vm/fuzzer_unsigned_shift_right_test.dart
+++ b/tests/language/vm/fuzzer_unsigned_shift_right_test.dart
@@ -2,7 +2,7 @@
// 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.
-/// VMOptions=--deterministic
+// VMOptions=--deterministic
// The Dart Project Fuzz Tester (1.93).
// Program generated as:
diff --git a/tests/lib/developer/timeline_recorders_test.dart b/tests/lib/developer/timeline_recorders_test.dart
index 349cbba..2656f30 100644
--- a/tests/lib/developer/timeline_recorders_test.dart
+++ b/tests/lib/developer/timeline_recorders_test.dart
@@ -2,10 +2,10 @@
// 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.
-/// VMOptions=--timeline_streams=VM,Isolate,GC,Dart --timeline_recorder=endless
-/// VMOptions=--timeline_streams=VM,Isolate,GC,Dart --timeline_recorder=ring
-/// VMOptions=--timeline_streams=VM,Isolate,GC,Dart --timeline_recorder=startup
-/// VMOptions=--timeline_streams=VM,Isolate,GC,Dart --timeline_recorder=systrace
+// VMOptions=--timeline_streams=VM,Isolate,GC,Dart --timeline_recorder=endless
+// VMOptions=--timeline_streams=VM,Isolate,GC,Dart --timeline_recorder=ring
+// VMOptions=--timeline_streams=VM,Isolate,GC,Dart --timeline_recorder=startup
+// VMOptions=--timeline_streams=VM,Isolate,GC,Dart --timeline_recorder=systrace
import 'dart:developer';
diff --git a/tests/lib/js/static_interop_test/external_dart_reference_test.dart b/tests/lib/js/static_interop_test/external_dart_reference_test.dart
index 33108e4..98bce34 100644
--- a/tests/lib/js/static_interop_test/external_dart_reference_test.dart
+++ b/tests/lib/js/static_interop_test/external_dart_reference_test.dart
@@ -2,7 +2,7 @@
// 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.
-/// Requirements=checked-implicit-downcasts
+// Requirements=checked-implicit-downcasts
import 'dart:js_interop';
diff --git a/tests/lib/js/static_interop_test/js_function_arity_test.dart b/tests/lib/js/static_interop_test/js_function_arity_test.dart
index a7ee811..5befc7e 100644
--- a/tests/lib/js/static_interop_test/js_function_arity_test.dart
+++ b/tests/lib/js/static_interop_test/js_function_arity_test.dart
@@ -2,7 +2,7 @@
// 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.
-/// Requirements=checked-implicit-downcasts
+// Requirements=checked-implicit-downcasts
import 'dart:js_interop';
diff --git a/tests/lib/js/static_interop_test/js_function_conversions_test.dart b/tests/lib/js/static_interop_test/js_function_conversions_test.dart
index 9719735..f800fbe 100644
--- a/tests/lib/js/static_interop_test/js_function_conversions_test.dart
+++ b/tests/lib/js/static_interop_test/js_function_conversions_test.dart
@@ -2,7 +2,7 @@
// 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.
-/// Requirements=checked-implicit-downcasts
+// Requirements=checked-implicit-downcasts
// Test that Function.toJS properly converts/casts arguments and return values
// when using non-JS types.
diff --git a/tests/standalone/dwarf_stack_trace_invisible_functions_test.dart b/tests/standalone/dwarf_stack_trace_invisible_functions_test.dart
index cb155bb..da91c2e 100644
--- a/tests/standalone/dwarf_stack_trace_invisible_functions_test.dart
+++ b/tests/standalone/dwarf_stack_trace_invisible_functions_test.dart
@@ -2,7 +2,7 @@
// 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.
-/// VMOptions=--dwarf-stack-traces --save-debugging-info=$TEST_COMPILATION_DIR/dwarf_invisible_functions.so
+// VMOptions=--dwarf-stack-traces --save-debugging-info=$TEST_COMPILATION_DIR/dwarf_invisible_functions.so
import 'dart:io';
diff --git a/tests/standalone/dwarf_stack_trace_obfuscate_test.dart b/tests/standalone/dwarf_stack_trace_obfuscate_test.dart
index 01b5515..a6f09a7 100644
--- a/tests/standalone/dwarf_stack_trace_obfuscate_test.dart
+++ b/tests/standalone/dwarf_stack_trace_obfuscate_test.dart
@@ -2,7 +2,7 @@
// 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.
-/// VMOptions=--dwarf-stack-traces --save-debugging-info=$TEST_COMPILATION_DIR/dwarf_obfuscate.so --obfuscate
+// VMOptions=--dwarf-stack-traces --save-debugging-info=$TEST_COMPILATION_DIR/dwarf_obfuscate.so --obfuscate
import 'dart:io';
diff --git a/tests/standalone/dwarf_stack_trace_test.dart b/tests/standalone/dwarf_stack_trace_test.dart
index 53f35db..f6bfad8 100644
--- a/tests/standalone/dwarf_stack_trace_test.dart
+++ b/tests/standalone/dwarf_stack_trace_test.dart
@@ -2,7 +2,7 @@
// 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.
-/// VMOptions=--dwarf-stack-traces --save-debugging-info=$TEST_COMPILATION_DIR/dwarf.so
+// VMOptions=--dwarf-stack-traces --save-debugging-info=$TEST_COMPILATION_DIR/dwarf.so
import 'dart:convert';
import 'dart:io';
diff --git a/tests/standalone/regress31114_test.dart b/tests/standalone/regress31114_test.dart
index 2977a21..8f822ef 100644
--- a/tests/standalone/regress31114_test.dart
+++ b/tests/standalone/regress31114_test.dart
@@ -2,7 +2,7 @@
// 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.
-/// VMOptions=--background-compilation=false --optimization-counter-threshold=20
+// VMOptions=--background-compilation=false --optimization-counter-threshold=20
import 'pow_test.dart' as test;
diff --git a/tests/web/consistent_subtract_error_test.dart b/tests/web/consistent_subtract_error_test.dart
index a34f50f..2a131a2 100644
--- a/tests/web/consistent_subtract_error_test.dart
+++ b/tests/web/consistent_subtract_error_test.dart
@@ -2,7 +2,7 @@
// 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.
-/// dart2jsOptions=--omit-implicit-checks
+// dart2jsOptions=--omit-implicit-checks
import "package:expect/expect.dart";