testGameWidget should allow passing Subject
Problem to solve
Currently, if one is testing with testGameWidget in order to test the subject within verify it requires the developer to traverse the game tree and find the subject they are interested in.
flame.testGameWidget('example test',
setUp: (game, tester) async {
final fooComponent = FooComponent();
final booComponent = BooComponent();
await booComponent.add(fooComponent);
await game.add(booComponent);
},
verify: (game, tester) {
final fooComponent = game.descendants().whereType<FooComponent>.first;
// The above is error prone, depends on how the given game tree is structured.
expect(fooComponent.something, isTrue);
},
);
Proposal
Something as below would be useful. Including a build parameter and updating the signature to:
void testGameWidget<G extends Game, S>(
String description, {
Future<void> Function(G game, WidgetTester tester)? setUp,
required Future<S> Function(G game, WidgetTester tester) build,
Future<void> Function(G game, S subject, WidgetTester tester)? verify,
})
or
void testGameWidget<G extends Game, S>(
String description, {
Future<void> Function(G game, WidgetTester tester)? setUp,
required Future<S> Function(G game, WidgetTester tester) build,
Future<void> Function(S subject, WidgetTester tester)? verify,
})
Although with the latter signature I think it would be challenging to test/verify something that requires both the game and the subject. The subject could be the game and then we would have to traverse (same problem).
Another proposal could be with an act parameter:
void testGameWidget<G extends Game, S>(
String description, {
required Future<S> Function(G game, WidgetTester tester)? setUp,
Future<void> Function(G game, S subject, WidgetTester tester) act,
Future<void> Function(G game, S subject, WidgetTester tester)? verify,
})
Note: the above snippets are a quick proposal, it is open to change. I didn't use typedef for readability.
More information
@wolfenrain and I had an offline conversation regarding this. Currently thinking that it is hard to define an API for it since sometimes you still want to verify other items on your game as well.
Currently thinking if an additional test would be better, for example, testComponent. That aims to only test a single component,
Essentially we are looking for a mappable method, from game go to subject.
You can always do
testWithFlameGame(
'example test',
(game) async {
final fooComponent = FooComponent();
final booComponent = BooComponent();
booComponent.add(fooComponent);
game.add(booComponent);
await game.ready();
expect(fooComponent.something, isTrue);
},
);
Yes of course @st-pasha that's also possible. However, I believe for golden tests one does need the verify method. The idea of this is just as an enhancement; there are currently workarounds one can do.
However, I believe for golden tests one does need the verify method.
Indeed; but for golden tests you don't need to search for a specific component inside the component tree -- the golden test renders the entire Game widget.
Adding this here:
Currently, some FlameBloc tests will pass in the setUp testGameWidgets but fail in test with an error outlining a BloC is not in context.
I will try to provide minimal code that reproduces this, however, if someone is willing to take this task I'll be happy to.