waitAll method

Future<TestInfoList<St>> waitAll(
  1. List<Type> actionTypes, {
  2. List<Type>? ignore,
})

Runs until all given actions types are dispatched, in order. Waits until all of them are finished. Returns the info after all actions finish. Will fail with an exception if an unexpected action is seen, or if any of the expected actions are dispatched in the wrong order.

If you pass action types to ignore, they will be ignored (the test won't fail when encountering them, and won't collect testInfo for them). However, if an action type exists both in actionTypes and ignore, it will be expected in that particular order, and the others of that type will be ignored. This method will remember all ignored actions and wait for them to finish, so that they don't "leak" to the next wait.

If ignore is null, it will use the global ignore provided in the StoreTester constructor, if any. If ignore is an empty list, it will disable that global ignore.

This method is the same as waitAllGetLast, but instead of returning just the last info, it returns a list with the end info for each action.

Implementation

Future<TestInfoList<St>> waitAll(
  List<Type> actionTypes, {
  List<Type>? ignore,
}) async {
  assert(actionTypes.isNotEmpty);
  ignore ??= _ignore;

  TestInfoList<St> infoList = TestInfoList<St>();

  TestInfo<St>? testInfo;

  Queue<Type> expectedActionTypesINI = Queue.from(actionTypes);

  // These are for better error messages only.
  List<Type> obtainedIni = [];
  List<Type> ignoredIni = [];

  List<ReduxAction?> expectedActionsEND = [];
  List<ReduxAction?> expectedActionsENDIgnored = [];

  while (expectedActionTypesINI.isNotEmpty ||
      expectedActionsEND.isNotEmpty ||
      expectedActionsENDIgnored.isNotEmpty) {
    //
    testInfo = await _next();

    // Action INI must all exist, in order.
    if (testInfo.isINI) {
      //
      bool wasIgnored = ignore.contains(testInfo.type) &&
          (expectedActionTypesINI.isEmpty || //
              expectedActionTypesINI.first != testInfo.type);

      /// Record this action, so that later we can wait until it ends.
      if (wasIgnored) {
        expectedActionsENDIgnored.add(testInfo.action);
        ignoredIni.add(testInfo.type); // // For better error messages only.
      }
      //
      else {
        expectedActionsEND.add(testInfo.action);
        obtainedIni.add(testInfo.type); // For better error messages only.

        Type? expectedActionTypeINI = expectedActionTypesINI.isEmpty
            ? //
            null
            : expectedActionTypesINI.removeFirst();

        if (testInfo.type != expectedActionTypeINI)
          throw StoreException("Got this unexpected action: "
              "${testInfo.type} INI.\n"
              "Was expecting: $expectedActionTypeINI INI.\n"
              "obtainedIni: $obtainedIni\n"
              "ignoredIni: $ignoredIni");
      }
    }
    //
    // Action END must all exist, but the order doesn't matter.
    else {
      bool wasRemoved = expectedActionsEND.remove(testInfo.action);

      if (wasRemoved)
        infoList._add(testInfo);
      else
        wasRemoved = expectedActionsENDIgnored.remove(testInfo.action);

      if (!wasRemoved)
        throw StoreException("Got this unexpected action: "
            "${testInfo.type} END.\n"
            "obtainedIni: $obtainedIni\n"
            "ignoredIni: $ignoredIni");
    }
  }

  lastInfo = infoList.last;

  return infoList;
}