mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Added find.ancestor to CommonFinders (#13691)
This commit is contained in:
parent
95aeb05ced
commit
83134cd39f
@ -198,6 +198,29 @@ class CommonFinders {
|
|||||||
Finder descendant({ Finder of, Finder matching, bool matchRoot: false, bool skipOffstage: true }) {
|
Finder descendant({ Finder of, Finder matching, bool matchRoot: false, bool skipOffstage: true }) {
|
||||||
return new _DescendantFinder(of, matching, matchRoot: matchRoot, skipOffstage: skipOffstage);
|
return new _DescendantFinder(of, matching, matchRoot: matchRoot, skipOffstage: skipOffstage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Finds widgets that are ancestors of the [of] parameter and that match
|
||||||
|
/// the [matching] parameter.
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
///
|
||||||
|
/// // Test if a Text widget that contains 'faded' is the
|
||||||
|
/// // descendant of an Opacity widget with opacity 0.5:
|
||||||
|
/// expect(
|
||||||
|
/// tester.widget<Opacity>(
|
||||||
|
/// find.ancestor(
|
||||||
|
/// of: find.text('faded'),
|
||||||
|
/// matching: find.byType('Opacity'),
|
||||||
|
/// )
|
||||||
|
/// ).opacity,
|
||||||
|
/// 0.5
|
||||||
|
/// );
|
||||||
|
///
|
||||||
|
/// If the [matchRoot] argument is true then the widget(s) specified by [of]
|
||||||
|
/// will be matched along with the ancestors.
|
||||||
|
Finder ancestor({ Finder of, Finder matching, bool matchRoot: false}) {
|
||||||
|
return new _AncestorFinder(of, matching, matchRoot: matchRoot);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Searches a widget tree and returns nodes that match a particular
|
/// Searches a widget tree and returns nodes that match a particular
|
||||||
@ -583,3 +606,39 @@ class _DescendantFinder extends Finder {
|
|||||||
return candidates;
|
return candidates;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _AncestorFinder extends Finder {
|
||||||
|
_AncestorFinder(this.descendant, this.ancestor, { this.matchRoot: false }) : super(skipOffstage: false);
|
||||||
|
|
||||||
|
final Finder ancestor;
|
||||||
|
final Finder descendant;
|
||||||
|
final bool matchRoot;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get description {
|
||||||
|
if (matchRoot)
|
||||||
|
return 'ancestor ${ancestor.description} beginning with ${descendant.description}';
|
||||||
|
return '${ancestor.description} which is an ancestor of ${descendant.description}';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<Element> apply(Iterable<Element> candidates) {
|
||||||
|
return candidates.where((Element element) => ancestor.evaluate().contains(element));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<Element> get allCandidates {
|
||||||
|
final List<Element> candidates = <Element>[];
|
||||||
|
for (Element root in descendant.evaluate()) {
|
||||||
|
final List<Element> ancestors = <Element>[];
|
||||||
|
if (matchRoot)
|
||||||
|
ancestors.add(root);
|
||||||
|
root.visitAncestorElements((Element element) {
|
||||||
|
ancestors.add(element);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
candidates.addAll(ancestors);
|
||||||
|
}
|
||||||
|
return candidates;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -198,6 +198,66 @@ void main() {
|
|||||||
contains('Actual: ?:<zero widgets with text "bar" that has ancestor(s) with type Column with text "foo"')
|
contains('Actual: ?:<zero widgets with text "bar" that has ancestor(s) with type Column with text "foo"')
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group('find.ancestor', () {
|
||||||
|
testWidgets('finds one ancestor', (WidgetTester tester) async {
|
||||||
|
await tester.pumpWidget(new Row(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
children: <Widget>[
|
||||||
|
new Column(children: fooBarTexts),
|
||||||
|
],
|
||||||
|
));
|
||||||
|
|
||||||
|
expect(find.ancestor(
|
||||||
|
of: find.text('bar'),
|
||||||
|
matching: find.widgetWithText(Row, 'foo'),
|
||||||
|
), findsOneWidget);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('finds two matching ancestors, one descendant', (WidgetTester tester) async {
|
||||||
|
await tester.pumpWidget(
|
||||||
|
new Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: new Row(
|
||||||
|
children: <Widget>[
|
||||||
|
new Row(children: fooBarTexts),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(find.ancestor(
|
||||||
|
of: find.text('bar'),
|
||||||
|
matching: find.byType(Row),
|
||||||
|
), findsNWidgets(2));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('fails with a descriptive message', (WidgetTester tester) async {
|
||||||
|
await tester.pumpWidget(new Row(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
children: <Widget>[
|
||||||
|
new Column(children: <Text>[const Text('foo', textDirection: TextDirection.ltr)]),
|
||||||
|
const Text('bar', textDirection: TextDirection.ltr),
|
||||||
|
],
|
||||||
|
));
|
||||||
|
|
||||||
|
TestFailure failure;
|
||||||
|
try {
|
||||||
|
expect(find.ancestor(
|
||||||
|
of: find.text('bar'),
|
||||||
|
matching: find.widgetWithText(Column, 'foo'),
|
||||||
|
), findsOneWidget);
|
||||||
|
} catch (e) {
|
||||||
|
failure = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(failure, isNotNull);
|
||||||
|
expect(
|
||||||
|
failure.message,
|
||||||
|
contains('Actual: ?:<zero widgets with type Column with text "foo" which is an ancestor of text "bar"'),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('Root not matched by default', (WidgetTester tester) async {
|
testWidgets('Root not matched by default', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(new Row(
|
await tester.pumpWidget(new Row(
|
||||||
@ -207,9 +267,9 @@ void main() {
|
|||||||
],
|
],
|
||||||
));
|
));
|
||||||
|
|
||||||
expect(find.descendant(
|
expect(find.ancestor(
|
||||||
of: find.widgetWithText(Row, 'foo'),
|
of: find.byType(Column),
|
||||||
matching: find.byType(Row),
|
matching: find.widgetWithText(Column, 'foo'),
|
||||||
), findsNothing);
|
), findsNothing);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -222,12 +282,11 @@ void main() {
|
|||||||
));
|
));
|
||||||
|
|
||||||
expect(find.descendant(
|
expect(find.descendant(
|
||||||
of: find.widgetWithText(Row, 'foo'),
|
of: find.byType(Column),
|
||||||
matching: find.byType(Row),
|
matching: find.widgetWithText(Column, 'foo'),
|
||||||
matchRoot: true,
|
matchRoot: true,
|
||||||
), findsOneWidget);
|
), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('hasRunningAnimations control test', (WidgetTester tester) async {
|
testWidgets('hasRunningAnimations control test', (WidgetTester tester) async {
|
||||||
|
Loading…
Reference in New Issue
Block a user