blob: c4ae3d199e746fecb2943a93f0cadbf2f1579049 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
extension FinderExtension on Finder {
// TODO(alexeyinkin): Push to Flutter or wait for them to make their own, https://github.com/flutter/flutter/issues/117675
Finder and(Finder another) {
return _AndFinder(this, another);
}
Finder or(Finder another) {
return _OrFinder(this, another);
}
Finder getChildrenByType(Type childType) {
final finders = evaluate();
final childElements = finders
.map((e) => collectAllElementsFrom(e, skipOffstage: true))
.expand((e) => e)
.where((e) => e.widget.runtimeType == childType);
return find.byElementPredicate(
(element) => childElements.contains(element),
);
}
Finder horizontallyAt(int index, WidgetTester wt) =>
_atIndexOnAxis(index, Axis.horizontal, wt);
Finder verticallyAt(int index, WidgetTester wt) =>
_atIndexOnAxis(index, Axis.vertical, wt);
Finder _atIndexOnAxis(int index, Axis axis, WidgetTester wt) {
final finders = evaluate();
if (index > finders.length - 1) {
throw IndexError(index, finders);
}
final offsets = <_IndexAndOffset>[];
for (int i = 0; i < finders.length; i++) {
offsets.add(_IndexAndOffset(i, wt.getCenter(at(i))));
}
offsets.sort(
(a, b) => axis == Axis.vertical
? _compareDoubles(a.offset.dy, b.offset.dy)
: _compareDoubles(a.offset.dx, b.offset.dx),
);
return at(offsets[index].index);
}
int _compareDoubles(double a, double b) {
return (a - b).sign.toInt();
}
}
class _AndFinder extends ChainedFinder {
_AndFinder(super.parent, this.another);
final Finder another;
@override
String get description => '${parent.description} AND ${another.description}';
@override
Iterable<Element> filter(Iterable<Element> parentCandidates) {
return another.apply(parentCandidates);
}
}
class _OrFinder extends ChainedFinder {
_OrFinder(super.parent, this.another);
final Finder another;
@override
String get description => '(${parent.description} OR ${another.description})';
@override
Iterable<Element> filter(Iterable<Element> parentCandidates) {
return {...parentCandidates, ...another.evaluate()};
}
}
class _IndexAndOffset {
final int index;
final Offset offset;
_IndexAndOffset(this.index, this.offset);
}