Commit 995fcdc9 authored by Yegor's avatar Yegor Committed by GitHub

add description to by-predicate finders (#6362)

Add an option to provide a custom description to predicate
finders. Without a custom description we default to printing the
predicate function's signature, which is not all that useful.

Use this new option in the driver extension to print the text of the
sought after tooltip.
parent 08ba8dc4
......@@ -163,7 +163,7 @@ class FlutterDriverExtension {
if (widget is Tooltip)
return widget.message == arguments.text;
return false;
});
}, description: 'widget with text tooltip "${arguments.text}"');
}
Finder _createByValueKeyFinder(ByValueKey arguments) {
......
......@@ -110,18 +110,24 @@ class CommonFinders {
/// nodes that are [Offstage] or that are from inactive [Route]s.
Finder byConfig(Widget config, { bool skipOffstage: true }) => new _ConfigFinder(config, skipOffstage: skipOffstage);
/// Finds widgets using a widget predicate.
/// Finds widgets using a widget [predicate].
///
/// Example:
///
/// expect(tester, hasWidget(find.byWidgetPredicate(
/// (Widget widget) => widget is Tooltip && widget.message == 'Back'
/// (Widget widget) => widget is Tooltip && widget.message == 'Back',
/// description: 'widget with tooltip "Back"',
/// )));
///
/// If [description] is provided, then this uses it as the description of the
/// [Finder] and appears, for example, in the error message when the finder
/// fails to locate the desired widget. Otherwise, the description prints the
/// signature of the predicate function.
///
/// If the `skipOffstage` argument is true (the default), then this skips
/// nodes that are [Offstage] or that are from inactive [Route]s.
Finder byWidgetPredicate(WidgetPredicate predicate, { bool skipOffstage: true }) {
return new _WidgetPredicateFinder(predicate, skipOffstage: skipOffstage);
Finder byWidgetPredicate(WidgetPredicate predicate, { String description, bool skipOffstage: true }) {
return new _WidgetPredicateFinder(predicate, description: description, skipOffstage: skipOffstage);
}
/// Finds Tooltip widgets with the given message.
......@@ -139,7 +145,7 @@ class CommonFinders {
);
}
/// Finds widgets using an element predicate.
/// Finds widgets using an element [predicate].
///
/// Example:
///
......@@ -147,13 +153,19 @@ class CommonFinders {
/// // finds elements of type SingleChildRenderObjectElement, including
/// // those that are actually subclasses of that type.
/// // (contrast with byElementType, which only returns exact matches)
/// (Element element) => element is SingleChildRenderObjectElement
/// (Element element) => element is SingleChildRenderObjectElement,
/// description: '$SingleChildRenderObjectElement element',
/// )));
///
/// If [description] is provided, then this uses it as the description of the
/// [Finder] and appears, for example, in the error message when the finder
/// fails to locate the desired widget. Otherwise, the description prints the
/// signature of the predicate function.
///
/// If the `skipOffstage` argument is true (the default), then this skips
/// nodes that are [Offstage] or that are from inactive [Route]s.
Finder byElementPredicate(ElementPredicate predicate, { bool skipOffstage: true }) {
return new _ElementPredicateFinder(predicate, skipOffstage: skipOffstage);
Finder byElementPredicate(ElementPredicate predicate, { String description, bool skipOffstage: true }) {
return new _ElementPredicateFinder(predicate, description: description, skipOffstage: skipOffstage);
}
}
......@@ -397,12 +409,15 @@ class _ConfigFinder extends MatchFinder {
}
class _WidgetPredicateFinder extends MatchFinder {
_WidgetPredicateFinder(this.predicate, { bool skipOffstage: true }) : super(skipOffstage: skipOffstage);
_WidgetPredicateFinder(this.predicate, { String description, bool skipOffstage: true })
: _description = description,
super(skipOffstage: skipOffstage);
final WidgetPredicate predicate;
final String _description;
@override
String get description => 'widget matching predicate ($predicate)';
String get description => _description ?? 'widget matching predicate ($predicate)';
@override
bool matches(Element candidate) {
......@@ -411,12 +426,15 @@ class _WidgetPredicateFinder extends MatchFinder {
}
class _ElementPredicateFinder extends MatchFinder {
_ElementPredicateFinder(this.predicate, { bool skipOffstage: true }) : super(skipOffstage: skipOffstage);
_ElementPredicateFinder(this.predicate, { String description, bool skipOffstage: true })
: _description = description,
super(skipOffstage: skipOffstage);
final ElementPredicate predicate;
final String _description;
@override
String get description => 'element matching predicate ($predicate)';
String get description => _description ?? 'element matching predicate ($predicate)';
@override
bool matches(Element candidate) {
......
......@@ -104,4 +104,37 @@ void main() {
});
});
group('find.byElementPredicate', () {
testWidgets('fails with a custom description in the message', (WidgetTester tester) async {
await tester.pumpWidget(new Text('foo'));
String customDescription = 'custom description';
TestFailure failure;
try {
expect(find.byElementPredicate((_) => false, description: customDescription), findsOneWidget);
} catch(e) {
failure = e;
}
expect(failure, isNotNull);
expect(failure.message, contains('Actual: ?:<zero widgets with $customDescription'));
});
});
group('find.byWidgetPredicate', () {
testWidgets('fails with a custom description in the message', (WidgetTester tester) async {
await tester.pumpWidget(new Text('foo'));
String customDescription = 'custom description';
TestFailure failure;
try {
expect(find.byWidgetPredicate((_) => false, description: customDescription), findsOneWidget);
} catch(e) {
failure = e;
}
expect(failure, isNotNull);
expect(failure.message, contains('Actual: ?:<zero widgets with $customDescription'));
});
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment