Random Battles: Add basic unit test framework

This will save me a lot of time typing in `/eval`s on localhost to test, and also hopefully catch regressions!
This commit is contained in:
Annika 2021-03-18 18:17:25 -07:00
parent 8a587b1746
commit ffd0092bfb
4 changed files with 83 additions and 1 deletions

View File

@ -1,5 +1,5 @@
{
"spec": ["test/main.js", "test/lib/**/*.js", "test/server/**/*.js", "test/sim/**/*.js", "test/tools/**/*.js"],
"spec": ["test/main.js", "test/lib/**/*.js", "test/server/**/*.js", "test/sim/**/*.js", "test/tools/**/*.js", "test/random-battles/**/*.js"],
"grep": "^((?!\\(slow\\)).)*$",
"reporter": "dot",
"ui": "bdd",

View File

@ -17,3 +17,4 @@ server/chat-plugins/scavenger*.ts @xfix @sparkychildcharlie
server/chat-plugins/the-studio.ts @KrisXV
server/chat-plugins/trivia.ts @AnnikaCodes
server/modlog.ts @monsanto
test/random-battles/* @AnnikaCodes

View File

@ -0,0 +1,37 @@
/**
* Tests for Gen 8 randomized formats
*/
'use strict';
const {testSet} = require('./tools');
const assert = require('../assert');
describe('[Gen 8] Random Battle', () => {
const options = {format: 'gen8randombattle'};
it('should not generate Golisopod without Bug STAB', () => {
testSet('golisopod', options, set => {
assert(set.moves.some(m => {
const move = Dex.getMove(m);
return move.type === 'Bug' && move.category !== 'Status';
}), `Golisopod should get Bug STAB (got ${set.moves})`);
});
});
});
describe('[Gen 8] Random Doubles Battle', () => {
const options = {format: 'gen8randomdoublesbattle'};
it('should never generate Melmetal without Body Press', () => {
testSet('melmetal', options, set => {
assert(set.moves.includes('bodypress'), `Melmetal should get Body Press (got ${set.moves})`);
});
});
});
describe('[Gen 8] Random Battle (No Dmax)', () => {
// No tests here yet!
// This format is extremely new; this will be filled in later when I have to fix No Dmax bugs.
// const options = {format: 'gen8randombattlenodmax', isDynamax: true};
});

View File

@ -0,0 +1,44 @@
/**
* Tools for testing Random Battles.
*
* @author Annika
*/
'use strict';
/**
* Unit test helper for Pokemon sets
*
* @param {ID} pokemon the ID of the Pokemon whose set is to be tested
* @param {{format?: string, rounds?: number, isDoubles?: boolean, isLead?: boolean, isDynamax?: boolean}} options
* @param {(set: RandomTeamsTypes.RandomSet) => void} test a function called on each set
*/
function testSet(pokemon, options, test) {
const generator = Dex.getTeamGenerator(options.format);
const rounds = options.rounds || 1000;
const isDoubles = options.isDoubles || (options.format && options.format.includes('doubles'));
const isDynamax = options.isDynamax || !(options.format && options.format.includes('nodmax'));
for (let i = 0; i < rounds; i++) {
const set = generator.randomSet(pokemon, {}, options.isLead, isDoubles, isDynamax);
test(set);
}
}
/**
* Unit test helper for Pokemon teams
*
* @param {{format?: string, rounds?: number}} options
* @param {(team: RandomTeamsTypes.RandomSet[]) => void} test a function called on each team
*/
function testTeam(options, test) {
const generator = Dex.getTeamGenerator(options.format);
const rounds = options.rounds || 1000;
for (let i = 0; i < rounds; i++) {
const team = generator.randomTeam();
test(team);
}
}
exports.testSet = testSet;
exports.testTeam = testTeam;