skills/dart-checks-migration/SKILL.md
Replace the usage of `expect` and similar functions from `package:matcher` to `package:checks` equivalents.
npx skillsauth add boazcstrike/opencode dart-checks-migrationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use this skill when:
package:matcher to package:checks.grep to identify files using expect or package:matcher.dev_dependencies includes checks.dart pub add --dev checks if missing.import 'package:checks/checks.dart';.import 'package:test/test.dart'; with
import 'package:test/scaffolding.dart'; ONLY after all expect calls
are replaced. This ensures incremental progress.| Legacy expect | Modern check |
| :--- | :--- |
| expect(a, equals(b)) | check(a).equals(b) |
| expect(a, isTrue) | check(a).isTrue() |
| expect(a, isFalse) | check(a).isFalse() |
| expect(a, isNull) | check(a).isNull() |
| expect(a, isNotNull) | check(a).isNotNull() |
| expect(() => fn(), throwsA<T>()) | check(() => fn()).throws<T>() |
| expect(list, hasLength(n)) | check(list).length.equals(n) |
| expect(a, closeTo(b, delta)) | check(a).isA<num>().isCloseTo(b, delta) |
| expect(a, greaterThan(b)) | check(a).isGreaterThan(b) |
| expect(a, lessThan(b)) | check(a).isLessThan(b) |
| expect(list, isEmpty) | check(list).isEmpty() |
| expect(list, isNotEmpty) | check(list).isNotEmpty() |
| expect(list, contains(item)) | check(list).contains(item) |
| expect(map, equals(otherMap)) | check(map).deepEquals(otherMap) |
| expect(list, equals(otherList)) | check(list).deepEquals(otherList) |
| expect(future, completes) | await check(future).completes() |
| expect(stream, emitsInOrder(...)) | await check(stream).withQueue.inOrder(...) |
Checking async functions:
check(() => asyncFunc()).throws<T>() causes FALSE POSITIVES because the
closure returns a Future, which is a value, so it "completes normally"
(as a Future).
Correct Usage:
await check(asyncFunc()).throws<T>();
Chaining on void returns:
Many async check methods (like throws) return Future<void>. You cannot
chain directly on them. Use cascades or callbacks.
Wrong:
await check(future).throws<Error>().has((e) => e.message, 'message').equals('foo');
Correct:
await check(future).throws<Error>((it) => it.has((e) => e.message, 'message').equals('foo'));
Deep Verification with isA and having:*
Legacy:
expect(() => foo(), throwsA(isA<ArgumentError>()
.having((e) => e.message, 'message', contains('MSG'))));
Modern:
check(() => foo())
.throws<ArgumentError>()
.has((e) => e.message, 'message')
.contains('MSG');
Property Extraction:
Legacy:
expect(obj.prop, equals(value)); // When checking multiple props
Modern:
check(obj)
..has((e) => e.prop, 'prop').equals(value)
..has((e) => e.other, 'other').equals(otherValue);
One-line Cascades:
Since checks often return void, use cascades for multiple assertions on the
same subject.
check(it)..isGreaterThan(10)..isLessThan(20);
test/ (and pubspec.yaml).package:checks is stricter about types than matcher.
You may need to add explicit as T casts or isA<T>() checks in the chain.dart-test-fundamentals: Core
concepts for structuring tests, lifecycles, and configuration.dart-matcher-best-practices:
Best practices for the traditional package:matcher that is being migrated
away from.development
Google Workflow: Announce a Drive file in a Chat space.
development
Google Workflow: Convert a Gmail message into a Google Tasks entry.
development
Google Tasks: Manage task lists and tasks.
development
Google Slides: Read and write presentations.