processQuery static method
void
processQuery(
- AFStateTestContext context,
- AFAsyncQuery query,
- AFStore store,
- AFDispatcher dispatcher,
Process a query by looking up the results we have for that query, and then feeding them to its testAsyncResponse method.
Implementation
static void processQuery(AFStateTestContext context, AFAsyncQuery query, AFStore store, AFDispatcher dispatcher) {
final key = AFStateTest.specifierToId(query);
final results = context.test.results;
if(query is AFTimeUpdateListenerQuery) {
if(AFibF.g.testOnlyIsInWorkflowTest) {
query.startAsyncAF(dispatcher, store, completer: null);
return;
}
}
if(query is AFNavigateUnimplementedQuery) {
query.startAsyncAF(dispatcher, store, completer: null);
return;
}
var h = results[key];
if(h == null) {
/// Ummm, this might be a good place to admit that sometimes the type system
/// in Dart vexes me.
if(key.toString().startsWith("AFAlwaysFailQuery")) {
h = results["AFAlwaysFailQuery<AFAppStateAreaUnused>"];
}
}
if(h == null) {
/// deferred queries don't have any results.
if(query is AFDeferredQuery) {
final successContext = query.createSuccessContext(
dispatcher: dispatcher,
state: store.state,
isPreExecute: false,
);
// when we are in a state test in the interactive UI, it is important to actually do the delay,
// as sometimes an animation must complete before it is safe to execute the deferred action.
_simulateLatencyIfAppropriate(() => query.finishAsyncExecute(successContext), delay: query.delay, factor: 1, onSuccess: () {
dispatcher.dispatch(AFShutdownDeferredQueryAction(query.key));
});
return;
}
if(query is AFPeriodicQuery) {
// TODO: This seems to work, but I think you want something more nuanced here. You really
// want to be synchronous in command-line tests, and also in state tests executed within prototype mode
// but in the background. Then, you want to add asynchronous waits in prototype mode once the UI
// is actually displayed, and the user is interacting with it.
if(AFibF.g.isPrototypeMode) {
Timer.periodic(query.delay, (timer) {
final successContext = query.createSuccessContext(
dispatcher: dispatcher,
state: store.state,
isPreExecute: false,
);
final keepGoing = query.finishAsyncExecute(successContext);
if(!keepGoing) {
timer.cancel();
dispatcher.dispatch(AFShutdownPeriodicQueryAction(query.key));
}
});
} else {
var keepGoing = true;
while(keepGoing) {
final successContext = query.createSuccessContext(
dispatcher: dispatcher,
state: store.state,
isPreExecute: false,
);
keepGoing = query.finishAsyncExecute(successContext);
if(!keepGoing) {
query.shutdown();
dispatcher.dispatch(AFShutdownPeriodicQueryAction(query.key));
}
}
}
return;
}
if(query is AFCompositeQuery) {
final successContext = AFFinishQuerySuccessContext<AFCompositeQueryResponse>(
conceptualStore: AFibF.g.activeConceptualStore,
response: query.queryResponses,
isPreExecute: false,
);
for(final consolidatedQueries in query.queryResponses.responses) {
final consolidatedQuery = consolidatedQueries.query;
final consolidatedKey = AFStateTest.specifierToId(consolidatedQuery);
final consolidatedHandler = results[consolidatedKey];
if(consolidatedHandler != null) {
consolidatedQueries.result = consolidatedHandler.handler?.call(context, consolidatedQuery);
} else {
throw AFException("No results specified for query $consolidatedKey in composite query. Note that you can use defineQueryResponseNone if you intend to have no results.");
}
}
_simulateLatencyIfAppropriate(() => query.finishAsyncWithResponseAF(successContext), factor: query.simulatedLatencyFactor ?? 1);
return;
}
if(key == AFUIQueryID.time.code) {
throw AFException("Please call defineInitialTime in your state tests if you use AFTimeUpdateListenerQuery to listen to the time");
}
throw AFException("No results specified for query ${AFStateTest.specifierToId(query)}");
}
final handler = h.handler;
if(handler != null) {
final pre = query.onPreExecuteResponse;
if(pre != null) {
final preResponse = pre();
final successContext = query.createSuccessContextForResponse(
dispatcher: dispatcher,
state: store.state,
response: preResponse,
isPreExecute: true,
);
query.finishAsyncWithResponseAF(successContext);
}
_simulateLatencyIfAppropriate(() => handler(context, query), factor: query.simulatedLatencyFactor ?? 1);
}
}