Skip to content

Commit

Permalink
Improved Test Runner Summary (rh-hideout#4641)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
AsparagusEduardo authored Jul 20, 2024
1 parent f2311b4 commit 9d5e253
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 114 deletions.
2 changes: 1 addition & 1 deletion gflib/malloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
7 changes: 3 additions & 4 deletions include/test/battle.h
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,6 @@ typedef void (*DoubleBattleTestFunction)(void *, const u32, struct BattlePokemon
struct BattleTest
{
u8 type;
u16 sourceLine;
union
{
SingleBattleTestFunction singles;
Expand Down Expand Up @@ -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__)), \
}, \
Expand All @@ -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__)), \
}, \
Expand Down Expand Up @@ -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
30 changes: 18 additions & 12 deletions include/test/test.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,15 @@ struct Test
const char *filename;
const struct TestRunner *runner;
void *data;
u16 sourceLine;
};

struct TestRunnerState
{
u8 state;
u8 exitCode;
const char *skipFilename;
u32 failedAssumptionsBlockLine;
const struct Test *test;
u32 processCosts[MAX_PROCESSES];

Expand Down Expand Up @@ -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, ...);

Expand All @@ -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)
Expand All @@ -95,6 +100,7 @@ s32 MgbaPrintf_(const char *fmt, ...);
.name = "ASSUMPTIONS: " __FILE__, \
.filename = __FILE__, \
.runner = &gAssumptionsRunner, \
.sourceLine = __LINE__, \
.data = Assumptions, \
}; \
static void Assumptions(void)
Expand All @@ -103,62 +109,62 @@ 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) \
do \
{ \
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) \
do \
{ \
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) \
do \
{ \
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) \
do \
{ \
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) \
do \
{ \
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) \
do \
{ \
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; };
Expand Down Expand Up @@ -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) \
Expand All @@ -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 \
Expand All @@ -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
26 changes: 25 additions & 1 deletion test/test_runner.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ void CB2_TestRunner(void)
}

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;
Expand Down Expand Up @@ -216,6 +217,7 @@ void CB2_TestRunner(void)
// 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;
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}
Loading

0 comments on commit 9d5e253

Please sign in to comment.