-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathvalidator.js
More file actions
118 lines (102 loc) · 3.51 KB
/
validator.js
File metadata and controls
118 lines (102 loc) · 3.51 KB
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
'use strict';
/**
* A tool to validate systems.json.
*/
import { readFile } from 'fs/promises';
import { JSV } from 'JSV'
console.log('Validating systems.json...');
const schema = JSON.parse(await readFile(new URL('./schema.json', import.meta.url)));
const json = JSON.parse(await readFile(new URL('./systems.json', import.meta.url)));
doValidate('JSON Schema', validateAgainstSchema);
doValidate('MeasurementSystems Inherits', validateMeasurementSystemInherits);
doValidate('Systems BaseUnit', validateBaseUnits);
doValidate('Systems Derived', validateDerived);
doValidate('Systems UnitMeasurementSystems', validateUnitSystems);
console.log('Validating systems.json succeeded!');
// HELPER FUNCTIONS
function doValidate(sectionName, func) {
var errors = func();
if (errors.length === 0) {
console.log(' - ' + sectionName + ': succeeded');
} else {
console.log(' - ' + sectionName + ': failed');
printErrors(errors);
process.exit(1);
}
}
function printErrors(errors) {
if (errors.length > 5) {
console.log("Showing first 5 errors only.");
}
console.log(errors.slice(0, 5));
console.log("Error Count: " + errors.length);
}
// VALIDATION
function validateAgainstSchema() {
var env = JSV.createEnvironment();
var report = env.validate(json, schema);
return report.errors;
}
function validateMeasurementSystemInherits() {
var errors = [];
var systemKeys = Object.keys(json.systems);
for (const [key, system] of Object.entries(json.systems)) {
if (system.inherits) {
if (!systemKeys.includes(system.inherits)) {
errors.push('system \'' + key + '\' inherits from unknown system \'' + system.inherits + '\'');
}
if (key === system.inherits) {
errors.push('system \'' + key + '\' should not inherit from itself');
}
}
};
return errors;
}
function validateBaseUnits() {
var errors = [];
for (const [key, dimension] of Object.entries(json.dimensions)) {
var unitKeys = Object.keys(dimension.units);
if (dimension.inheritedUnits) {
unitKeys = [...unitKeys, ...Object.keys(json.dimensions[dimension.inheritedUnits].units)];
}
if (!unitKeys.includes(dimension.baseUnit)) {
errors.push('dimension \'' + key + '\' has a baseUnit \'' + dimension.baseUnit + '\' that does not match any know unit');
}
}
return errors;
}
function validateUnitSystems() {
var errors = [];
var systemKeys = Object.keys(json.systems);
for (const [dimKey, dimension] of Object.entries(json.dimensions)) {
for (const [unitKey, unit] of Object.entries(dimension.units)) {
for (const system of Object.values(unit.systems)) {
if (!systemKeys.includes(system)) {
errors.push('unknown system \'' + system + '\' in ' + dimKey + ':' + unitKey);
}
}
}
}
return errors;
}
function validateDerived() {
var errors = [];
// Can only be derived from base dimensions
var baseDimensionKeys = Object.entries(json.dimensions)
.filter(([, value]) => !value.derived)
.map(([key]) => key);
for (const [dimensionKey, dimension] of Object.entries(json.dimensions)) {
if (dimension.derived && dimension.derived.length > 0) {
var parts = dimension.derived.split(/([/*|/])/);
parts.forEach((part, position) => {
if (position % 2 === 1 && !(part === '*' || part === '/')) {
errors.push('unknown operation \'' + part + '\' used in dimension.derived for ' + dimensionKey);
}
if (position % 2 === 0 && !(baseDimensionKeys.includes(part) || part === '1')) {
errors.push('unknown base dimension or placeholder \'' + part + '\' used in dimension.derived for ' + dimensionKey);
}
});
}
}
return errors;
}