* result
*/
protected void validate(final List<Pair<K2, V2>> outputs,
final boolean orderMatters) {
final Errors errors = new Errors(LOG);
if (!outputs.isEmpty()) {
// were we supposed to get output in the first place?
if (expectedOutputs.isEmpty()) {
errors.record("Expected no outputs; got %d outputs.", outputs.size());
}
// check that user's key and value writables implement equals, hashCode, toString
checkOverrides(outputs.get(0));
}
final Map<Pair<K2, V2>, List<Integer>> expectedPositions = buildPositionMap(expectedOutputs);
final Map<Pair<K2, V2>, List<Integer>> actualPositions = buildPositionMap(outputs);
for (final Pair<K2, V2> output : expectedPositions.keySet()) {
final List<Integer> expectedPositionList = expectedPositions.get(output);
final List<Integer> actualPositionList = actualPositions.get(output);
if (actualPositionList != null) {
// the expected value has been seen - check positions
final int expectedPositionsCount = expectedPositionList.size();
final int actualPositionsCount = actualPositionList.size();
if (orderMatters) {
// order is important, so the positions must match exactly
if (expectedPositionList.equals(actualPositionList)) {
LOG.debug(String.format("Matched expected output %s at "
+ "positions %s", output, expectedPositionList.toString()));
} else {
int i = 0;
while (expectedPositionsCount > i || actualPositionsCount > i) {
if (expectedPositionsCount > i && actualPositionsCount > i) {
final int expectedPosition = expectedPositionList.get(i);
final int actualPosition = actualPositionList.get(i);
if (expectedPosition == actualPosition) {
LOG.debug(String.format("Matched expected output %s at "
+ "position %d", output, expectedPosition));
} else {
errors.record("Matched expected output %s but at "
+ "incorrect position %d (expected position %d)", output,
actualPosition, expectedPosition);
}
} else if (expectedPositionsCount > i) {
// not ok, value wasn't seen enough times
errors.record("Missing expected output %s at position %d.",
output, expectedPositionList.get(i));
} else {
// not ok, value seen too many times
errors.record("Received unexpected output %s at position %d.",
output, actualPositionList.get(i));
}
i++;
}
}
} else {
// order is unimportant, just check that the count of times seen match
if (expectedPositionsCount == actualPositionsCount) {
// ok, counts match
LOG.debug(String.format("Matched expected output %s in "
+ "%d positions", output, expectedPositionsCount));
} else if (expectedPositionsCount > actualPositionsCount) {
// not ok, value wasn't seen enough times
for (int i = 0; i < expectedPositionsCount - actualPositionsCount; i++) {
errors.record("Missing expected output %s", output);
}
} else {
// not ok, value seen too many times
for (int i = 0; i < actualPositionsCount - expectedPositionsCount; i++) {
errors.record("Received unexpected output %s", output);
}
}
}
actualPositions.remove(output);
} else {
// the expected value was not found anywhere - output errors
checkTypesAndLogError(outputs, output, expectedPositionList,
orderMatters, errors, "Missing expected output");
}
}
for (final Pair<K2, V2> output : actualPositions.keySet()) {
// anything left in actual set is unexpected
checkTypesAndLogError(outputs, output, actualPositions.get(output),
orderMatters, errors, "Received unexpected output");
}
errors.assertNone();
}