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
MyWidget
is 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
ParentWidget
is 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
ParentWidget
is 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.