Skip to content
Development
Skill

/dart-migrate-to-checks-package

Replace the usage of `expect` and similar functions from `package:matcher` to `package:checks` equivalents.

From plugin
dart-flutter
2.8k24 skills1 MCP
Install
$ npx -y skills add flutter/agent-plugins --skill dart-migrate-to-checks-package --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/dart-migrate-to-checks-package

Context preview

The summary Claude sees to decide when to auto-load this skill.

Replace the usage of `expect` and similar functions from `package:matcher` to `package:checks` equivalents.

SKILL.md

dart-migrate-to-checks-package.SKILL.md
name: dart-migrate-to-checks-package
description: |-
  Replace the usage of `expect` and similar functions from `package:matcher`
  to `package:checks` equivalents.
metadata:
  model: models/gemini-3.1-pro-preview
  last_modified: Tue, 09 Jun 2026 19:30:00 GMT

Migrating Dart Tests to Package Checks

Use this skill when you need to migrate a Dart test suite from the legacy `package:matcher` (which is exported by default from `package:test/test.dart`) to the modern, type-safe, and literate `package:checks` assertion library.

Contents

  • [When to Use This Skill](#when-to-use-this-skill)
  • [How to Use This Skill (The Workflow)](#how-to-use-this-skill-the-workflow)
  • [Key Syntax Differences and Pitfalls](#key-syntax-differences-and-pitfalls)
  • [Matcher-to-Checks Mapping Table](#matcher-to-checks-mapping-table)
  • [Matchers with No Direct Replacements](#matchers-with-no-direct-replacements)
  • [Strategies for Discovery](#strategies-for-discovery)
  • [Examples](#examples)

---

When to Use This Skill

  • When asked to "migrate tests to checks", "use package:checks", or

"modernize test assertions".

  • When updating legacy test suites where static type safety, better

autocomplete in IDEs, and highly detailed failure diagnostics are desired.

---

How to Use This Skill (The Workflow)

Follow this structured workflow to safely and systematically migrate a test suite:

1. Dependency Setup

  • Add `package:checks` as a `dev_dependency` in `pubspec.yaml`:
  dart pub add dev:checks
  • Remove `package:matcher` if it is explicitly listed under `dev_dependencies`

(it is typically transitively included by `package:test`, which is fine).

2. Identify and Plan Target Files

  • Use the grep patterns in [Strategies for Discovery](#strategies-for-discovery)

to locate all test files containing legacy `expect` or `expectLater` calls.

  • Decide whether to migrate files fully or incrementally.

3. Migrating a File (Incremental or Full)

For any target test file: 1. **Update Imports**:

  • Replace the generic `import 'package:test/test.dart';` with:
     import 'package:test/scaffolding.dart';
     import 'package:checks/checks.dart';
  • **For Incremental Migration**: If you only want to migrate some test cases

in the file, or want to migrate one step at a time, add:

     import 'package:test/expect.dart'; // Temporarily allows legacy expect()

2. **Translate Assertions**: Rewrite legacy `expect` and `expectLater` calls to `check` syntax following the [Key Syntax Differences and Pitfalls](#key-syntax-differences-and-pitfalls) and the [Matcher-to-Checks Mapping Table](#matcher-to-checks-mapping-table). 3. **Verify via Compiler**: If migrating fully, remove the `import 'package:test/expect.dart';` line. Any remaining un-migrated `expect` calls will immediately surface as compiler errors, making them easy to find and fix.

4. Verification and Feedback Loops

  • **Static Analysis**: Run static analysis on the target package:
  dart analyze

Pay close attention to generic type parameters on `.isA<Type>()` and ensure asynchronous expectations are properly awaited (check for `unawaited_futures` warnings).

  • **Run Tests**: Execute the tests to verify both behavior and correct

assertion runtime logic:

  dart test

If a test fails, review the extremely detailed failure output of `package:checks` to diagnose if the test is genuinely failing or if the expectation was translated incorrectly.

---

Key Syntax Differences and Pitfalls

> [!IMPORTANT] > A line-for-line translation can sometimes introduce subtle bugs or false > passes. Always review these key differences carefully:

1. Collection Equality Pitfall (`equals` vs `deepEquals`)

  • **Legacy Matcher**: `expect(actual, expected)` or `expect(actual,

equals(expected))` performed a **deep equality check** if the arguments were collections (Lists, Maps, Sets).

  • **Package Checks**: `.equals(expected)` corresponds strictly to

`operator ==`. Since Dart collections do not override `operator ==` for element-wise comparison, using `.equals` on a collection will check for *identity* and almost certainly fail at runtime.

  • **Remediation**: You **must** replace collection equality assertions with

`.deepEquals(expected)`.

  // BEFORE (Matcher)
  expect(myList, [1, 2, 3]);

  // AFTER (Checks)
  check(myList).deepEquals([1, 2, 3]);

2. The `reason` Parameter is now `because`

  • **Legacy Matcher**: The explanation was passed as a trailing named

argument `reason` to `expect`:

  expect(actual, expectation, reason: 'Explanation');
  • **Package Checks**: The explanation is passed as the named argument

`because` to the `check` function *before* the actual subject:

  check(because: 'Explanation', actual).expectation();

3. Regular Expression Matching (`matches` vs `matchesPattern`)

  • **Legacy Matcher**: The `matches(pattern)` matcher automatically converted

a `String` argument into a `RegExp` (e.g., `matches(r'\d')` matched `'1'`).

  • **Package Checks**: `.matchesPattern(pattern)` treats a `String` argument

as a literal string pattern.

  • **Remediation**: To match using a regular expression, you must explicitly

pass a `RegExp` object:

  // BEFORE (Matcher)
  expect(someString, matches(r'\d+'));

  // AFTER (Checks)
  check(someString).matchesPattern(RegExp(r'\d+'));

4. Property Extraction (`TypeMatcher.having` vs `.has`)

  • **Legacy Matcher**: Chained field/property expectations used

`TypeMatcher.having(feature, description, matcher)`:

  expect(actual, isA<Person>().having((p) => p.name, 'name', startsWith('A')));
  • **Package Checks**: The `.has(feature, description)` extension is

available on all `Subject`s, takes one fewer argument, and returns a new `Subject` representing that property. You chain expectations directly

Read more
Ships withdart-flutter

Agent plugins for Flutter, maintained by the Flutter team. A collection of plugins designed to extend AI agent capabilities for Flutter development.

Get the whole plugin