Improved Test Runner Summary (#4641)
* Filename in list (no proper sorting yet) * Line number and message in error list + removed sorting * Style adjustment * Added missing file/line number to "expected N passes/successes" * Fixed Known Failing Passing test list * Separated test list from totals * Assumption fails list * Better names * Filename for KNOWN_FAILINGs passing * Moved total back to the bottom * Spaces correction * Fixed test list count * Source file for Alloc fails on tests * Moved sourceLine from BattleTest to Test struct * Fixed assumptions failed "and more" counter * Fixed ASSUMPTION block not printing their line numbers * Fixed when stopLine is printed * Renamed stopLine to failedAssumptionsBlockLine
This commit is contained in:
parent
f2311b4c97
commit
9d5e253867
6 changed files with 192 additions and 115 deletions
|
@ -99,7 +99,7 @@ void *AllocInternal(void *heapStart, u32 size, const char *location)
|
|||
block = block->next;
|
||||
}
|
||||
while (block != head);
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, "%s: OOM allocating %d bytes", location, size);
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, SourceLine(0), ":L%s:%d, %s: OOM allocating %d bytes", gTestRunnerState.test->filename, SourceLine(0), location, size);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -518,7 +518,6 @@ typedef void (*DoubleBattleTestFunction)(void *, const u32, struct BattlePokemon
|
|||
struct BattleTest
|
||||
{
|
||||
u8 type;
|
||||
u16 sourceLine;
|
||||
union
|
||||
{
|
||||
SingleBattleTestFunction singles;
|
||||
|
@ -762,10 +761,10 @@ extern struct BattleTestRunnerState *const gBattleTestRunnerState;
|
|||
.name = _name, \
|
||||
.filename = __FILE__, \
|
||||
.runner = &gBattleTestRunner, \
|
||||
.sourceLine = __LINE__, \
|
||||
.data = (void *)&(const struct BattleTest) \
|
||||
{ \
|
||||
.type = _type, \
|
||||
.sourceLine = __LINE__, \
|
||||
.function = { .singles = (SingleBattleTestFunction)CAT(Test, __LINE__) }, \
|
||||
.resultsSize = sizeof(struct CAT(Result, __LINE__)), \
|
||||
}, \
|
||||
|
@ -780,10 +779,10 @@ extern struct BattleTestRunnerState *const gBattleTestRunnerState;
|
|||
.name = _name, \
|
||||
.filename = __FILE__, \
|
||||
.runner = &gBattleTestRunner, \
|
||||
.sourceLine = __LINE__, \
|
||||
.data = (void *)&(const struct BattleTest) \
|
||||
{ \
|
||||
.type = _type, \
|
||||
.sourceLine = __LINE__, \
|
||||
.function = { .doubles = (DoubleBattleTestFunction)CAT(Test, __LINE__) }, \
|
||||
.resultsSize = sizeof(struct CAT(Result, __LINE__)), \
|
||||
}, \
|
||||
|
@ -1091,7 +1090,7 @@ void ValidateFinally(u32 sourceLine);
|
|||
s32 _am = Q_4_12_TO_INT(_a * _m); \
|
||||
s32 _t = max(Q_4_12_TO_INT(abs(_m) + Q_4_12_ROUND), 1); \
|
||||
if (abs(_am-_b) > _t) \
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: EXPECT_MUL_EQ(%d, %q, %d) failed: %d not in [%d..%d]", gTestRunnerState.test->filename, __LINE__, _a, _m, _b, _am, _b-_t, _b+_t); \
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, __LINE__, ":L%s:%d: EXPECT_MUL_EQ(%d, %q, %d) failed: %d not in [%d..%d]", gTestRunnerState.test->filename, __LINE__, _a, _m, _b, _am, _b-_t, _b+_t); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -33,6 +33,7 @@ struct Test
|
|||
const char *filename;
|
||||
const struct TestRunner *runner;
|
||||
void *data;
|
||||
u16 sourceLine;
|
||||
};
|
||||
|
||||
struct TestRunnerState
|
||||
|
@ -40,6 +41,7 @@ struct TestRunnerState
|
|||
u8 state;
|
||||
u8 exitCode;
|
||||
const char *skipFilename;
|
||||
u32 failedAssumptionsBlockLine;
|
||||
const struct Test *test;
|
||||
u32 processCosts[MAX_PROCESSES];
|
||||
|
||||
|
@ -73,7 +75,9 @@ void CB2_TestRunner(void);
|
|||
|
||||
void Test_ExpectedResult(enum TestResult);
|
||||
void Test_ExpectLeaks(bool32);
|
||||
void Test_ExitWithResult(enum TestResult, const char *fmt, ...);
|
||||
void Test_ExitWithResult(enum TestResult, u32 stopLine, const char *fmt, ...);
|
||||
u32 SourceLine(u32 sourceLineOffset);
|
||||
u32 SourceLineOffset(u32 sourceLine);
|
||||
|
||||
s32 MgbaPrintf_(const char *fmt, ...);
|
||||
|
||||
|
@ -84,6 +88,7 @@ s32 MgbaPrintf_(const char *fmt, ...);
|
|||
.name = _name, \
|
||||
.filename = __FILE__, \
|
||||
.runner = &gFunctionTestRunner, \
|
||||
.sourceLine = __LINE__, \
|
||||
.data = (void *)CAT(Test, __LINE__), \
|
||||
}; \
|
||||
static void CAT(Test, __LINE__)(void)
|
||||
|
@ -95,6 +100,7 @@ s32 MgbaPrintf_(const char *fmt, ...);
|
|||
.name = "ASSUMPTIONS: " __FILE__, \
|
||||
.filename = __FILE__, \
|
||||
.runner = &gAssumptionsRunner, \
|
||||
.sourceLine = __LINE__, \
|
||||
.data = Assumptions, \
|
||||
}; \
|
||||
static void Assumptions(void)
|
||||
|
@ -103,14 +109,14 @@ s32 MgbaPrintf_(const char *fmt, ...);
|
|||
do \
|
||||
{ \
|
||||
if (!(c)) \
|
||||
Test_ExitWithResult(TEST_RESULT_ASSUMPTION_FAIL, "%s:%d: ASSUME failed", gTestRunnerState.test->filename, __LINE__); \
|
||||
Test_ExitWithResult(TEST_RESULT_ASSUMPTION_FAIL, __LINE__, ":L%s:%d: ASSUME failed", gTestRunnerState.test->filename, __LINE__); \
|
||||
} while (0)
|
||||
|
||||
#define EXPECT(c) \
|
||||
do \
|
||||
{ \
|
||||
if (!(c)) \
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: EXPECT failed", gTestRunnerState.test->filename, __LINE__); \
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, __LINE__, ":L%s:%d: EXPECT failed", gTestRunnerState.test->filename, __LINE__); \
|
||||
} while (0)
|
||||
|
||||
#define EXPECT_EQ(a, b) \
|
||||
|
@ -118,7 +124,7 @@ s32 MgbaPrintf_(const char *fmt, ...);
|
|||
{ \
|
||||
typeof(a) _a = (a), _b = (b); \
|
||||
if (_a != _b) \
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: EXPECT_EQ(%d, %d) failed", gTestRunnerState.test->filename, __LINE__, _a, _b); \
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, __LINE__, ":L%s:%d: EXPECT_EQ(%d, %d) failed", gTestRunnerState.test->filename, __LINE__, _a, _b); \
|
||||
} while (0)
|
||||
|
||||
#define EXPECT_NE(a, b) \
|
||||
|
@ -126,7 +132,7 @@ s32 MgbaPrintf_(const char *fmt, ...);
|
|||
{ \
|
||||
typeof(a) _a = (a), _b = (b); \
|
||||
if (_a == _b) \
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: EXPECT_NE(%d, %d) failed", gTestRunnerState.test->filename, __LINE__, _a, _b); \
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, __LINE__, ":L%s:%d: EXPECT_NE(%d, %d) failed", gTestRunnerState.test->filename, __LINE__, _a, _b); \
|
||||
} while (0)
|
||||
|
||||
#define EXPECT_LT(a, b) \
|
||||
|
@ -134,7 +140,7 @@ s32 MgbaPrintf_(const char *fmt, ...);
|
|||
{ \
|
||||
typeof(a) _a = (a), _b = (b); \
|
||||
if (_a >= _b) \
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: EXPECT_LT(%d, %d) failed", gTestRunnerState.test->filename, __LINE__, _a, _b); \
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, __LINE__, ":L%s:%d: EXPECT_LT(%d, %d) failed", gTestRunnerState.test->filename, __LINE__, _a, _b); \
|
||||
} while (0)
|
||||
|
||||
#define EXPECT_LE(a, b) \
|
||||
|
@ -142,7 +148,7 @@ s32 MgbaPrintf_(const char *fmt, ...);
|
|||
{ \
|
||||
typeof(a) _a = (a), _b = (b); \
|
||||
if (_a > _b) \
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: EXPECT_LE(%d, %d) failed", gTestRunnerState.test->filename, __LINE__, _a, _b); \
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, __LINE__, ":L%s:%d: EXPECT_LE(%d, %d) failed", gTestRunnerState.test->filename, __LINE__, _a, _b); \
|
||||
} while (0)
|
||||
|
||||
#define EXPECT_GT(a, b) \
|
||||
|
@ -150,7 +156,7 @@ s32 MgbaPrintf_(const char *fmt, ...);
|
|||
{ \
|
||||
typeof(a) _a = (a), _b = (b); \
|
||||
if (_a <= _b) \
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: EXPECT_GT(%d, %d) failed", gTestRunnerState.test->filename, __LINE__, _a, _b); \
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, __LINE__, ":L%s:%d: EXPECT_GT(%d, %d) failed", gTestRunnerState.test->filename, __LINE__, _a, _b); \
|
||||
} while (0)
|
||||
|
||||
#define EXPECT_GE(a, b) \
|
||||
|
@ -158,7 +164,7 @@ s32 MgbaPrintf_(const char *fmt, ...);
|
|||
{ \
|
||||
typeof(a) _a = (a), _b = (b); \
|
||||
if (_a < _b) \
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: EXPECT_GE(%d, %d) failed", gTestRunnerState.test->filename, __LINE__, _a, _b); \
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, __LINE__, ":L%s:%d: EXPECT_GE(%d, %d) failed", gTestRunnerState.test->filename, __LINE__, _a, _b); \
|
||||
} while (0)
|
||||
|
||||
struct Benchmark { s32 ticks; };
|
||||
|
@ -195,7 +201,7 @@ static inline struct Benchmark BenchmarkStop(void)
|
|||
u32 a_ = (a).ticks; u32 b_ = (b).ticks; \
|
||||
MgbaPrintf_(#a ": %d ticks, " #b ": %d ticks", a_, b_); \
|
||||
if (((a_ - BENCHMARK_ABS) * BENCHMARK_REL) >= (b_ * 100)) \
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: EXPECT_FASTER(" #a ", " #b ") failed", gTestRunnerState.test->filename, __LINE__); \
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, __LINE__, ":L%s:%d: EXPECT_FASTER(" #a ", " #b ") failed", gTestRunnerState.test->filename, __LINE__); \
|
||||
} while (0)
|
||||
|
||||
#define EXPECT_SLOWER(a, b) \
|
||||
|
@ -204,7 +210,7 @@ static inline struct Benchmark BenchmarkStop(void)
|
|||
u32 a_ = (a).ticks; u32 b_ = (b).ticks; \
|
||||
MgbaPrintf_(#a ": %d ticks, " #b ": %d ticks", a_, b_); \
|
||||
if ((a_ * 100) <= ((b_ - BENCHMARK_ABS) * BENCHMARK_REL)) \
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: EXPECT_SLOWER(" #a ", " #b ") failed", gTestRunnerState.test->filename, __LINE__); \
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, __LINE__, ":L%s:%d: EXPECT_SLOWER(" #a ", " #b ") failed", gTestRunnerState.test->filename, __LINE__); \
|
||||
} while (0)
|
||||
|
||||
#define KNOWN_FAILING \
|
||||
|
@ -218,7 +224,7 @@ static inline struct Benchmark BenchmarkStop(void)
|
|||
#define TO_DO \
|
||||
do { \
|
||||
Test_ExpectedResult(TEST_RESULT_TODO); \
|
||||
Test_ExitWithResult(TEST_RESULT_TODO, "%s:%d: EXPECT_TO_DO", gTestRunnerState.test->filename, __LINE__); \
|
||||
Test_ExitWithResult(TEST_RESULT_TODO, __LINE__, ":L%s:%d: EXPECT_TO_DO", gTestRunnerState.test->filename, __LINE__); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -179,6 +179,7 @@ top:
|
|||
}
|
||||
|
||||
MgbaPrintf_(":N%s", gTestRunnerState.test->name);
|
||||
MgbaPrintf_(":L%s:%d", gTestRunnerState.test->filename);
|
||||
gTestRunnerState.result = TEST_RESULT_PASS;
|
||||
gTestRunnerState.expectedResult = TEST_RESULT_PASS;
|
||||
gTestRunnerState.expectLeaks = FALSE;
|
||||
|
@ -216,6 +217,7 @@ top:
|
|||
// NOTE: Assumes that the compiler interns __FILE__.
|
||||
if (gTestRunnerState.skipFilename == gTestRunnerState.test->filename) // Assumption fails for tests in this file.
|
||||
{
|
||||
MgbaPrintf_(":L%s:%d", gTestRunnerState.test->filename, gTestRunnerState.failedAssumptionsBlockLine);
|
||||
gTestRunnerState.result = TEST_RESULT_ASSUMPTION_FAIL;
|
||||
return;
|
||||
}
|
||||
|
@ -480,9 +482,10 @@ static void Intr_Timer2(void)
|
|||
}
|
||||
}
|
||||
|
||||
void Test_ExitWithResult(enum TestResult result, const char *fmt, ...)
|
||||
void Test_ExitWithResult(enum TestResult result, u32 stopLine, const char *fmt, ...)
|
||||
{
|
||||
gTestRunnerState.result = result;
|
||||
gTestRunnerState.failedAssumptionsBlockLine = stopLine;
|
||||
ReinitCallbacks();
|
||||
if (gTestRunnerState.state == STATE_REPORT_RESULT
|
||||
&& gTestRunnerState.result != gTestRunnerState.expectedResult)
|
||||
|
@ -690,3 +693,24 @@ void DACSHandle(void)
|
|||
ReinitCallbacks();
|
||||
DACS_LR = ((uintptr_t)JumpToAgbMainLoop & ~1) + 4;
|
||||
}
|
||||
|
||||
static const struct Test *GetTest(void)
|
||||
{
|
||||
const struct Test *test = gTestRunnerState.test;
|
||||
return test;
|
||||
}
|
||||
|
||||
u32 SourceLine(u32 sourceLineOffset)
|
||||
{
|
||||
const struct Test *test = GetTest();
|
||||
return test->sourceLine + sourceLineOffset;
|
||||
}
|
||||
|
||||
u32 SourceLineOffset(u32 sourceLine)
|
||||
{
|
||||
const struct Test *test = GetTest();
|
||||
if (sourceLine - test->sourceLine > 0xFF)
|
||||
return 0;
|
||||
else
|
||||
return sourceLine - test->sourceLine;
|
||||
}
|
||||
|
|
|
@ -25,10 +25,10 @@
|
|||
#undef TestRunner_Battle_GetForcedAbility
|
||||
#endif
|
||||
|
||||
#define INVALID(fmt, ...) Test_ExitWithResult(TEST_RESULT_INVALID, "%s:%d: " fmt, gTestRunnerState.test->filename, sourceLine, ##__VA_ARGS__)
|
||||
#define INVALID_IF(c, fmt, ...) do { if (c) Test_ExitWithResult(TEST_RESULT_INVALID, "%s:%d: " fmt, gTestRunnerState.test->filename, sourceLine, ##__VA_ARGS__); } while (0)
|
||||
#define INVALID(fmt, ...) Test_ExitWithResult(TEST_RESULT_INVALID, sourceLine, ":L%s:%d: " fmt, gTestRunnerState.test->filename, sourceLine, ##__VA_ARGS__)
|
||||
#define INVALID_IF(c, fmt, ...) do { if (c) Test_ExitWithResult(TEST_RESULT_INVALID, sourceLine, ":L%s:%d: " fmt, gTestRunnerState.test->filename, sourceLine, ##__VA_ARGS__); } while (0)
|
||||
|
||||
#define ASSUMPTION_FAIL_IF(c, fmt, ...) do { if (c) Test_ExitWithResult(TEST_RESULT_ASSUMPTION_FAIL, "%s:%d: " fmt, gTestRunnerState.test->filename, sourceLine, ##__VA_ARGS__); } while (0)
|
||||
#define ASSUMPTION_FAIL_IF(c, fmt, ...) do { if (c) Test_ExitWithResult(TEST_RESULT_ASSUMPTION_FAIL, sourceLine, ":L%s:%d: " fmt, gTestRunnerState.test->filename, sourceLine, ##__VA_ARGS__); } while (0)
|
||||
|
||||
#define STATE gBattleTestRunnerState
|
||||
#define DATA gBattleTestRunnerState->data
|
||||
|
@ -145,21 +145,6 @@ static bool32 IsAITest(void)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static u32 SourceLine(u32 sourceLineOffset)
|
||||
{
|
||||
const struct BattleTest *test = GetBattleTest();
|
||||
return test->sourceLine + sourceLineOffset;
|
||||
}
|
||||
|
||||
static u32 SourceLineOffset(u32 sourceLine)
|
||||
{
|
||||
const struct BattleTest *test = GetBattleTest();
|
||||
if (sourceLine - test->sourceLine > 0xFF)
|
||||
return 0;
|
||||
else
|
||||
return sourceLine - test->sourceLine;
|
||||
}
|
||||
|
||||
static u32 BattleTest_EstimateCost(void *data)
|
||||
{
|
||||
u32 cost;
|
||||
|
@ -184,9 +169,9 @@ static void BattleTest_SetUp(void *data)
|
|||
InvokeTestFunction(test);
|
||||
STATE->parameters = STATE->parametersCount;
|
||||
if (STATE->parametersCount == 0 && test->resultsSize > 0)
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, "results without PARAMETRIZE");
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, SourceLine(0), ":Lresults without PARAMETRIZE");
|
||||
if (sizeof(*STATE) + test->resultsSize * STATE->parameters > sizeof(sBackupMapData))
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, "OOM: STATE (%d) + STATE->results (%d) too big for sBackupMapData (%d)", sizeof(*STATE), test->resultsSize * STATE->parameters, sizeof(sBackupMapData));
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, SourceLine(0), ":LOOM: STATE (%d) + STATE->results (%d) too big for sBackupMapData (%d)", sizeof(*STATE), test->resultsSize * STATE->parameters, sizeof(sBackupMapData));
|
||||
STATE->results = (void *)((char *)sBackupMapData + sizeof(struct BattleTestRunnerState));
|
||||
memset(STATE->results, 0, test->resultsSize * STATE->parameters);
|
||||
switch (test->type)
|
||||
|
@ -260,7 +245,7 @@ static void SetImplicitSpeeds(void)
|
|||
}
|
||||
}
|
||||
if (!madeProgress)
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, "TURNs have contradictory speeds");
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, SourceLine(0), ":LTURNs have contradictory speeds");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -334,9 +319,9 @@ static void BattleTest_Run(void *data)
|
|||
requiredOpponentPartySize = DATA.currentMonIndexes[i] + 1;
|
||||
}
|
||||
if (DATA.playerPartySize < requiredPlayerPartySize)
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, "%d PLAYER Pokemon required", requiredPlayerPartySize);
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, SourceLine(0), ":L%d PLAYER Pokemon required", requiredPlayerPartySize);
|
||||
if (DATA.opponentPartySize < requiredOpponentPartySize)
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, "%d OPPONENT Pokemon required", requiredOpponentPartySize);
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, SourceLine(0), ":L%d OPPONENT Pokemon required", requiredOpponentPartySize);
|
||||
|
||||
for (i = 0; i < STATE->battlersCount; i++)
|
||||
PushBattlerAction(0, i, RECORDED_BYTE, 0xFF);
|
||||
|
@ -346,7 +331,7 @@ static void BattleTest_Run(void *data)
|
|||
if (DATA.explicitSpeeds[B_SIDE_PLAYER] != (1 << DATA.playerPartySize) - 1
|
||||
&& DATA.explicitSpeeds[B_SIDE_OPPONENT] != (1 << DATA.opponentPartySize) - 1)
|
||||
{
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, "Speed required for all PLAYERs and OPPONENTs");
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, SourceLine(0), ":LSpeed required for all PLAYERs and OPPONENTs");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -392,7 +377,7 @@ u32 RandomUniform(enum RandomTag tag, u32 lo, u32 hi)
|
|||
}
|
||||
else if (STATE->trials != n)
|
||||
{
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, "RandomUniform called with inconsistent trials %d and %d", STATE->trials, n);
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, SourceLine(0), ":LRandomUniform called with inconsistent trials %d and %d", STATE->trials, n);
|
||||
}
|
||||
STATE->trialRatio = Q_4_12(1) / STATE->trials;
|
||||
return STATE->runTrial + lo;
|
||||
|
@ -413,7 +398,7 @@ u32 RandomUniformExcept(enum RandomTag tag, u32 lo, u32 hi, bool32 (*reject)(u32
|
|||
if (turn && turn->rng.tag == tag)
|
||||
{
|
||||
if (reject(turn->rng.value))
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, "WITH_RNG specified a rejected value (%d)", turn->rng.value);
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, SourceLine(0), ":LWITH_RNG specified a rejected value (%d)", turn->rng.value);
|
||||
return turn->rng.value;
|
||||
}
|
||||
}
|
||||
|
@ -434,7 +419,7 @@ u32 RandomUniformExcept(enum RandomTag tag, u32 lo, u32 hi, bool32 (*reject)(u32
|
|||
while (reject(STATE->runTrial + lo + STATE->rngTrialOffset))
|
||||
{
|
||||
if (STATE->runTrial + lo + STATE->rngTrialOffset > hi)
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, "RandomUniformExcept called with inconsistent reject");
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, SourceLine(0), ":LRandomUniformExcept called with inconsistent reject");
|
||||
STATE->rngTrialOffset++;
|
||||
}
|
||||
|
||||
|
@ -445,7 +430,7 @@ u32 RandomUniformExcept(enum RandomTag tag, u32 lo, u32 hi, bool32 (*reject)(u32
|
|||
while (reject(default_))
|
||||
{
|
||||
if (default_ == lo)
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, "RandomUniformExcept rejected all values");
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, SourceLine(0), ":LRandomUniformExcept rejected all values");
|
||||
default_--;
|
||||
}
|
||||
return default_;
|
||||
|
@ -456,7 +441,7 @@ u32 RandomWeightedArray(enum RandomTag tag, u32 sum, u32 n, const u8 *weights)
|
|||
const struct BattlerTurn *turn = NULL;
|
||||
|
||||
if (sum == 0)
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, "RandomWeightedArray called with zero sum");
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, SourceLine(0), ":LRandomWeightedArray called with zero sum");
|
||||
|
||||
if (gCurrentTurnActionNumber < gBattlersCount)
|
||||
{
|
||||
|
@ -475,7 +460,7 @@ u32 RandomWeightedArray(enum RandomTag tag, u32 sum, u32 n, const u8 *weights)
|
|||
}
|
||||
else if (STATE->trials != n)
|
||||
{
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, "RandomWeighted called with inconsistent trials %d and %d", STATE->trials, n);
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, SourceLine(0), ":LRandomWeighted called with inconsistent trials %d and %d", STATE->trials, n);
|
||||
}
|
||||
// TODO: Detect inconsistent sum.
|
||||
STATE->trialRatio = Q_4_12(weights[STATE->runTrial]) / sum;
|
||||
|
@ -509,7 +494,7 @@ u32 RandomWeightedArray(enum RandomTag tag, u32 sum, u32 n, const u8 *weights)
|
|||
while (weights[n-1] == 0)
|
||||
{
|
||||
if (n == 1)
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, "RandomWeightedArray called with all zero weights");
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, SourceLine(0), ":LRandomWeightedArray called with all zero weights");
|
||||
n--;
|
||||
}
|
||||
return n-1;
|
||||
|
@ -535,7 +520,7 @@ const void *RandomElementArray(enum RandomTag tag, const void *array, size_t siz
|
|||
return (const u8 *)array + size * index;
|
||||
}
|
||||
// TODO: Incorporate the line number.
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, "%s: RandomElement illegal value requested: %d", gTestRunnerState.test->filename, turn->rng.value);
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, SourceLine(0), ":L%s: RandomElement illegal value requested: %d", gTestRunnerState.test->filename, turn->rng.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -548,7 +533,7 @@ const void *RandomElementArray(enum RandomTag tag, const void *array, size_t siz
|
|||
}
|
||||
else if (STATE->trials != count)
|
||||
{
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, "RandomElement called with inconsistent trials %d and %d", STATE->trials, count);
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, SourceLine(0), ":LRandomElement called with inconsistent trials %d and %d", STATE->trials, count);
|
||||
}
|
||||
STATE->trialRatio = Q_4_12(1) / count;
|
||||
return (const u8 *)array + size * STATE->runTrial;
|
||||
|
@ -599,7 +584,7 @@ void TestRunner_Battle_RecordAbilityPopUp(u32 battlerId, u32 ability)
|
|||
{
|
||||
const char *filename = gTestRunnerState.test->filename;
|
||||
u32 line = SourceLine(DATA.queuedEvents[match].sourceLineOffset);
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: Matched ABILITY_POPUP", filename, line);
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, line, ":L%s:%d: Matched ABILITY_POPUP", filename, line);
|
||||
}
|
||||
|
||||
queuedEvent += event->groupSize;
|
||||
|
@ -662,7 +647,7 @@ void TestRunner_Battle_RecordAnimation(u32 animType, u32 animId)
|
|||
{
|
||||
const char *filename = gTestRunnerState.test->filename;
|
||||
u32 line = SourceLine(DATA.queuedEvents[match].sourceLineOffset);
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: Matched ANIMATION", filename, line);
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, line, ":L%s:%d: Matched ANIMATION", filename, line);
|
||||
}
|
||||
|
||||
queuedEvent += event->groupSize;
|
||||
|
@ -752,7 +737,7 @@ void TestRunner_Battle_RecordHP(u32 battlerId, u32 oldHP, u32 newHP)
|
|||
{
|
||||
const char *filename = gTestRunnerState.test->filename;
|
||||
u32 line = SourceLine(DATA.queuedEvents[match].sourceLineOffset);
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: Matched HP_BAR", filename, line);
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, line, ":L%s:%d: Matched HP_BAR", filename, line);
|
||||
}
|
||||
|
||||
queuedEvent += event->groupSize;
|
||||
|
@ -807,10 +792,10 @@ void TestRunner_Battle_CheckChosenMove(u32 battlerId, u32 moveId, u32 target)
|
|||
bool32 movePasses = FALSE;
|
||||
|
||||
if (expectedAction->type != B_ACTION_USE_MOVE)
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: Expected %s, got MOVE", filename, expectedAction->sourceLine, sBattleActionNames[expectedAction->type]);
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, SourceLine(0), ":L%s:%d: Expected %s, got MOVE", filename, expectedAction->sourceLine, sBattleActionNames[expectedAction->type]);
|
||||
|
||||
if (expectedAction->explicitTarget && expectedAction->target != target)
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: Expected target %s, got %s", filename, expectedAction->sourceLine, BattlerIdentifier(expectedAction->target), BattlerIdentifier(target));
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, SourceLine(0), ":L%s:%d: Expected target %s, got %s", filename, expectedAction->sourceLine, BattlerIdentifier(expectedAction->target), BattlerIdentifier(target));
|
||||
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
|
@ -844,16 +829,16 @@ void TestRunner_Battle_CheckChosenMove(u32 battlerId, u32 moveId, u32 target)
|
|||
u32 moveSlot = GetMoveSlot(gBattleMons[battlerId].moves, moveId);
|
||||
PrintAiMoveLog(battlerId, moveSlot, moveId, gBattleStruct->aiFinalScore[battlerId][expectedAction->target][moveSlot]);
|
||||
if (countExpected > 1)
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: Unmatched EXPECT_MOVES %S, got %S", filename, expectedAction->sourceLine, GetMoveName(expectedMoveId), GetMoveName(moveId));
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, SourceLine(0), ":L%s:%d: Unmatched EXPECT_MOVES %S, got %S", filename, expectedAction->sourceLine, GetMoveName(expectedMoveId), GetMoveName(moveId));
|
||||
else
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: Unmatched EXPECT_MOVE %S, got %S", filename, expectedAction->sourceLine, GetMoveName(expectedMoveId), GetMoveName(moveId));
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, SourceLine(0), ":L%s:%d: Unmatched EXPECT_MOVE %S, got %S", filename, expectedAction->sourceLine, GetMoveName(expectedMoveId), GetMoveName(moveId));
|
||||
}
|
||||
if (expectedAction->notMove && !movePasses)
|
||||
{
|
||||
if (countExpected > 1)
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: Unmatched NOT_EXPECT_MOVES %S", filename, expectedAction->sourceLine, GetMoveName(expectedMoveId));
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, SourceLine(0), ":L%s:%d: Unmatched NOT_EXPECT_MOVES %S", filename, expectedAction->sourceLine, GetMoveName(expectedMoveId));
|
||||
else
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: Unmatched NOT_EXPECT_MOVE %S", filename, expectedAction->sourceLine, GetMoveName(expectedMoveId));
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, SourceLine(0), ":L%s:%d: Unmatched NOT_EXPECT_MOVE %S", filename, expectedAction->sourceLine, GetMoveName(expectedMoveId));
|
||||
}
|
||||
}
|
||||
// Turn passed, clear logs from the turn
|
||||
|
@ -873,17 +858,17 @@ void TestRunner_Battle_CheckSwitch(u32 battlerId, u32 partyIndex)
|
|||
if (!expectedAction->pass)
|
||||
{
|
||||
if (expectedAction->type != B_ACTION_SWITCH)
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: Expected %s, got SWITCH/SEND_OUT", filename, expectedAction->sourceLine, sBattleActionNames[expectedAction->type]);
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, SourceLine(0), ":L%s:%d: Expected %s, got SWITCH/SEND_OUT", filename, expectedAction->sourceLine, sBattleActionNames[expectedAction->type]);
|
||||
|
||||
if (expectedAction->target != partyIndex)
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: Expected partyIndex %d, got %d", filename, expectedAction->sourceLine, expectedAction->target, partyIndex);
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, SourceLine(0), ":L%s:%d: Expected partyIndex %d, got %d", filename, expectedAction->sourceLine, expectedAction->target, partyIndex);
|
||||
}
|
||||
DATA.aiActionsPlayed[battlerId]++;
|
||||
}
|
||||
|
||||
void TestRunner_Battle_InvalidNoHPMon(u32 battlerId, u32 partyIndex)
|
||||
{
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, "%s: INVALID: %s trying to send out a mon(id: %d) with 0 HP.",
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, SourceLine(0), ":L%s: INVALID: %s trying to send out a mon(id: %d) with 0 HP.",
|
||||
gTestRunnerState.test->filename, BattlerIdentifier(battlerId), gBattlerPartyIndexes[battlerId]);
|
||||
}
|
||||
|
||||
|
@ -933,7 +918,7 @@ static void CheckIfMaxScoreEqualExpectMove(u32 battlerId, s32 target, struct Exp
|
|||
&& (aiAction->moveSlots & gBitTable[i])
|
||||
&& !(aiAction->moveSlots & gBitTable[bestScoreId]))
|
||||
{
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: EXPECT_MOVE %S has the same best score(%d) as not expected MOVE %S", filename,
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, SourceLine(0), ":L%s:%d: EXPECT_MOVE %S has the same best score(%d) as not expected MOVE %S", filename,
|
||||
aiAction->sourceLine, GetMoveName(moves[i]), scores[i], GetMoveName(moves[bestScoreId]));
|
||||
}
|
||||
// We DO NOT expect move 'i', but it has the same best score as another move.
|
||||
|
@ -942,7 +927,7 @@ static void CheckIfMaxScoreEqualExpectMove(u32 battlerId, s32 target, struct Exp
|
|||
&& (aiAction->moveSlots & gBitTable[i])
|
||||
&& !(aiAction->moveSlots & gBitTable[bestScoreId]))
|
||||
{
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: NOT_EXPECT_MOVE %S has the same best score(%d) as MOVE %S", filename,
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, SourceLine(0), ":L%s:%d: NOT_EXPECT_MOVE %S has the same best score(%d) as MOVE %S", filename,
|
||||
aiAction->sourceLine, GetMoveName(moves[i]), scores[i], GetMoveName(moves[bestScoreId]));
|
||||
}
|
||||
}
|
||||
|
@ -985,7 +970,7 @@ static void PrintAiMoveLog(u32 battlerId, u32 moveSlot, u32 moveId, s32 totalSco
|
|||
}
|
||||
if (scoreFromLogs != totalScore)
|
||||
{
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, "Warning! Score from logs(%d) is different than actual score(%d). Make sure all of the score adjustments use the ADJUST_SCORE macro\n", scoreFromLogs, totalScore);
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, SourceLine(0), ":LWarning! Score from logs(%d) is different than actual score(%d). Make sure all of the score adjustments use the ADJUST_SCORE macro\n", scoreFromLogs, totalScore);
|
||||
}
|
||||
MgbaPrintf_("Total: %d\n", totalScore);
|
||||
}
|
||||
|
@ -1023,7 +1008,7 @@ void TestRunner_Battle_CheckAiMoveScores(u32 battlerId)
|
|||
PrintAiMoveLog(battlerId, scoreCtx->moveSlot1, moveId1, scores[scoreCtx->moveSlot1]);
|
||||
if (!CheckComparision(scores[scoreCtx->moveSlot1], scoreCtx->value, scoreCtx->cmp))
|
||||
{
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: Unmatched SCORE_%s_VAL %S %d, got %d",
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, SourceLine(0), ":L%s:%d: Unmatched SCORE_%s_VAL %S %d, got %d",
|
||||
filename, scoreCtx->sourceLine, sCmpToStringTable[scoreCtx->cmp], GetMoveName(moveId1), scoreCtx->value, scores[scoreCtx->moveSlot1]);
|
||||
}
|
||||
}
|
||||
|
@ -1034,7 +1019,7 @@ void TestRunner_Battle_CheckAiMoveScores(u32 battlerId)
|
|||
PrintAiMoveLog(battlerId, scoreCtx->moveSlot2, moveId2, scores[scoreCtx->moveSlot2]);
|
||||
if (!CheckComparision(scores[scoreCtx->moveSlot1], scores[scoreCtx->moveSlot2], scoreCtx->cmp))
|
||||
{
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: Unmatched SCORE_%s, got %S: %d, %S: %d",
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, SourceLine(0), ":L%s:%d: Unmatched SCORE_%s, got %S: %d, %S: %d",
|
||||
filename, scoreCtx->sourceLine, sCmpToStringTable[scoreCtx->cmp], GetMoveName(moveId1), scores[scoreCtx->moveSlot1], GetMoveName(moveId2), scores[scoreCtx->moveSlot2]);
|
||||
}
|
||||
}
|
||||
|
@ -1134,7 +1119,7 @@ void TestRunner_Battle_RecordExp(u32 battlerId, u32 oldExp, u32 newExp)
|
|||
{
|
||||
const char *filename = gTestRunnerState.test->filename;
|
||||
u32 line = SourceLine(DATA.queuedEvents[match].sourceLineOffset);
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: Matched EXPERIENCE_BAR", filename, line);
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, line, ":L%s:%d: Matched EXPERIENCE_BAR", filename, line);
|
||||
}
|
||||
|
||||
queuedEvent += event->groupSize;
|
||||
|
@ -1223,7 +1208,7 @@ void TestRunner_Battle_RecordMessage(const u8 *string)
|
|||
{
|
||||
const char *filename = gTestRunnerState.test->filename;
|
||||
u32 line = SourceLine(DATA.queuedEvents[match].sourceLineOffset);
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: Matched MESSAGE", filename, line);
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, line, ":L%s:%d: Matched MESSAGE", filename, line);
|
||||
}
|
||||
|
||||
queuedEvent += event->groupSize;
|
||||
|
@ -1288,7 +1273,7 @@ void TestRunner_Battle_RecordStatus1(u32 battlerId, u32 status1)
|
|||
{
|
||||
const char *filename = gTestRunnerState.test->filename;
|
||||
u32 line = SourceLine(DATA.queuedEvents[match].sourceLineOffset);
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: Matched STATUS_ICON", filename, line);
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, line, ":L%s:%d: Matched STATUS_ICON", filename, line);
|
||||
}
|
||||
|
||||
queuedEvent += event->groupSize;
|
||||
|
@ -1323,7 +1308,7 @@ void TestRunner_Battle_AfterLastTurn(void)
|
|||
if (DATA.turns - 1 != DATA.lastActionTurn)
|
||||
{
|
||||
const char *filename = gTestRunnerState.test->filename;
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: %d TURNs specified, but %d ran", filename, SourceLine(0), DATA.turns, DATA.lastActionTurn + 1);
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, SourceLine(0), ":L%s:%d: %d TURNs specified, but %d ran", filename, SourceLine(0), DATA.turns, DATA.lastActionTurn + 1);
|
||||
}
|
||||
|
||||
while (DATA.queuedEvent < DATA.queuedEventsCount
|
||||
|
@ -1336,7 +1321,7 @@ void TestRunner_Battle_AfterLastTurn(void)
|
|||
const char *filename = gTestRunnerState.test->filename;
|
||||
u32 line = SourceLine(DATA.queuedEvents[DATA.queuedEvent].sourceLineOffset);
|
||||
const char *macro = sEventTypeMacros[DATA.queuedEvents[DATA.queuedEvent].type];
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: Unmatched %s", filename, line, macro);
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, line, ":L%s:%d: Unmatched %s", filename, line, macro);
|
||||
}
|
||||
|
||||
STATE->runThen = TRUE;
|
||||
|
@ -1418,7 +1403,7 @@ static void CB2_BattleTest_NextTrial(void)
|
|||
if (abs(STATE->observedRatio - STATE->expectedRatio) <= Q_4_12(0.02))
|
||||
gTestRunnerState.result = TEST_RESULT_PASS;
|
||||
else
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "Expected %q passes/successes, observed %q", STATE->expectedRatio, STATE->observedRatio);
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, SourceLine(0), ":L%s:%d: Expected %q passes/successes, observed %q", gTestRunnerState.test->filename, SourceLine(0), STATE->expectedRatio, STATE->observedRatio);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1831,7 +1816,7 @@ static void PushBattlerAction(u32 sourceLine, s32 battlerId, u32 actionType, u32
|
|||
{
|
||||
u32 recordIndex = DATA.recordIndexes[battlerId]++;
|
||||
if (recordIndex >= BATTLER_RECORD_SIZE)
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, "Too many actions");
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, SourceLine(0), ":LToo many actions");
|
||||
DATA.battleRecordTypes[battlerId][recordIndex] = actionType;
|
||||
DATA.battleRecordSourceLineOffsets[battlerId][recordIndex] = SourceLineOffset(sourceLine);
|
||||
DATA.recordedBattle.battleRecord[battlerId][recordIndex] = byte;
|
||||
|
@ -1853,10 +1838,10 @@ void TestRunner_Battle_CheckBattleRecordActionType(u32 battlerId, u32 recordInde
|
|||
&& DATA.recordedBattle.battleRecord[battlerId][i-1] == B_ACTION_USE_MOVE)
|
||||
{
|
||||
u32 line = SourceLine(DATA.battleRecordSourceLineOffsets[battlerId][i-1]);
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, "%s:%d: Illegal MOVE", filename, line);
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, line, ":L%s:%d: Illegal MOVE", filename, line);
|
||||
}
|
||||
}
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, "%s:%d: Illegal MOVE", filename, SourceLine(0));
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, SourceLine(0), ":L%s:%d: Illegal MOVE", filename, SourceLine(0));
|
||||
}
|
||||
|
||||
if (DATA.battleRecordTypes[battlerId][recordIndex] != RECORDED_BYTE)
|
||||
|
@ -1884,13 +1869,13 @@ void TestRunner_Battle_CheckBattleRecordActionType(u32 battlerId, u32 recordInde
|
|||
switch (actionType)
|
||||
{
|
||||
case RECORDED_ACTION_TYPE:
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, "%s:%d: Expected MOVE/SWITCH, got %s", filename, line, actualMacro);
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, line, ":L%s:%d: Expected MOVE/SWITCH, got %s", filename, line, actualMacro);
|
||||
case RECORDED_PARTY_INDEX:
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, "%s:%d: Expected SEND_OUT, got %s", filename, line, actualMacro);
|
||||
Test_ExitWithResult(TEST_RESULT_INVALID, line, ":L%s:%d: Expected SEND_OUT, got %s", filename, line, actualMacro);
|
||||
}
|
||||
}
|
||||
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, "%s:%d: Illegal battle record", filename, line);
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, line, ":L%s:%d: Illegal battle record", filename, line);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1898,7 +1883,7 @@ void TestRunner_Battle_CheckBattleRecordActionType(u32 battlerId, u32 recordInde
|
|||
if (DATA.lastActionTurn == gBattleResults.battleTurnCounter)
|
||||
{
|
||||
const char *filename = gTestRunnerState.test->filename;
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, "%s:%d: TURN %d incomplete", filename, SourceLine(0), gBattleResults.battleTurnCounter + 1);
|
||||
Test_ExitWithResult(TEST_RESULT_FAIL, SourceLine(0), ":L%s:%d: TURN %d incomplete", filename, SourceLine(0), gBattleResults.battleTurnCounter + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1907,7 +1892,7 @@ void OpenTurn(u32 sourceLine)
|
|||
{
|
||||
INVALID_IF(DATA.turnState != TURN_CLOSED, "Nested TURN");
|
||||
if (DATA.turns == MAX_TURNS)
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, "%s:%d: TURN exceeds MAX_TURNS", gTestRunnerState.test->filename, sourceLine);
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, sourceLine, ":L%s:%d: TURN exceeds MAX_TURNS", gTestRunnerState.test->filename, sourceLine);
|
||||
DATA.turnState = TURN_OPEN;
|
||||
DATA.actionBattlers = 0x00;
|
||||
DATA.moveBattlers = 0x00;
|
||||
|
@ -2422,7 +2407,7 @@ void QueueAbility(u32 sourceLine, struct BattlePokemon *battler, struct AbilityE
|
|||
s32 battlerId = battler - gBattleMons;
|
||||
INVALID_IF(!STATE->runScene, "ABILITY_POPUP outside of SCENE");
|
||||
if (DATA.queuedEventsCount == MAX_QUEUED_EVENTS)
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, "%s:%d: ABILITY exceeds MAX_QUEUED_EVENTS", gTestRunnerState.test->filename, sourceLine);
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, sourceLine, ":L%s:%d: ABILITY exceeds MAX_QUEUED_EVENTS", gTestRunnerState.test->filename, sourceLine);
|
||||
DATA.queuedEvents[DATA.queuedEventsCount++] = (struct QueuedEvent) {
|
||||
.type = QUEUED_ABILITY_POPUP_EVENT,
|
||||
.sourceLineOffset = SourceLineOffset(sourceLine),
|
||||
|
@ -2442,7 +2427,7 @@ void QueueAnimation(u32 sourceLine, u32 type, u32 id, struct AnimationEventConte
|
|||
|
||||
INVALID_IF(!STATE->runScene, "ANIMATION outside of SCENE");
|
||||
if (DATA.queuedEventsCount == MAX_QUEUED_EVENTS)
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, "%s:%d: ANIMATION exceeds MAX_QUEUED_EVENTS", gTestRunnerState.test->filename, sourceLine);
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, sourceLine, ":L%s:%d: ANIMATION exceeds MAX_QUEUED_EVENTS", gTestRunnerState.test->filename, sourceLine);
|
||||
|
||||
attackerId = ctx.attacker ? ctx.attacker - gBattleMons : 0xF;
|
||||
if (type == ANIM_TYPE_MOVE)
|
||||
|
@ -2477,7 +2462,7 @@ void QueueHP(u32 sourceLine, struct BattlePokemon *battler, struct HPEventContex
|
|||
|
||||
INVALID_IF(!STATE->runScene, "HP_BAR outside of SCENE");
|
||||
if (DATA.queuedEventsCount == MAX_QUEUED_EVENTS)
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, "%s:%d: HP_BAR exceeds MAX_QUEUED_EVENTS", gTestRunnerState.test->filename, sourceLine);
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, sourceLine, ":L%s:%d: HP_BAR exceeds MAX_QUEUED_EVENTS", gTestRunnerState.test->filename, sourceLine);
|
||||
|
||||
if (ctx.explicitHP)
|
||||
{
|
||||
|
@ -2530,7 +2515,7 @@ void QueueExp(u32 sourceLine, struct BattlePokemon *battler, struct ExpEventCont
|
|||
|
||||
INVALID_IF(!STATE->runScene, "EXPERIENCE_BAR outside of SCENE");
|
||||
if (DATA.queuedEventsCount == MAX_QUEUED_EVENTS)
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, "%s:%d: EXPERIENCE_BAR exceeds MAX_QUEUED_EVENTS", gTestRunnerState.test->filename, sourceLine);
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, sourceLine, ":L%s:%d: EXPERIENCE_BAR exceeds MAX_QUEUED_EVENTS", gTestRunnerState.test->filename, sourceLine);
|
||||
|
||||
if (ctx.explicitExp)
|
||||
{
|
||||
|
@ -2567,7 +2552,7 @@ void QueueMessage(u32 sourceLine, const u8 *pattern)
|
|||
{
|
||||
INVALID_IF(!STATE->runScene, "MESSAGE outside of SCENE");
|
||||
if (DATA.queuedEventsCount == MAX_QUEUED_EVENTS)
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, "%s:%d: MESSAGE exceeds MAX_QUEUED_EVENTS", gTestRunnerState.test->filename, sourceLine);
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, sourceLine, ":L%s:%d: MESSAGE exceeds MAX_QUEUED_EVENTS", gTestRunnerState.test->filename, sourceLine);
|
||||
DATA.queuedEvents[DATA.queuedEventsCount++] = (struct QueuedEvent) {
|
||||
.type = QUEUED_MESSAGE_EVENT,
|
||||
.sourceLineOffset = SourceLineOffset(sourceLine),
|
||||
|
@ -2586,7 +2571,7 @@ void QueueStatus(u32 sourceLine, struct BattlePokemon *battler, struct StatusEve
|
|||
|
||||
INVALID_IF(!STATE->runScene, "STATUS_ICON outside of SCENE");
|
||||
if (DATA.queuedEventsCount == MAX_QUEUED_EVENTS)
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, "%s:%d: STATUS_ICON exceeds MAX_QUEUED_EVENTS", gTestRunnerState.test->filename, sourceLine);
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, sourceLine, ":L%s:%d: STATUS_ICON exceeds MAX_QUEUED_EVENTS", gTestRunnerState.test->filename, sourceLine);
|
||||
|
||||
if (ctx.none)
|
||||
mask = 0;
|
||||
|
@ -2645,7 +2630,7 @@ struct AILogLine *GetLogLine(u32 battlerId, u32 moveIndex)
|
|||
}
|
||||
}
|
||||
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, "Too many AI log lines");
|
||||
Test_ExitWithResult(TEST_RESULT_ERROR, SourceLine(0), ":LToo many AI log lines");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
*
|
||||
* COMMANDS
|
||||
* N: Sets the test name to the remainder of the line.
|
||||
* L: Sets the filename to the remainder of the line.
|
||||
* R: Sets the result to the remainder of the line, and flushes any
|
||||
* output buffered since the previous R.
|
||||
* P/K/F/A: Sets the result to the remaining of the line, flushes any
|
||||
|
@ -46,6 +47,7 @@ struct Runner
|
|||
int outfd;
|
||||
char rom_path[FILENAME_MAX];
|
||||
char test_name[256];
|
||||
char filename_line[256];
|
||||
size_t input_buffer_size;
|
||||
size_t input_buffer_capacity;
|
||||
char *input_buffer;
|
||||
|
@ -59,8 +61,12 @@ struct Runner
|
|||
int assumptionFails;
|
||||
int fails;
|
||||
int results;
|
||||
char failedTestNames[MAX_SUMMARY_TESTS_TO_LIST][MAX_TEST_LIST_BUFFER_LENGTH];
|
||||
char knownFailingPassedTestNames[MAX_SUMMARY_TESTS_TO_LIST][MAX_TEST_LIST_BUFFER_LENGTH];
|
||||
char failed_TestNames[MAX_SUMMARY_TESTS_TO_LIST][MAX_TEST_LIST_BUFFER_LENGTH];
|
||||
char failed_TestFilenameLine[MAX_SUMMARY_TESTS_TO_LIST][MAX_TEST_LIST_BUFFER_LENGTH];
|
||||
char knownFailingPassed_TestNames[MAX_SUMMARY_TESTS_TO_LIST][MAX_TEST_LIST_BUFFER_LENGTH];
|
||||
char knownFailingPassed_FilenameLine[MAX_SUMMARY_TESTS_TO_LIST][MAX_TEST_LIST_BUFFER_LENGTH];
|
||||
char assumeFailed_TestNames[MAX_SUMMARY_TESTS_TO_LIST * MAX_PROCESSES][MAX_TEST_LIST_BUFFER_LENGTH];
|
||||
char assumeFailed_FilenameLine[MAX_SUMMARY_TESTS_TO_LIST * MAX_PROCESSES][MAX_TEST_LIST_BUFFER_LENGTH];
|
||||
};
|
||||
|
||||
static unsigned nrunners = 0;
|
||||
|
@ -102,6 +108,16 @@ static void handle_read(int i, struct Runner *runner)
|
|||
strncpy(runner->test_name, soc, eol - soc - 1);
|
||||
runner->test_name[eol - soc - 1] = '\0';
|
||||
break;
|
||||
case 'L':
|
||||
soc += 2;
|
||||
if (sizeof(runner->filename_line) <= eol - soc - 1)
|
||||
{
|
||||
fprintf(stderr, "filename_line too long\n");
|
||||
exit(2);
|
||||
}
|
||||
strncpy(runner->filename_line, soc, eol - soc - 1);
|
||||
runner->filename_line[eol - soc - 1] = '\0';
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
runner->passes++;
|
||||
|
@ -111,18 +127,29 @@ static void handle_read(int i, struct Runner *runner)
|
|||
goto add_to_results;
|
||||
case 'U':
|
||||
if (runner->knownFailsPassing < MAX_SUMMARY_TESTS_TO_LIST)
|
||||
strcpy(runner->knownFailingPassedTestNames[runner->knownFailsPassing], runner->test_name);
|
||||
{
|
||||
strcpy(runner->knownFailingPassed_TestNames[runner->knownFailsPassing], runner->test_name);
|
||||
strcpy(runner->knownFailingPassed_FilenameLine[runner->knownFailsPassing], runner->filename_line);
|
||||
}
|
||||
runner->knownFailsPassing++;
|
||||
goto add_to_results;
|
||||
case 'T':
|
||||
runner->todos++;
|
||||
goto add_to_results;
|
||||
case 'A':
|
||||
if (runner->assumptionFails < MAX_SUMMARY_TESTS_TO_LIST)
|
||||
{
|
||||
strcpy(runner->assumeFailed_TestNames[runner->assumptionFails], runner->test_name);
|
||||
strcpy(runner->assumeFailed_FilenameLine[runner->assumptionFails], runner->filename_line);
|
||||
}
|
||||
runner->assumptionFails++;
|
||||
goto add_to_results;
|
||||
case 'F':
|
||||
if (runner->fails < MAX_SUMMARY_TESTS_TO_LIST)
|
||||
strcpy(runner->failedTestNames[runner->fails], runner->test_name);
|
||||
{
|
||||
strcpy(runner->failed_TestNames[runner->fails], runner->test_name);
|
||||
strcpy(runner->failed_TestFilenameLine[runner->fails], runner->filename_line);
|
||||
}
|
||||
runner->fails++;
|
||||
add_to_results:
|
||||
runner->results++;
|
||||
|
@ -532,8 +559,14 @@ int main(int argc, char *argv[])
|
|||
int fails = 0;
|
||||
int results = 0;
|
||||
|
||||
char failedTestNames[MAX_SUMMARY_TESTS_TO_LIST * MAX_PROCESSES][MAX_TEST_LIST_BUFFER_LENGTH];
|
||||
char knownFailingPassedTestNames[MAX_SUMMARY_TESTS_TO_LIST * MAX_PROCESSES][MAX_TEST_LIST_BUFFER_LENGTH];
|
||||
char failed_TestNames[MAX_SUMMARY_TESTS_TO_LIST * MAX_PROCESSES][MAX_TEST_LIST_BUFFER_LENGTH];
|
||||
char failed_TestFilenameLine[MAX_SUMMARY_TESTS_TO_LIST * MAX_PROCESSES][MAX_TEST_LIST_BUFFER_LENGTH];
|
||||
|
||||
char knownFailingPassed_TestNames[MAX_SUMMARY_TESTS_TO_LIST * MAX_PROCESSES][MAX_TEST_LIST_BUFFER_LENGTH];
|
||||
char knownFailingPassed_FilenameLine[MAX_SUMMARY_TESTS_TO_LIST * MAX_PROCESSES][MAX_TEST_LIST_BUFFER_LENGTH];
|
||||
|
||||
char assumeFailed_TestNames[MAX_SUMMARY_TESTS_TO_LIST * MAX_PROCESSES][MAX_TEST_LIST_BUFFER_LENGTH];
|
||||
char assumeFailed_FilenameLine[MAX_SUMMARY_TESTS_TO_LIST * MAX_PROCESSES][MAX_TEST_LIST_BUFFER_LENGTH];
|
||||
|
||||
for (int i = 0; i < nrunners; i++)
|
||||
{
|
||||
|
@ -552,33 +585,43 @@ int main(int argc, char *argv[])
|
|||
for (int j = 0; j < runners[i].knownFailsPassing; j++)
|
||||
{
|
||||
if (j < MAX_SUMMARY_TESTS_TO_LIST)
|
||||
strcpy(knownFailingPassedTestNames[fails], runners[i].knownFailingPassedTestNames[j]);
|
||||
{
|
||||
strcpy(knownFailingPassed_TestNames[knownFailsPassing], runners[i].knownFailingPassed_TestNames[j]);
|
||||
strcpy(knownFailingPassed_FilenameLine[knownFailsPassing], runners[i].knownFailingPassed_FilenameLine[j]);
|
||||
}
|
||||
knownFailsPassing++;
|
||||
}
|
||||
todos += runners[i].todos;
|
||||
assumptionFails += runners[i].assumptionFails;
|
||||
for (int j = 0; j < runners[i].assumptionFails; j++)
|
||||
{
|
||||
if (j < MAX_SUMMARY_TESTS_TO_LIST)
|
||||
{
|
||||
strcpy(assumeFailed_TestNames[assumptionFails], runners[i].assumeFailed_TestNames[j]);
|
||||
strcpy(assumeFailed_FilenameLine[assumptionFails], runners[i].assumeFailed_FilenameLine[j]);
|
||||
}
|
||||
assumptionFails++;
|
||||
}
|
||||
for (int j = 0; j < runners[i].fails; j++)
|
||||
{
|
||||
if (j < MAX_SUMMARY_TESTS_TO_LIST)
|
||||
strcpy(failedTestNames[fails], runners[i].failedTestNames[j]);
|
||||
{
|
||||
strcpy(failed_TestNames[fails], runners[i].failed_TestNames[j]);
|
||||
strcpy(failed_TestFilenameLine[fails], runners[i].failed_TestFilenameLine[j]);
|
||||
}
|
||||
fails++;
|
||||
}
|
||||
results += runners[i].results;
|
||||
}
|
||||
|
||||
qsort(failedTestNames, min(fails, MAX_SUMMARY_TESTS_TO_LIST), sizeof(char) * MAX_TEST_LIST_BUFFER_LENGTH, compare_strings);
|
||||
qsort(knownFailingPassedTestNames, min(fails, MAX_SUMMARY_TESTS_TO_LIST), sizeof(char) * MAX_TEST_LIST_BUFFER_LENGTH, compare_strings);
|
||||
|
||||
if (results == 0)
|
||||
{
|
||||
fprintf(stdout, "\nNo tests found.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stdout, "\n");
|
||||
if (fails > 0)
|
||||
{
|
||||
fprintf(stdout, "- Tests \e[31mFAILED\e[0m : %d Add TESTS='X' to run tests with the defined prefix.\n", fails);
|
||||
fprintf(stdout, "\n \e[31mFAILED\e[0m tests:\n");
|
||||
for (int i = 0; i < fails; i++)
|
||||
{
|
||||
if (i >= MAX_SUMMARY_TESTS_TO_LIST)
|
||||
|
@ -586,31 +629,51 @@ int main(int argc, char *argv[])
|
|||
fprintf(stdout, " - \e[31mand %d more...\e[0m\n", fails - MAX_SUMMARY_TESTS_TO_LIST);
|
||||
break;
|
||||
}
|
||||
fprintf(stdout, " - \e[31m%s\e[0m.\n", failedTestNames[i]);
|
||||
fprintf(stdout, " - \e[31m%s\e[0m - %s.\n", failed_TestFilenameLine[i], failed_TestNames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (assumptionFails > 0)
|
||||
{
|
||||
fprintf(stdout, "\n Tests with \e[33mASSUMPTIONS_FAILED\e[0m:\n");
|
||||
for (int i = 0; i < assumptionFails; i++)
|
||||
{
|
||||
if (i >= MAX_SUMMARY_TESTS_TO_LIST)
|
||||
{
|
||||
fprintf(stdout, " - \e[33mand %d more...\e[0m\n", assumptionFails - MAX_SUMMARY_TESTS_TO_LIST);
|
||||
break;
|
||||
}
|
||||
fprintf(stdout, " - \e[33m%s\e[0m - %s.\n", assumeFailed_FilenameLine[i], assumeFailed_TestNames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (knownFailsPassing > 0)
|
||||
{
|
||||
fprintf(stdout, "- \e[31mKNOWN_FAILING_PASSED\e[0m: %d \e[31mPlease remove KNOWN_FAILING if these tests intentionally PASS\e[0m\n", knownFailsPassing);
|
||||
fprintf(stdout, "\n \e[33mKNOWN_FAILING\e[0m tests \e[32mPASSING\e[0m:\n");
|
||||
for (int i = 0; i < knownFailsPassing; i++)
|
||||
{
|
||||
if (i >= MAX_SUMMARY_TESTS_TO_LIST)
|
||||
{
|
||||
fprintf(stdout, " - \e[31mand %d more...\e[0m\n", knownFailsPassing - MAX_SUMMARY_TESTS_TO_LIST);
|
||||
fprintf(stdout, " - \e[32mand %d more...\e[0m\n", knownFailsPassing - MAX_SUMMARY_TESTS_TO_LIST);
|
||||
break;
|
||||
}
|
||||
fprintf(stdout, " - \e[31m%s\e[0m.\n", knownFailingPassedTestNames[i]);
|
||||
fprintf(stdout, " - \e[32m%s\e[0m - %s.\n", knownFailingPassed_FilenameLine[i], knownFailingPassed_TestNames[i]);
|
||||
}
|
||||
}
|
||||
fprintf(stdout, "- Tests \e[32mPASSED\e[0m: %d\n", passes);
|
||||
if (knownFails > 0)
|
||||
fprintf(stdout, "- Tests \e[33mKNOWN_FAILING\e[0m: %d\n", knownFails);
|
||||
if (todos > 0)
|
||||
fprintf(stdout, "- Tests \e[33mTO_DO\e[0m: %d\n", todos);
|
||||
if (assumptionFails > 0)
|
||||
fprintf(stdout, "- \e[33mASSUMPTIONS_FAILED\e[0m: %d\n", assumptionFails);
|
||||
|
||||
fprintf(stdout, "- Tests \e[34mTOTAL\e[0m: %d\n", results);
|
||||
fprintf(stdout, "\n");
|
||||
if (fails > 0)
|
||||
fprintf(stdout, "- Tests \e[31mFAILED\e[0m : %d Add TESTS='X' to run tests with the defined prefix.\n", fails);
|
||||
if (knownFails > 0)
|
||||
fprintf(stdout, "- Tests \e[33mKNOWN_FAILING\e[0m: %d\n", knownFails);
|
||||
if (assumptionFails > 0)
|
||||
fprintf(stdout, "- \e[33mASSUMPTIONS_FAILED\e[0m: %d\n", assumptionFails);
|
||||
if (todos > 0)
|
||||
fprintf(stdout, "- Tests \e[33mTO_DO\e[0m: %d\n", todos);
|
||||
if (knownFailsPassing > 0)
|
||||
fprintf(stdout, "- \e[32mKNOWN_FAILING_PASSING\e[0m: %d \e[33mPlease remove KNOWN_FAILING if these tests intentionally PASS\e[0m\n", knownFailsPassing);
|
||||
fprintf(stdout, "- Tests \e[32mPASSED\e[0m: %d\n", passes);
|
||||
fprintf(stdout, "- Tests \e[34mTOTAL\e[0m: %d\n", results);
|
||||
}
|
||||
fprintf(stdout, "\n");
|
||||
|
||||
|
|
Loading…
Reference in a new issue