Try DCM on test_core
diff --git a/analysis_options.yaml b/analysis_options.yaml index 0f13fc8..1d28e63 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml
@@ -11,3 +11,30 @@ - avoid_private_typedef_functions - directives_ordering - prefer_single_quotes + +dart_code_metrics: + rules: + - avoid-dynamic + # - avoid-passing-async-when-sync-expected + - avoid-redundant-async + # - avoid-unnecessary-type-assertions + - avoid-unnecessary-type-casts + - avoid-unrelated-type-assertions + - avoid-unused-parameters + - avoid-nested-conditional-expressions + # - newline-before-return + - no-boolean-literal-compare + # - no-empty-block + # - prefer-trailing-comma + - prefer-conditional-expressions + - no-equal-then-else + # - prefer-moving-to-variable + # - prefer-match-file-name + - avoid-collapsible-if + - avoid-redundant-else + - avoid-incomplete-copy-with + - avoid-self-compare + - avoid-self-assignment + - avoid-unnecessary-nullable-return-type + - avoid-unrelated-type-casts + # - prefer-declaring-const-constructor
diff --git a/pkgs/test_core/lib/scaffolding.dart b/pkgs/test_core/lib/scaffolding.dart index ab1ec59..5a52440 100644 --- a/pkgs/test_core/lib/scaffolding.dart +++ b/pkgs/test_core/lib/scaffolding.dart
@@ -133,7 +133,7 @@ /// avoid this flag if possible and instead use the test runner flag `-n` to /// filter tests by name. @isTest -void test(description, dynamic Function() body, +void test(description, FutureOr<void> Function() body, {String? testOn, Timeout? timeout, skip, @@ -211,12 +211,12 @@ /// avoid this flag if possible, and instead use the test runner flag `-n` to /// filter tests by name. @isTestGroup -void group(description, dynamic Function() body, +void group(description, void Function() body, {String? testOn, Timeout? timeout, skip, tags, - Map<String, dynamic>? onPlatform, + Map<String, Object>? onPlatform, int? retry, @Deprecated('Debug only') bool solo = false}) { _declarer.group(description.toString(), body, @@ -246,7 +246,7 @@ /// /// Each callback at the top level or in a given group will be run in the order /// they were declared. -void setUp(dynamic Function() callback) => _declarer.setUp(callback); +void setUp(FutureOr<void> Function() callback) => _declarer.setUp(callback); /// Registers a function to be run after tests. /// @@ -261,7 +261,8 @@ /// reverse of the order they were declared. /// /// See also [addTearDown], which adds tear-downs to a running test. -void tearDown(dynamic Function() callback) => _declarer.tearDown(callback); +void tearDown(FutureOr<void> Function() callback) => + _declarer.tearDown(callback); /// Registers a function to be run once before all tests. /// @@ -276,7 +277,8 @@ /// dependencies between tests that should be isolated. In general, you should /// prefer [setUp], and only use [setUpAll] if the callback is prohibitively /// slow. -void setUpAll(dynamic Function() callback) => _declarer.setUpAll(callback); +void setUpAll(FutureOr<void> Function() callback) => + _declarer.setUpAll(callback); /// Registers a function to be run once after all tests. /// @@ -289,5 +291,5 @@ /// dependencies between tests that should be isolated. In general, you should /// prefer [tearDown], and only use [tearDownAll] if the callback is /// prohibitively slow. -void tearDownAll(dynamic Function() callback) => +void tearDownAll(FutureOr<void> Function() callback) => _declarer.tearDownAll(callback);
diff --git a/pkgs/test_core/lib/src/executable.dart b/pkgs/test_core/lib/src/executable.dart index 0c7530b..e2e0662 100644 --- a/pkgs/test_core/lib/src/executable.dart +++ b/pkgs/test_core/lib/src/executable.dart
@@ -29,9 +29,8 @@ return Platform.environment['DART_TEST_CONFIG']!; } else if (Platform.operatingSystem == 'windows') { return p.join(Platform.environment['LOCALAPPDATA']!, 'DartTest.yaml'); - } else { - return '${Platform.environment['HOME']}/.dart_test.yaml'; } + return '${Platform.environment['HOME']}/.dart_test.yaml'; }(); Future<void> main(List<String> args) async { @@ -60,12 +59,15 @@ /// Signals will only be captured as long as this has an active subscription. /// Otherwise, they'll be handled by Dart's default signal handler, which /// terminates the program immediately. - final signals = Platform.isWindows - ? ProcessSignal.sigint.watch() - : Platform.isFuchsia // Signals don't exist on Fuchsia. - ? Stream.empty() - : StreamGroup.merge( - [ProcessSignal.sigterm.watch(), ProcessSignal.sigint.watch()]); + final Stream signals; + if (Platform.isWindows) { + signals = ProcessSignal.sigint.watch(); + } else if (Platform.isFuchsia) { + signals = Stream.empty(); + } else { + signals = StreamGroup.merge( + [ProcessSignal.sigterm.watch(), ProcessSignal.sigint.watch()]); + } Configuration configuration; try { @@ -139,9 +141,9 @@ Runner? runner; - signalSubscription ??= signals.listen((signal) async { + signalSubscription ??= signals.listen((signal) { completeShutdown(); - await runner?.close(); + runner?.close(); }); try {
diff --git a/pkgs/test_core/lib/src/runner.dart b/pkgs/test_core/lib/src/runner.dart index 0553136..068f9f5 100644 --- a/pkgs/test_core/lib/src/runner.dart +++ b/pkgs/test_core/lib/src/runner.dart
@@ -149,9 +149,8 @@ 'No tests match the requested tag selectors:\n' ' include: "${_config.includeTags}"\n' ' exclude: "${_config.excludeTags}"'); - } else { - throw NoTestsFoundException('No tests were found.'); } + throw NoTestsFoundException('No tests were found.'); } return (success ?? false) && @@ -264,14 +263,13 @@ return _loader.loadDir(testPath, suiteConfig); } else if (File(testPath).existsSync()) { return _loader.loadFile(testPath, suiteConfig); - } else { - return Stream.fromIterable([ - LoadSuite.forLoadException( - LoadException(testPath, 'Does not exist.'), - suiteConfig, - ), - ]); } + return Stream.fromIterable([ + LoadSuite.forLoadException( + LoadException(testPath, 'Does not exist.'), + suiteConfig, + ), + ]); })).map((loadSuite) { return loadSuite.changeSuite((suite) { _warnForUnknownTags(suite); @@ -283,13 +281,14 @@ return false; } + final isInTags = test.metadata.tags.contains; // If the user provided tags, skip tests that don't match all of them. - if (!_config.includeTags.evaluate(test.metadata.tags.contains)) { + if (!_config.includeTags.evaluate(isInTags)) { return false; } // Skip tests that do match any tags the user wants to exclude. - if (_config.excludeTags.evaluate(test.metadata.tags.contains)) { + if (_config.excludeTags.evaluate(isInTags)) { return false; }
diff --git a/pkgs/test_core/lib/src/runner/compiler_selection.dart b/pkgs/test_core/lib/src/runner/compiler_selection.dart index 5f7df78..70ab553 100644 --- a/pkgs/test_core/lib/src/runner/compiler_selection.dart +++ b/pkgs/test_core/lib/src/runner/compiler_selection.dart
@@ -46,7 +46,7 @@ } @override - bool operator ==(other) => + bool operator ==(Object other) => other is CompilerSelection && other.compiler == compiler; @override
diff --git a/pkgs/test_core/lib/src/runner/configuration/args.dart b/pkgs/test_core/lib/src/runner/configuration/args.dart index c31a253..56a9b25 100644 --- a/pkgs/test_core/lib/src/runner/configuration/args.dart +++ b/pkgs/test_core/lib/src/runner/configuration/args.dart
@@ -188,13 +188,11 @@ void _parseTestSelection( String option, Map<String, Set<TestSelection>> selections) { - if (Platform.isWindows) { - // If given a path that starts with what looks like a drive letter, convert it - // into a file scheme URI. We can't parse using `Uri.file` because we do + if (Platform.isWindows && option.indexOf(':') == 1) { + // If given a path that starts with what looks like a drive letter, convert + // it into a file scheme URI. We can't parse using `Uri.file` because we do // support query parameters which aren't valid file uris. - if (option.indexOf(':') == 1) { - option = 'file:///$option'; - } + option = 'file:///$option'; } final uri = Uri.parse(option); // Decode the path segment. Specifically, on github actions back slashes on
diff --git a/pkgs/test_core/lib/src/runner/configuration/load.dart b/pkgs/test_core/lib/src/runner/configuration/load.dart index 02073cd..739b0eb 100644 --- a/pkgs/test_core/lib/src/runner/configuration/load.dart +++ b/pkgs/test_core/lib/src/runner/configuration/load.dart
@@ -452,7 +452,7 @@ /// Throws an exception with [message] if [test] returns `false` when passed /// [node]'s value. - void _validate(YamlNode node, String message, bool Function(dynamic) test) { + void _validate(YamlNode node, String message, bool Function(Object?) test) { if (test(node.value)) return; throw SourceSpanFormatException(message, node.span, _source); } @@ -462,7 +462,7 @@ /// If [typeTest] returns `false` for that value, instead throws an error /// complaining that the field is not a [typeName]. Object? _getValue( - String field, String typeName, bool Function(dynamic) typeTest) { + String field, String typeName, bool Function(Object?) typeTest) { var value = _document[field]; if (value == null || typeTest(value)) return value; _error('$field must be ${a(typeName)}.', field); @@ -475,7 +475,7 @@ /// /// Returns `null` if [field] does not have a node in [_document]. YamlNode? _getNode( - String field, String typeName, bool Function(dynamic) typeTest) { + String field, String typeName, bool Function(Object?) typeTest) { var node = _document.nodes[field]; if (node == null) return null; _validate(node, '$field must be ${a(typeName)}.', typeTest); @@ -625,10 +625,9 @@ if (presets.isEmpty) { return base.isEmpty ? Configuration.empty : create(base); - } else { - var newPresets = presets.map((key, map) => MapEntry(key, create(map))); - return create(base).change(presets: newPresets); } + var newPresets = presets.map((key, map) => MapEntry(key, create(map))); + return create(base).change(presets: newPresets); } /// Asserts that [map] has a field named [field] and returns it.
diff --git a/pkgs/test_core/lib/src/runner/configuration/reporters.dart b/pkgs/test_core/lib/src/runner/configuration/reporters.dart index d52f163..71acdf3 100644 --- a/pkgs/test_core/lib/src/runner/configuration/reporters.dart +++ b/pkgs/test_core/lib/src/runner/configuration/reporters.dart
@@ -60,13 +60,12 @@ JsonReporter.watch(engine, sink, isDebugRun: config.debug)), }; -final defaultReporter = inTestTests - ? 'expanded' - : inGithubContext - ? 'github' - : canUseSpecialChars - ? 'compact' - : 'expanded'; +final defaultReporter = () { + if (inTestTests) return 'expanded'; + if (inGithubContext) return 'github'; + if (canUseSpecialChars) return 'compact'; + return 'expanded'; +}(); /// **Do not call this function without express permission from the test package /// authors**.
diff --git a/pkgs/test_core/lib/src/runner/console.dart b/pkgs/test_core/lib/src/runner/console.dart index b716aad..21fde3c 100644 --- a/pkgs/test_core/lib/src/runner/console.dart +++ b/pkgs/test_core/lib/src/runner/console.dart
@@ -49,7 +49,7 @@ /// in the help output. The [body] callback will be called when the user types /// the command, and may return a [Future]. void registerCommand( - String name, String description, dynamic Function() body) { + String name, String description, Object? Function() body) { if (_commands.containsKey(name)) { throw ArgumentError('The console already has a command named "$name".'); }
diff --git a/pkgs/test_core/lib/src/runner/coverage_stub.dart b/pkgs/test_core/lib/src/runner/coverage_stub.dart index 64f69c7..d939db3 100644 --- a/pkgs/test_core/lib/src/runner/coverage_stub.dart +++ b/pkgs/test_core/lib/src/runner/coverage_stub.dart
@@ -4,7 +4,6 @@ import 'live_suite_controller.dart'; -Future<void> writeCoverage( - String coveragePath, LiveSuiteController controller) => +Future<void> writeCoverage(String _, LiveSuiteController __) => throw UnsupportedError( 'Coverage is only supported through the test runner.');
diff --git a/pkgs/test_core/lib/src/runner/hybrid_listener.dart b/pkgs/test_core/lib/src/runner/hybrid_listener.dart index bf2daa2..2b738e4 100644 --- a/pkgs/test_core/lib/src/runner/hybrid_listener.dart +++ b/pkgs/test_core/lib/src/runner/hybrid_listener.dart
@@ -14,7 +14,7 @@ /// A sink transformer that wraps data and error events so that errors can be /// decoded after being JSON-serialized. -final _transformer = StreamSinkTransformer<dynamic, dynamic>.fromHandlers( +final _transformer = StreamSinkTransformer<Object?, Object?>.fromHandlers( handleData: (data, sink) { ensureJsonEncodable(data); sink.add({'type': 'data', 'data': data}); @@ -38,7 +38,7 @@ Chain.capture(() { runZoned(() { - dynamic /*Function*/ main; + Object /*Function*/ main; try { main = getMain(); } on NoSuchMethodError catch (_) { @@ -80,10 +80,9 @@ }, zoneSpecification: ZoneSpecification(print: (_, __, ___, line) { channel.sink.add({'type': 'print', 'line': line}); })); - }, onError: (error, stackTrace) async { + }, onError: (error, stackTrace) { _sendError(channel, error, stackTrace); - await channel.sink.close(); - Isolate.current.kill(); + channel.sink.close().whenComplete(Isolate.current.kill); }); }
diff --git a/pkgs/test_core/lib/src/runner/parse_metadata.dart b/pkgs/test_core/lib/src/runner/parse_metadata.dart index 8dc60e6..32747ac 100644 --- a/pkgs/test_core/lib/src/runner/parse_metadata.dart +++ b/pkgs/test_core/lib/src/runner/parse_metadata.dart
@@ -57,13 +57,8 @@ // We explicitly *don't* just look for "package:test" imports here, // because it could be re-exported from another library. _prefixes = directives - .map((directive) { - if (directive is ImportDirective) { - return directive.prefix?.name; - } else { - return null; - } - }) + .map((directive) => + directive is ImportDirective ? directive.prefix?.name : null) .whereType<String>() .toSet(); } @@ -164,7 +159,7 @@ /// [annotation] is the annotation. /// /// Returns either `true` or a reason string. - dynamic _parseSkip(Annotation annotation) { + Object? _parseSkip(Annotation annotation) { var args = annotation.arguments!.arguments; return args.isEmpty ? true : _parseString(args.first).stringValue; } @@ -172,7 +167,7 @@ /// Parses a `Skip` constructor. /// /// Returns either `true` or a reason string. - dynamic _parseSkipConstructor(Expression constructor) { + Object? _parseSkipConstructor(Expression constructor) { _findConstructorName(constructor, 'Skip'); var arguments = _parseArguments(constructor); return arguments.isEmpty ? true : _parseString(arguments.first).stringValue; @@ -415,17 +410,16 @@ var target = constructor.target; // Example: `SomeOtherClass()` if (target == null) return null; - if (target is SimpleIdentifier) { + if (target is SimpleIdentifier && candidates.contains(target.name)) { // Example: `Timeout.factor()` - if (candidates.contains(target.name)) return target.name; + return target.name; } - if (target is PrefixedIdentifier) { + if (target is PrefixedIdentifier && + candidates.contains(target.identifier.name)) { // Looks like `some_prefix.SomeTarget.someMethod` - "SomeTarget" is the // only potential type name. // Example: `test.Timeout.factor()` - if (candidates.contains(target.identifier.name)) { - return target.identifier.name; - } + return target.identifier.name; } return null; }
diff --git a/pkgs/test_core/lib/src/runner/reporter/compact.dart b/pkgs/test_core/lib/src/runner/reporter/compact.dart index 962213f..462aede 100644 --- a/pkgs/test_core/lib/src/runner/reporter/compact.dart +++ b/pkgs/test_core/lib/src/runner/reporter/compact.dart
@@ -252,7 +252,7 @@ } /// A callback called when [liveTest] throws [error]. - void _onError(LiveTest liveTest, error, StackTrace stackTrace) { + void _onError(LiveTest liveTest, Object error, StackTrace stackTrace) { if (!liveTest.test.metadata.chainStackTraces && !liveTest.suite.isLoadSuite) { _shouldPrintStackTraceChainingNotice = true;
diff --git a/pkgs/test_core/lib/src/runner/reporter/expanded.dart b/pkgs/test_core/lib/src/runner/reporter/expanded.dart index d16252c..afaf066 100644 --- a/pkgs/test_core/lib/src/runner/reporter/expanded.dart +++ b/pkgs/test_core/lib/src/runner/reporter/expanded.dart
@@ -189,7 +189,7 @@ } /// A callback called when [liveTest]'s state becomes [state]. - void _onStateChange(LiveTest liveTest, State state) { + void _onStateChange(LiveTest _, State state) { if (state.status != Status.complete) return; // If any tests are running, display the name of the oldest active @@ -200,7 +200,7 @@ } /// A callback called when [liveTest] throws [error]. - void _onError(LiveTest liveTest, error, StackTrace stackTrace) { + void _onError(LiveTest liveTest, Object error, StackTrace stackTrace) { if (!liveTest.test.metadata.chainStackTraces && !liveTest.suite.isLoadSuite) { _shouldPrintStackTraceChainingNotice = true;
diff --git a/pkgs/test_core/lib/src/runner/reporter/github.dart b/pkgs/test_core/lib/src/runner/reporter/github.dart index 5249817..ae9307c 100644 --- a/pkgs/test_core/lib/src/runner/reporter/github.dart +++ b/pkgs/test_core/lib/src/runner/reporter/github.dart
@@ -133,23 +133,27 @@ // For now, we use the same icon for both tests and test-like structures // (loadSuite, setUpAll, tearDownAll). - var defaultIcon = synthetic ? _GithubMarkup.passed : _GithubMarkup.passed; - final prefix = failed - ? _GithubMarkup.failed - : skipped - ? _GithubMarkup.skipped - : defaultIcon; - final statusSuffix = failed - ? ' (failed)' - : skipped - ? ' (skipped)' - : ''; + var defaultIcon = _GithubMarkup.passed; + final String prefix; + if (failed) { + prefix = _GithubMarkup.failed; + } else if (skipped) { + prefix = _GithubMarkup.skipped; + } else { + prefix = defaultIcon; + } + final String statusSuffix; + if (failed) { + statusSuffix = ' (failed)'; + } else if (skipped) { + statusSuffix = ' (skipped)'; + } else { + statusSuffix = ''; + } var name = test.test.name; - if (!loadSuite) { - if (_printPath && test.suite.path != null) { - name = '${test.suite.path}: $name'; - } + if (!loadSuite && _printPath && test.suite.path != null) { + name = '${test.suite.path}: $name'; } if (_printPlatform) { name = '[${test.suite.platform.runtime.name}, ' @@ -179,10 +183,8 @@ final statusSuffix = ' (failed after test completion)'; var name = test.test.name; - if (!loadSuite) { - if (_printPath && test.suite.path != null) { - name = '${test.suite.path}: $name'; - } + if (!loadSuite && _printPath && test.suite.path != null) { + name = '${test.suite.path}: $name'; } if (_printPlatform) { name = '[${test.suite.platform.runtime.name}, '
diff --git a/pkgs/test_core/lib/src/runner/reporter/json.dart b/pkgs/test_core/lib/src/runner/reporter/json.dart index 5497817..fa98583 100644 --- a/pkgs/test_core/lib/src/runner/reporter/json.dart +++ b/pkgs/test_core/lib/src/runner/reporter/json.dart
@@ -261,7 +261,7 @@ } /// A callback called when [liveTest] throws [error]. - void _onError(LiveTest liveTest, error, StackTrace stackTrace) { + void _onError(LiveTest liveTest, Object error, StackTrace stackTrace) { _emit('error', { 'testID': _liveTestIDs[liveTest], 'error': error.toString(),
diff --git a/pkgs/test_core/lib/src/runner/runtime_selection.dart b/pkgs/test_core/lib/src/runner/runtime_selection.dart index e607400..7f64a5c 100644 --- a/pkgs/test_core/lib/src/runner/runtime_selection.dart +++ b/pkgs/test_core/lib/src/runner/runtime_selection.dart
@@ -17,7 +17,8 @@ RuntimeSelection(this.name, [this.span]); @override - bool operator ==(other) => other is RuntimeSelection && other.name == name; + bool operator ==(Object other) => + other is RuntimeSelection && other.name == name; @override int get hashCode => name.hashCode;
diff --git a/pkgs/test_core/lib/src/runner/spawn_hybrid.dart b/pkgs/test_core/lib/src/runner/spawn_hybrid.dart index e49f63e..f71b5b9 100644 --- a/pkgs/test_core/lib/src/runner/spawn_hybrid.dart +++ b/pkgs/test_core/lib/src/runner/spawn_hybrid.dart
@@ -100,12 +100,11 @@ // to pass in an explicit root. return p.url .join(p.toUri(p.current).toString(), parsedUri.path.substring(1)); - } else { - var suitePath = suite.path!; - return p.url.join( - p.url.dirname(p.toUri(p.absolute(suitePath)).toString()), - parsedUri.toString()); } + var suitePath = suite.path!; + return p.url.join( + p.url.dirname(p.toUri(p.absolute(suitePath)).toString()), + parsedUri.toString()); case 'package': final resolvedUri = await Isolate.resolvePackageUri(parsedUri); if (resolvedUri == null) {
diff --git a/pkgs/test_core/lib/src/runner/suite.dart b/pkgs/test_core/lib/src/runner/suite.dart index c5175b6..8de04a5 100644 --- a/pkgs/test_core/lib/src/runner/suite.dart +++ b/pkgs/test_core/lib/src/runner/suite.dart
@@ -445,9 +445,8 @@ if (selection.span != null) { throw SourceSpanFormatException( 'Unknown platform "${selection.name}".', selection.span); - } else { - throw FormatException('Unknown platform "${selection.name}".'); } + throw FormatException('Unknown platform "${selection.name}".'); } } }
diff --git a/pkgs/test_core/lib/src/runner/version.dart b/pkgs/test_core/lib/src/runner/version.dart index 3eab242..f62781c 100644 --- a/pkgs/test_core/lib/src/runner/version.dart +++ b/pkgs/test_core/lib/src/runner/version.dart
@@ -11,7 +11,7 @@ /// This is a semantic version, optionally followed by a space and additional /// data about its source. final String? testVersion = (() { - dynamic lockfile; + Object? lockfile; try { lockfile = loadYaml(File('pubspec.lock').readAsStringSync()); } on FormatException catch (_) {
diff --git a/pkgs/test_core/lib/src/runner/vm/platform.dart b/pkgs/test_core/lib/src/runner/vm/platform.dart index 0a84023..61e939a 100644 --- a/pkgs/test_core/lib/src/runner/vm/platform.dart +++ b/pkgs/test_core/lib/src/runner/vm/platform.dart
@@ -51,7 +51,7 @@ _setupPauseAfterTests(); MultiChannel outerChannel; - var cleanupCallbacks = <void Function()>[]; + var cleanupCallbacks = <FutureOr<void> Function()>[]; Isolate? isolate; if (platform.compiler == Compiler.exe) { var serverSocket = await ServerSocket.bind('localhost', 0); @@ -101,7 +101,7 @@ await outerQueue.next; } for (var fn in cleanupCallbacks) { - fn(); + await fn(); } eventSub?.cancel(); client?.dispose();
diff --git a/pkgs/test_core/lib/src/util/async.dart b/pkgs/test_core/lib/src/util/async.dart index 422de0e..42ad7d2 100644 --- a/pkgs/test_core/lib/src/util/async.dart +++ b/pkgs/test_core/lib/src/util/async.dart
@@ -31,4 +31,4 @@ return controller.stream; } -void unawaited(Future<void> f) {} +void unawaited(Future<void> _) {}
diff --git a/pkgs/test_core/lib/src/util/io_stub.dart b/pkgs/test_core/lib/src/util/io_stub.dart index 7953877..ded2c0f 100644 --- a/pkgs/test_core/lib/src/util/io_stub.dart +++ b/pkgs/test_core/lib/src/util/io_stub.dart
@@ -6,6 +6,6 @@ import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports import 'package:test_api/src/backend/suite_platform.dart'; // ignore: implementation_imports -SuitePlatform currentPlatform(Runtime runtime, Compiler? compiler) => +SuitePlatform currentPlatform(Runtime _, Compiler? __) => throw UnsupportedError( 'Getting the current platform is only supported where dart:io exists');
diff --git a/pkgs/test_core/lib/src/util/pair.dart b/pkgs/test_core/lib/src/util/pair.dart index 61dcff7..89a3d14 100644 --- a/pkgs/test_core/lib/src/util/pair.dart +++ b/pkgs/test_core/lib/src/util/pair.dart
@@ -13,7 +13,7 @@ String toString() => '($first, $last)'; @override - bool operator ==(other) { + bool operator ==(Object other) { if (other is! Pair) return false; return other.first == first && other.last == last; }