Test improvements (#3408)

* Run assumptions on all runners

* Make i const in battle tests

This avoids the pitfall of using i in a PARAMETRIZEd test and confusing
the runner.
This commit is contained in:
Martin Griffin 2023-10-12 11:14:07 +01:00 committed by GitHub
parent 482029d7ec
commit f5b149b971
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 28 additions and 23 deletions

View File

@ -472,8 +472,8 @@
enum { BATTLE_TEST_SINGLES, BATTLE_TEST_DOUBLES }; enum { BATTLE_TEST_SINGLES, BATTLE_TEST_DOUBLES };
typedef void (*SingleBattleTestFunction)(void *, u32, struct BattlePokemon *, struct BattlePokemon *); typedef void (*SingleBattleTestFunction)(void *, const u32, struct BattlePokemon *, struct BattlePokemon *);
typedef void (*DoubleBattleTestFunction)(void *, u32, struct BattlePokemon *, struct BattlePokemon *, struct BattlePokemon *, struct BattlePokemon *); typedef void (*DoubleBattleTestFunction)(void *, const u32, struct BattlePokemon *, struct BattlePokemon *, struct BattlePokemon *, struct BattlePokemon *);
struct BattleTest struct BattleTest
{ {
@ -660,7 +660,7 @@ extern struct BattleTestRunnerState *gBattleTestRunnerState;
#define SINGLE_BATTLE_TEST(_name, ...) \ #define SINGLE_BATTLE_TEST(_name, ...) \
struct CAT(Result, __LINE__) { MEMBERS(__VA_ARGS__) }; \ struct CAT(Result, __LINE__) { MEMBERS(__VA_ARGS__) }; \
static void CAT(Test, __LINE__)(struct CAT(Result, __LINE__) *, u32, struct BattlePokemon *, struct BattlePokemon *); \ static void CAT(Test, __LINE__)(struct CAT(Result, __LINE__) *, const u32, struct BattlePokemon *, struct BattlePokemon *); \
__attribute__((section(".tests"))) static const struct Test CAT(sTest, __LINE__) = \ __attribute__((section(".tests"))) static const struct Test CAT(sTest, __LINE__) = \
{ \ { \
.name = _name, \ .name = _name, \
@ -674,11 +674,11 @@ extern struct BattleTestRunnerState *gBattleTestRunnerState;
.resultsSize = sizeof(struct CAT(Result, __LINE__)), \ .resultsSize = sizeof(struct CAT(Result, __LINE__)), \
}, \ }, \
}; \ }; \
static void CAT(Test, __LINE__)(struct CAT(Result, __LINE__) *results, u32 i, struct BattlePokemon *player, struct BattlePokemon *opponent) static void CAT(Test, __LINE__)(struct CAT(Result, __LINE__) *results, const u32 i, struct BattlePokemon *player, struct BattlePokemon *opponent)
#define DOUBLE_BATTLE_TEST(_name, ...) \ #define DOUBLE_BATTLE_TEST(_name, ...) \
struct CAT(Result, __LINE__) { MEMBERS(__VA_ARGS__) }; \ struct CAT(Result, __LINE__) { MEMBERS(__VA_ARGS__) }; \
static void CAT(Test, __LINE__)(struct CAT(Result, __LINE__) *, u32, struct BattlePokemon *, struct BattlePokemon *, struct BattlePokemon *, struct BattlePokemon *); \ static void CAT(Test, __LINE__)(struct CAT(Result, __LINE__) *, const u32, struct BattlePokemon *, struct BattlePokemon *, struct BattlePokemon *, struct BattlePokemon *); \
__attribute__((section(".tests"))) static const struct Test CAT(sTest, __LINE__) = \ __attribute__((section(".tests"))) static const struct Test CAT(sTest, __LINE__) = \
{ \ { \
.name = _name, \ .name = _name, \
@ -692,7 +692,7 @@ extern struct BattleTestRunnerState *gBattleTestRunnerState;
.resultsSize = sizeof(struct CAT(Result, __LINE__)), \ .resultsSize = sizeof(struct CAT(Result, __LINE__)), \
}, \ }, \
}; \ }; \
static void CAT(Test, __LINE__)(struct CAT(Result, __LINE__) *results, u32 i, struct BattlePokemon *playerLeft, struct BattlePokemon *opponentLeft, struct BattlePokemon *playerRight, struct BattlePokemon *opponentRight) static void CAT(Test, __LINE__)(struct CAT(Result, __LINE__) *results, const u32 i, struct BattlePokemon *playerLeft, struct BattlePokemon *opponentLeft, struct BattlePokemon *playerRight, struct BattlePokemon *opponentRight)
/* Parametrize */ /* Parametrize */

View File

@ -8,18 +8,19 @@ ASSUMPTIONS
SINGLE_BATTLE_TEST("Salt Cure inflicts 1/8 of the target's maximum HP as damage per turn") SINGLE_BATTLE_TEST("Salt Cure inflicts 1/8 of the target's maximum HP as damage per turn")
{ {
u32 j;
GIVEN { GIVEN {
PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET);
} WHEN { } WHEN {
TURN { MOVE(player, MOVE_SALT_CURE); } TURN { MOVE(player, MOVE_SALT_CURE); }
for (i = 0; i < 3; i++) for (j = 0; j < 3; j++)
TURN {} TURN {}
} SCENE { } SCENE {
s32 maxHP = GetMonData(&OPPONENT_PARTY[0], MON_DATA_MAX_HP); s32 maxHP = GetMonData(&OPPONENT_PARTY[0], MON_DATA_MAX_HP);
ANIMATION(ANIM_TYPE_MOVE, MOVE_SALT_CURE, player); ANIMATION(ANIM_TYPE_MOVE, MOVE_SALT_CURE, player);
MESSAGE("Foe Wobbuffet is being salt cured!"); MESSAGE("Foe Wobbuffet is being salt cured!");
for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_SALT_CURE_DAMAGE, opponent); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_SALT_CURE_DAMAGE, opponent);
HP_BAR(opponent, damage: maxHP / 8); HP_BAR(opponent, damage: maxHP / 8);
MESSAGE("Foe Wobbuffet is hurt by Salt Cure!"); MESSAGE("Foe Wobbuffet is hurt by Salt Cure!");

View File

@ -3,21 +3,23 @@
SINGLE_BATTLE_TEST("Bad poison deals 1/16th cumulative damage per turn") SINGLE_BATTLE_TEST("Bad poison deals 1/16th cumulative damage per turn")
{ {
u32 j;
GIVEN { GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_TOXIC_POISON); } PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_TOXIC_POISON); }
OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET);
} WHEN { } WHEN {
for (i = 0; i < 4; i++) for (j = 0; j < 4; j++)
TURN {} TURN {}
} SCENE { } SCENE {
s32 maxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP); s32 maxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP);
for (i = 0; i < 4; i++) for (j = 0; j < 4; j++)
HP_BAR(player, damage: maxHP / 16 * (i + 1)); HP_BAR(player, damage: maxHP / 16 * (j + 1));
} }
} }
SINGLE_BATTLE_TEST("Bad poison cumulative damage resets on switch") SINGLE_BATTLE_TEST("Bad poison cumulative damage resets on switch")
{ {
u32 j;
GIVEN { GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_TOXIC_POISON); } PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_TOXIC_POISON); }
PLAYER(SPECIES_WYNAUT); PLAYER(SPECIES_WYNAUT);
@ -31,9 +33,9 @@ SINGLE_BATTLE_TEST("Bad poison cumulative damage resets on switch")
TURN {} TURN {}
} SCENE { } SCENE {
s32 maxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP); s32 maxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP);
for (i = 0; i < 2; i++) for (j = 0; j < 2; j++)
HP_BAR(player, damage: maxHP / 16 * (i + 1)); HP_BAR(player, damage: maxHP / 16 * (j + 1));
for (i = 0; i < 2; i++) for (j = 0; j < 2; j++)
HP_BAR(player, damage: maxHP / 16 * (i + 1)); HP_BAR(player, damage: maxHP / 16 * (j + 1));
} }
} }

View File

@ -3,16 +3,17 @@
SINGLE_BATTLE_TEST("Burn deals 1/16th damage per turn") SINGLE_BATTLE_TEST("Burn deals 1/16th damage per turn")
{ {
u32 j;
GIVEN { GIVEN {
ASSUME(B_BURN_DAMAGE >= GEN_LATEST); ASSUME(B_BURN_DAMAGE >= GEN_LATEST);
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_BURN); } PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_BURN); }
OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET);
} WHEN { } WHEN {
for (i = 0; i < 4; i++) for (j = 0; j < 4; j++)
TURN {} TURN {}
} SCENE { } SCENE {
s32 maxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP); s32 maxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP);
for (i = 0; i < 4; i++) for (j = 0; j < 4; j++)
HP_BAR(player, damage: maxHP / 16); HP_BAR(player, damage: maxHP / 16);
} }
} }

View File

@ -3,15 +3,16 @@
SINGLE_BATTLE_TEST("Poison deals 1/8th damage per turn") SINGLE_BATTLE_TEST("Poison deals 1/8th damage per turn")
{ {
u32 j;
GIVEN { GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_POISON); } PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_POISON); }
OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET);
} WHEN { } WHEN {
for (i = 0; i < 4; i++) for (j = 0; j < 4; j++)
TURN {} TURN {}
} SCENE { } SCENE {
s32 maxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP); s32 maxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP);
for (i = 0; i < 4; i++) for (j = 0; j < 4; j++)
HP_BAR(player, damage: maxHP / 8); HP_BAR(player, damage: maxHP / 8);
} }
} }

View File

@ -3,7 +3,7 @@
SINGLE_BATTLE_TEST("Sleep prevents the battler from using a move") SINGLE_BATTLE_TEST("Sleep prevents the battler from using a move")
{ {
u32 turns; u32 turns, j;
PARAMETRIZE { turns = 1; } PARAMETRIZE { turns = 1; }
PARAMETRIZE { turns = 2; } PARAMETRIZE { turns = 2; }
PARAMETRIZE { turns = 3; } PARAMETRIZE { turns = 3; }
@ -11,10 +11,10 @@ SINGLE_BATTLE_TEST("Sleep prevents the battler from using a move")
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_SLEEP_TURN(turns)); } PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_SLEEP_TURN(turns)); }
OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET);
} WHEN { } WHEN {
for (i = 0; i < turns; i++) for (j = 0; j < turns; j++)
TURN { MOVE(player, MOVE_CELEBRATE); } TURN { MOVE(player, MOVE_CELEBRATE); }
} SCENE { } SCENE {
for (i = 0; i < turns - 1; i++) for (j = 0; j < turns - 1; j++)
MESSAGE("Wobbuffet is fast asleep."); MESSAGE("Wobbuffet is fast asleep.");
MESSAGE("Wobbuffet woke up!"); MESSAGE("Wobbuffet woke up!");
STATUS_ICON(player, none: TRUE); STATUS_ICON(player, none: TRUE);

View File

@ -88,7 +88,7 @@ static u32 AssignCostToRunner(void)
u32 minCostProcess; u32 minCostProcess;
if (gTestRunnerState.test->runner == &gAssumptionsRunner) if (gTestRunnerState.test->runner == &gAssumptionsRunner)
return 0; return gTestRunnerI;
minCostProcess = MinCostProcess(); minCostProcess = MinCostProcess();