install
source · Clone the upstream repo
git clone https://github.com/kevmoo/dash_skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/kevmoo/dash_skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.agent/skills/dart-checks-migration" ~/.claude/skills/kevmoo-dash-skills-dart-checks-migration && rm -rf "$T"
manifest:
.agent/skills/dart-checks-migration/SKILL.mdsource content
Dart Checks Migration
When to use this skill
Use this skill when:
- Migrating existing test files from
topackage:matcher
.package:checks - A user specifically asks for "modern checks" or similar.
The Workflow
- Analysis:
- Use
to identify files usinggrep
orexpect
.package:matcher - Review custom matchers; these may require manual migration.
- Use
- Tools & Dependencies:
- Ensure
includesdev_dependencies
.checks - Run
if missing.dart pub add --dev checks
- Ensure
- Discovery:
- Use the Strategies for Discovery below to find candidates.
- Replacement:
- Add
.import 'package:checks/checks.dart'; - Apply the Common Patterns below.
- Final Step: Replace
withimport 'package:test/test.dart';
ONLY after allimport 'package:test/scaffolding.dart';
calls are replaced. This ensures incremental progress.expect
- Add
- Verification:
- Ensure the code analyzes cleanly.
- Ensure tests pass.
Common Patterns
Legacy | Modern |
|---|---|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
Async & Futures (CRITICAL)
-
Checking async functions:
causes FALSE POSITIVES because the closure returns acheck(() => asyncFunc()).throws<T>()
, which is a value, so it "completes normally" (as a Future). Correct Usage:Futureawait check(asyncFunc()).throws<T>(); -
Chaining on void returns: Many async check methods (like
) returnthrows
. You cannot chain directly on them. Use cascades or callbacks. Wrong:Future<void>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'));
Complex Examples
Deep Verification with
and isA
: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);
Constraints
- Scope: Only modify files in
(andtest/
).pubspec.yaml - Correctness: One failing test is unacceptable. If a test fails after migration and you cannot fix it immediately, REVERT that specific change.
- Type Safety:
is stricter about types thanpackage:checks
. You may need to add explicitmatcher
casts oras T
checks in the chain.isA<T>()
Related Skills
- dart-test-fundamentals: Core concepts for structuring tests, lifecycles, and configuration.
- dart-matcher-best-practices:
Best practices for the traditional
that is being migrated away from.package:matcher