-
Notifications
You must be signed in to change notification settings - Fork 306
Find a package:checks analogue of flutter_test's widget-finder matchers #232
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hello! I stumbled upon this looking to see if anyone else had written some widget-finder-with-checks tests. I hope it helps! |
Very interesting, thanks! I see the core of that implementation of I think the strategy I'd hope to be able to make work is to reuse the existing logic from there, rather than have to duplicate it. (There's a couple of thousands of lines in that final matchState = {};
if (!findsOne.matches(finder, matchState)) {
return Rejection(
// … call `findsOne.describe` and `findsOne.describeMismatch`, passing `matchState` to the latter …
);
}
return null; Even if that doesn't end up with something that would work well for a totally general implementation of the |
So you'd want an API like this? check(find.whatever()).findsOneWidget(); or: check(find.whatever()).legacyMatcher(findsOneWidget); Or, I suppose, Just figure I might as well make my impl work for y'all if I'm going to write it either way. I'm not particularly thrilled with the prospect of maintaining all of matcher 😀 |
I couldn't figure out async matchers, but here's an impl for sync matchers, @gnprice. import 'package:checks/context.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:matcher/src/expect/async_matcher.dart';
extension LegacyMatcher<T> on Subject<T> {
void legacyMatcher(Matcher matcher) {
context.expect(() => [], (value) {
final matchState = <Object?, Object?>{};
final match = matcher.matches(value, matchState);
if (!match) {
final description = matcher.describe(StringDescription());
final mismatchDescription = matcher.describeMismatch(
value,
StringDescription(),
matchState,
false,
);
return Rejection(
which: [description.toString()],
actual: [mismatchDescription.toString()],
);
}
return null;
});
}
Future<void> legacyMatcherAsync(AsyncMatcher matcher) async {
await context.expectAsync(() => [], (actual) async {
final Object? match = await matcher.matchAsync(actual);
// Do something with the match.
});
}
} |
Ok, wrote two basic packages, including async support. I'll probably publish it to pub at some time, any permissive license would work for y'all if it's external, right? |
@gnprice, does https://pub.dev/packages/legacy_checks (& https://pub.dev/packages/flutter_checks) work for y'all? |
Neat, thanks for building this! So for the example in my original description above: expect(find.whatever(), findsOneWidget); it looks like one would write: check(find.whatever()).findsOneWidget(); (And actually one would write That looks like a very clean usage pattern to me. I think the main remaining question I have is what the output looks like when things don't match: how does the output for some example compare between the old That question comes to mind because the quality of output when a test fails is something that can make a big difference in the effort spent working out what a failed test is telling you (is it a bug in the change you just made? or is the test just brittle and needs updating? or something else?). It's therefore something both the And then I guess after that the only thing |
(I'll be offline next week and so might not reply promptly; but I'll see any comments here when I'm catching up after that, and respond then. Other Zulip folks might also reply before I do.) |
You're welcome! 😁
Yup, exactly!
Good question! Being perfectly honest, I forgot to add failures to the test suite so 🤷♂️ (I did test it manually, they work, but I didn't pay attention to more than that)
Yeah, I only wrote what I needed for some boilerplate tests for a project I'm starting, which wasn't much 🙃 |
Sounds great, thanks!
Yep, good strategy. |
I just got around to pushing and publishing |
Thanks lishaduck for creating these with us in mind! Discussion: zulip#232 (comment)
Thanks lishaduck for creating these with us in mind! Discussion: zulip#232 (comment)
Thanks again @lishaduck for building that We've now started using it, with 90c7b26 / #949. I'll close this issue, as a |
Filed #952 for that follow-up. |
In Flutter widget tests written with the venerable
expect
API, it's common to have expectations likeusing the matchers findsOneWidget, findsNothing, and findsWidgets. See docs.
We're using
package:checks
instead, which is the projected, still-beta, successor toexpect
with a fancy type-safe API, so these "matchers" like findsOneWidget aren't available; and we don't currently have great analogues of them. One thing we currently often do in place offindsOneWidget
iswhich will indeed throw if there isn't exactly one such widget, but it's not great because it doesn't look like something intended as one of the checks that are the payload of the test — it looks like it's just part of the test's setup (and on top of that, isn't doing anything). A bit of discussion here: #207 (comment)
Shouldn't be hard to write appropriate checks in the
package:checks
API. We should do that, convert our existing tests, and also make sure there's a discussion upstream about there being good support for usingpackage:checks
withpackage:flutter_test
before the former is rolled out as stable.The text was updated successfully, but these errors were encountered: