-
Notifications
You must be signed in to change notification settings - Fork 0
/
test-json.js
134 lines (106 loc) · 4.04 KB
/
test-json.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
const fs = require("fs");
require("../js/utils");
const ut = require("../node/util.js");
const Ajv = require("ajv").default;
// Compile the schema
require("../node/compile-schemas.js");
// region Set up validator
const ajv = new Ajv({
allowUnionTypes: true,
});
ajv.addKeyword({
keyword: "version",
validate: false,
});
const DATE_REGEX = /^\d\d\d\d-\d\d-\d\d$/;
ajv.addFormat(
"date",
{
validate: (str) => DATE_REGEX.test(str),
},
);
// endregion
function handleError () {
const out = JSON.stringify(ajv.errors, null, 2);
console.error(out);
console.warn(`Tests failed`);
fs.writeFileSync("../log-test-json.json", out, "utf-8");
return false;
}
// add any implicit data to the JSON
function addImplicits (obj, lastKey) {
if (typeof obj !== "object") return;
if (obj == null) return;
if (obj instanceof Array) obj.forEach(it => addImplicits(it, lastKey));
else {
// "obj.mode" will be set if this is in a "_copy" etc. block
if (lastKey === "spellcasting" && !obj.mode) obj.type = obj.type || "spellcasting";
Object.entries(obj).forEach(([k, v]) => addImplicits(v, k));
}
}
async function main () {
console.log(`##### Validating JSON against schemata #####`);
// a probably-unnecessary directory shift to ensure the JSON schema internal references line up
const cacheDir = process.cwd();
process.chdir(`${cacheDir}/test/schema`);
const PRELOAD_SINGLE_FILE_SCHEMAS = [
];
const PRELOAD_COMMON_SINGLE_FILE_SCHEMAS = [
];
PRELOAD_SINGLE_FILE_SCHEMAS.forEach(schemaName => {
ajv.addSchema(ut.readJson(schemaName, "utf8"), schemaName);
});
PRELOAD_COMMON_SINGLE_FILE_SCHEMAS.forEach(schemaName => {
const json = ut.readJson(schemaName, "utf8");
ajv.addSchema(json, schemaName);
});
// Get schema files, ignoring directories
const schemaFiles = fs.readdirSync(`${cacheDir}/test/schema`)
.filter(file => file.endsWith(".json"));
const SCHEMA_BLACKLIST = new Set([...PRELOAD_COMMON_SINGLE_FILE_SCHEMAS, "homebrew.json"]);
for (let i = 0; i < schemaFiles.length; ++i) {
const schemaFile = schemaFiles[i];
if (!SCHEMA_BLACKLIST.has(schemaFile)) {
const dataFile = schemaFile; // data and schema filenames match
console.log(`Testing data/${dataFile}`.padEnd(50), `against schema/${schemaFile}`);
const data = ut.readJson(`${cacheDir}/data/${dataFile}`);
// Avoid re-adding schemas we have already loaded
if (!PRELOAD_SINGLE_FILE_SCHEMAS.includes(schemaFile)) {
const schema = ut.readJson(schemaFile, "utf8");
ajv.addSchema(schema, schemaFile);
}
addImplicits(data);
const valid = ajv.validate(schemaFile, data);
if (!valid) return handleError(valid);
}
}
// Get schema files in directories
const schemaDirectories = fs.readdirSync(`${cacheDir}/test/schema`)
.filter(category => !category.includes("."));
for (let i = 0; i < schemaDirectories.length; ++i) {
const schemaDir = schemaDirectories[i];
console.log(`Testing category ${schemaDir}`);
const schemaFiles = fs.readdirSync(`${cacheDir}/test/schema/${schemaDir}`);
const dataFiles = fs.readdirSync(`${cacheDir}/data/${schemaDir}`);
for (let i = 0; i < dataFiles.length; ++i) {
const dataFile = dataFiles[i];
const relevantSchemaFiles = schemaFiles.filter(schema => dataFile.startsWith(schema.split(".")[0]));
for (let i = 0; i < relevantSchemaFiles.length; ++i) {
const schemaFile = relevantSchemaFiles[i];
const schemaKey = `${schemaDir}/${schemaFile}`;
console.log(`Testing data/${schemaDir}/${dataFile}`.padEnd(50), `against schema/${schemaDir}/${schemaFile}`);
const data = ut.readJson(`${cacheDir}/data/${schemaDir}/${dataFile}`);
const schema = ut.readJson(`${cacheDir}/test/schema/${schemaDir}/${schemaFile}`, "utf8");
// only add the schema if we didn't do so already for this category
if (!ajv.getSchema(schemaKey)) ajv.addSchema(schema, schemaKey);
addImplicits(data);
const valid = ajv.validate(schemaKey, data);
if (!valid) return handleError(valid);
}
}
}
console.log(`All schema tests passed.`);
process.chdir(cacheDir); // restore working directory
return true;
}
module.exports = main();