mirror of
https://github.com/Kornstalx/5etools-mirror-2.github.io.git
synced 2025-10-28 20:45:35 -05:00
166 lines
5.8 KiB
JavaScript
166 lines
5.8 KiB
JavaScript
import fs from "fs";
|
|
import * as ut from "../node/util.js";
|
|
import "../js/parser.js";
|
|
import "../js/utils.js";
|
|
import "../js/render.js";
|
|
import "../js/render-dice.js";
|
|
|
|
class TestFoundry {
|
|
static async pLoadData (originalFilename, originalPath) {
|
|
switch (originalFilename) {
|
|
case "races.json": {
|
|
ut.patchLoadJson();
|
|
const out = await DataUtil.race.loadJSON({isAddBaseRaces: true});
|
|
ut.unpatchLoadJson();
|
|
return out;
|
|
}
|
|
|
|
default: return ut.readJson(originalPath);
|
|
}
|
|
}
|
|
|
|
static testClasses ({errors}) {
|
|
const classIndex = ut.readJson("./data/class/index.json");
|
|
const classFiles = Object.values(classIndex)
|
|
.map(file => ut.readJson(`./data/class/${file}`));
|
|
|
|
const uidsClass = new Set();
|
|
const uidsClassFeature = new Set();
|
|
const uidsSubclassFeature = new Set();
|
|
|
|
classFiles.forEach(data => {
|
|
(data.class || []).forEach(cls => {
|
|
const uid = UrlUtil.URL_TO_HASH_BUILDER[UrlUtil.PG_CLASSES](cls);
|
|
uidsClass.add(uid);
|
|
});
|
|
|
|
(data.classFeature || []).forEach(cf => {
|
|
const uid = UrlUtil.URL_TO_HASH_BUILDER["classFeature"](cf);
|
|
uidsClassFeature.add(uid);
|
|
});
|
|
|
|
(data.subclassFeature || []).forEach(scf => {
|
|
const uid = UrlUtil.URL_TO_HASH_BUILDER["subclassFeature"](scf);
|
|
uidsSubclassFeature.add(uid);
|
|
});
|
|
});
|
|
|
|
const foundryData = ut.readJson("./data/class/foundry.json");
|
|
(foundryData.class || []).forEach(cls => {
|
|
const uid = UrlUtil.URL_TO_HASH_BUILDER[UrlUtil.PG_CLASSES](cls);
|
|
if (!uidsClass.has(uid)) errors.push(`\tClass "${uid}" not found!`);
|
|
});
|
|
(foundryData.classFeature || []).forEach(fcf => {
|
|
const uid = UrlUtil.URL_TO_HASH_BUILDER["classFeature"](fcf);
|
|
if (!uidsClassFeature.has(uid)) errors.push(`\tClass feature "${uid}" not found!`);
|
|
});
|
|
(foundryData.subclassFeature || []).forEach(fscf => {
|
|
const uid = UrlUtil.URL_TO_HASH_BUILDER["subclassFeature"](fscf);
|
|
if (!uidsSubclassFeature.has(uid)) errors.push(`\tSubclass feature "${uid}" not found!`);
|
|
});
|
|
}
|
|
|
|
static async pTestDir ({errors, dir}) {
|
|
const FOUNDRY_FILE = "foundry.json";
|
|
|
|
const dirList = fs.readdirSync(`./data/${dir}`)
|
|
.filter(it => !it.startsWith("fluff-") && it !== "sources.json" && it !== "index.json");
|
|
|
|
if (!dirList.includes(FOUNDRY_FILE)) throw new Error(`No "${FOUNDRY_FILE}" file found in dir "${dir}"!`);
|
|
|
|
const foundryPath = `./data/${dir}/${FOUNDRY_FILE}`;
|
|
const foundryData = ut.readJson(foundryPath);
|
|
const originalDatas = await dirList
|
|
.filter(it => it !== FOUNDRY_FILE)
|
|
.pSerialAwaitMap(it => this.pLoadData(it, `./data/${dir}/${it}`));
|
|
|
|
await this.pTestFile({errors, foundryData, foundryPath, originalDatas});
|
|
}
|
|
|
|
static async pTestRoot ({errors}) {
|
|
const dirList = fs.readdirSync(`./data/`);
|
|
const foundryFiles = dirList.filter(it => it.startsWith("foundry-") && it.endsWith(".json"));
|
|
|
|
for (const foundryFile of foundryFiles) {
|
|
const foundryPath = `./data/${foundryFile}`;
|
|
const foundryData = ut.readJson(foundryPath);
|
|
const originalFile = foundryFile.replace(/^foundry-/i, "");
|
|
const originalData = await this.pLoadData(originalFile, `./data/${originalFile}`);
|
|
|
|
await this.pTestFile({errors, foundryData, foundryPath, originalDatas: [originalData]});
|
|
}
|
|
}
|
|
|
|
static testSpecialRaceFeatures ({foundryData, originalDatas, errors}) {
|
|
const uidsRaceFeature = new Set();
|
|
|
|
const HASH_BUILDER = it => UrlUtil.encodeForHash([it.name, it.source, it.raceName, it.raceSource]);
|
|
|
|
originalDatas.forEach(originalData => {
|
|
originalData.race.forEach(race => {
|
|
DataUtil.generic.getVersions(race).forEach(ver => this._testSpecialRaceFeatures_addRace({HASH_BUILDER, uidsRaceFeature, race: ver}));
|
|
this._testSpecialRaceFeatures_addRace({HASH_BUILDER, uidsRaceFeature, race});
|
|
});
|
|
});
|
|
|
|
foundryData.raceFeature.forEach(raceFeature => {
|
|
const uid = HASH_BUILDER(raceFeature);
|
|
if (!uidsRaceFeature.has(uid)) errors.push(`\tRace feature "${uid}" not found!`);
|
|
});
|
|
}
|
|
|
|
static _testSpecialRaceFeatures_addRace ({HASH_BUILDER, uidsRaceFeature, race}) {
|
|
(race.entries || []).forEach(ent => {
|
|
const uid = HASH_BUILDER({source: race.source, ...ent, raceName: race.name, raceSource: race.source});
|
|
uidsRaceFeature.add(uid);
|
|
});
|
|
}
|
|
|
|
static async pTestSpecialMagicItemVariants ({foundryData, originalDatas, errors}) {
|
|
const variants = await this.pLoadData("magicvariants.json", `./data/magicvariants.json`);
|
|
const prop = "magicvariant";
|
|
this.doCompareData({prop, foundryData, originalDatas: [variants], errors});
|
|
}
|
|
|
|
static doCompareData ({prop, foundryData, originalDatas, errors}) {
|
|
foundryData[prop].forEach(it => {
|
|
const match = originalDatas.first(variants => variants[prop].find(og => og.name === it.name && (og?.inherits?.source ?? og.source) === it.source));
|
|
if (!match) errors.push(`\t"${prop}" ${it.name} (${it.source}) not found!`);
|
|
});
|
|
}
|
|
|
|
static async pTestFile ({foundryPath, foundryData, originalDatas, errors}) {
|
|
Object.entries(foundryData)
|
|
.forEach(([prop, arr]) => {
|
|
if (SPECIAL_PROPS[prop]) return SPECIAL_PROPS[prop]({foundryPath, foundryData, originalDatas, errors});
|
|
|
|
if (!(arr instanceof Array)) return;
|
|
if (originalDatas.every(originalData => !originalData[prop] || !(originalData[prop] instanceof Array))) return console.warn(`\tUntested prop "${prop}" in file ${foundryPath}`);
|
|
|
|
this.doCompareData({prop, foundryData, originalDatas, errors});
|
|
});
|
|
}
|
|
}
|
|
|
|
const SPECIAL_PROPS = {
|
|
"raceFeature": TestFoundry.testSpecialRaceFeatures.bind(TestFoundry),
|
|
"magicvariant": TestFoundry.pTestSpecialMagicItemVariants.bind(TestFoundry),
|
|
};
|
|
|
|
async function main () {
|
|
const errors = [];
|
|
|
|
TestFoundry.testClasses({errors});
|
|
await TestFoundry.pTestDir({dir: "spells", errors});
|
|
await TestFoundry.pTestRoot({errors});
|
|
|
|
if (!errors.length) console.log("##### Foundry Tests Passed #####");
|
|
else {
|
|
console.error("Foundry data errors:");
|
|
errors.forEach(err => console.error(err));
|
|
}
|
|
return !errors.length;
|
|
}
|
|
|
|
export default main();
|