Annotate the main() function of your test file with the @Match annotation. Pass a list of MatchWidget to the matchers param to generate a matcher counterpart.
@Match(matchers: [
MatchWidget(MyWidget, MatchSpecification.hasAncestorOf, secondaryType: Dialog),
])
void main() {
//Test code in here
}
A ${my_test_file}.matchers.dart is created after a successful build_runner build. It contains generated custom matcher code. The generated custom matchers are private by default and expose a global variable or function for use.
You can generate different matchers for the same widget, by passing different instances of MatchWidget with same widget type and different MatchSpecification to the @Match annotation.
@Match(matchers: [
MatchWidget(MyWidget, MatchSpecification.matchesOneWidget),
MatchWidget(MyWidget, MatchSpecification.hasAncestorOf, secondaryType: Dialog),
])
void main() {
//Test code in here
}
There are several test cases to assert a widget. The enum MatchSpecification is provided to specify the generated matcher assertion case. The following sections summarises the MatchSpecification values that can be set.
Set MatchSpecification.matchesOneWidget to generate a matcher that asserts exactly one widget with specified properties is found in the widget tree.
The code below shows the format of the exposed function or variable:
final matchesOneMyWidget = _MyWidgetOneMatcher();
Where
MyWidgetis the name of the widget
Pass generated matcher to the second param of the expect() function.
expect(finder, matchesOneMyWidget);
Set MatchSpecification.matchesNoWidget to generate a matcher that asserts no widget with specified properties is found in the widget tree.
The code below shows the format of the exposed function or variable:
final matchesNoMyWidget = _MyWidgetNoneMatcher();
Pass generated matcher to the second param of the expect() function.
expect(finder, matchesNoMyWidget);
Set MatchSpecification.matchesAtleastOneWidget to generate a matcher that asserts at least one widget with specified properties is found in the widget tree.
The code below shows the format of the exposed function or variable:
final matchesAtleastOneMyWidget = _MyWidgetAtleastOneMatcher();
Pass generated matcher to the second param of the expect() function.
expect(finder, matchesAtleastOneMyWidget);
Set MatchSpecification.matchesNWidget to generate a matcher that asserts N number of widgets with specified properties are found in the widget tree.
The code below shows the format of the exposed function:
matchesNMyWidget(required int n) => _MyWidgetNMatcher(n: n);
Pass generated matcher to the second param of the expect() function passing in the expected count of widgets.
expect(finder, matchesNMyWidget(n: 5));
Set MatchSpecification.hasAncestorOf to generate a matcher that asserts MyWidget is in another specified widget.
By setting this specification, the secondaryType cannot be null. Pass the potential ancestor widget type as the secondaryType argument to the MatchWidget object.
The code below shows the format of the exposed function or variable:
final myWidgetHasAncestorOfParentWidget = _MyWidgetHasAncestorOfParentWidgetMatcher();
Where
ParentWidgetis the potential ancestor widget type.
Pass generated matcher to the second param of the expect() function.
expect(finder, myWidgetHasAncestorOfParentWidget);
Set MatchSpecification.doesNotHaveAncestorOf to generate a matcher that asserts that MyWidget is not in the specified widget.
By setting this specification, the secondaryType cannot be null. Pass the potential ancestor widget type as the secondaryType argument to the MatchWidget object.
The code below shows the format of the exposed function or variable:
final myWidgetDoesNotHaveAncestorOfParentWidget = _MyWidgetHasNoAncestorOfParentWidgetMatcher();
Where
ParentWidgetis the potential ancestor widget type.
Pass generated matcher to the second param of the expect() function.
expect(finder, myWidgetDoesNotHaveAncestorOfParentWidget);
The generated code will contain a constructor field for every declaration marked without a default value.
matchesOneMyWidget(String text) => _MyWidgetOneMatcher(text: text);
class _MyWidgetOneMatcher extends Matcher {
_MyWidgetOneMatcher({
required String text,
}) : _text = text;
final String _text;
...
}
In cases of a generic type widget, finder-gen-matcher takes this into account.
Assuming we have a generic widget.
class MyGenericWidget<K, V> extends StatelessWidget {
/// Widget code
}
The generated code header output will be:
matchesOneMyGenericWidget<K, V>() => _MyGenericWidgetOneMatcher<K, V>();
While running the command to generate files, you might encounter some build failures. The table below summarises the exceptions that are likely to be thrown during development to better equip you in resolving them.
| Triggers | Message |
|---|---|
Passing a non-widget class type to @Match annotation |
Unsupported class: Matcher can only be generated for widgets |
Applying @MatchDeclaration annotation on a method with parameters |
Unsupported: annotated method should have no parameter |
Applying @MatchDeclaration annotation on a private declaration |
Unsupported access modifier: Cannot utilise a private declaration |
Applying @MatchDeclaration annotation to a declaration that isn’t a field, getter, or method |
Unsupported entity annotated: Apply annotations to Fields, Methods, or Getters only |
To request a feature or file an issue check out the GitHub page.