Skip to content

Commit 86c9c84

Browse files
committed
validate test data against schema - JS
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
1 parent c1946ef commit 86c9c84

4 files changed

Lines changed: 129 additions & 8 deletions

File tree

tools/src/test/js/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ for validation of a schema.
55

66
## requirements
77

8-
* node >=16
8+
* node >=18.3
99

1010
## setup
1111

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
"use strict";
2+
3+
/**
4+
* validate all test data for a given version of CycloneDX.
5+
* call the script via `node <this-file> -v <CDX-version>`
6+
*/
7+
8+
import {readFile, stat} from 'node:fs/promises'
9+
import {dirname, join} from 'node:path'
10+
import {fileURLToPath} from 'node:url'
11+
import {parseArgs} from 'node:util'
12+
13+
import Ajv from "ajv"
14+
import addFormats from "ajv-formats"
15+
import addFormats2019 from "ajv-formats-draft2019"
16+
import {globSync} from 'glob'
17+
18+
19+
const _thisDir = dirname(fileURLToPath(import.meta.url))
20+
21+
// region config
22+
23+
const testschemaVersion = (parseArgs({options: {v: {type: 'string', short: 'v'}}}).values.v ?? '').trim()
24+
const schemaDir = join(_thisDir, '..', '..', '..', '..', 'schema')
25+
const schemaFile = join(schemaDir, `bom-${testschemaVersion}.schema.json`)
26+
const testdataDir = join(_thisDir, '..', 'resources', testschemaVersion)
27+
28+
if (testschemaVersion.length === 0) {
29+
throw new Error('missing testschemaVersion. expected via argument')
30+
}
31+
console.debug('DEBUG | testschemaVersion = ', testschemaVersion);
32+
33+
if (!await stat(schemaFile).then(s => s.isFile()).catch(() => false)) {
34+
throw new Error(`missing schemaFile: ${schemaFile}`);
35+
}
36+
console.debug('DEBUG | schemaFile = ', schemaFile);
37+
38+
if (!await stat(testdataDir).then(s => s.isDirectory()).catch(() => false)) {
39+
throw new Error(`missing testdataDir: ${testdataDir}`);
40+
}
41+
console.debug('DEBUG | testdataDir = ', testdataDir);
42+
43+
// endregion config
44+
45+
// region validator
46+
47+
const [spdxSchema, jsfSchema, bomSchema] = await Promise.all([
48+
readFile(join(schemaDir, 'spdx.schema.json'), 'utf-8').then(JSON.parse),
49+
readFile(join(schemaDir, 'jsf-0.82.schema.json'), 'utf-8').then(JSON.parse),
50+
readFile(schemaFile, 'utf-8').then(JSON.parse)
51+
])
52+
53+
const ajv = new Ajv({
54+
// not running in strict - this is done in the linter-test already
55+
strict: false,
56+
validateFormats: true,
57+
addUsedSchema: false,
58+
schemas: {
59+
'http://cyclonedx.org/schema/spdx.schema.json': spdxSchema,
60+
'http://cyclonedx.org/schema/jsf-0.82.schema.json': jsfSchema
61+
}
62+
});
63+
addFormats(ajv)
64+
addFormats2019(ajv, {formats: ['idn-email']})
65+
// there is just no working implementation for format "iri-reference"
66+
// see https://github.com/luzlab/ajv-formats-draft2019/issues/22
67+
ajv.addFormat('iri-reference', true)
68+
if (testschemaVersion === '1.2') {
69+
// CycloneDX 1.2 had a wrong undefined format `string`.
70+
// Let's ignore this format only for this special version.
71+
ajv.addFormat('string', true)
72+
}
73+
const _ajvValidate = ajv.compile(bomSchema)
74+
75+
/**
76+
* @param {string} file - file path to validate
77+
* @return {null|object}
78+
*/
79+
async function validateFile(file) {
80+
return _ajvValidate(await readFile(file, 'utf-8').then(JSON.parse))
81+
? null
82+
: _ajvValidate.errors
83+
}
84+
85+
// endregion validator
86+
87+
let errCnt = 0
88+
89+
for (const file of globSync(join(testdataDir, 'valid-*.json'))) {
90+
console.log('\ntest', file, '...');
91+
const validationErrors = await validateFile(file)
92+
if (validationErrors === null) {
93+
console.log('OK.')
94+
} else {
95+
++errCnt;
96+
console.error('ERROR: Unexpected validation error for file:', file);
97+
console.error(validationErrors)
98+
}
99+
}
100+
101+
for (const file of globSync(join(testdataDir, 'invalid-*.json'))) {
102+
console.log('\ntest', file, '...');
103+
const validationErrors = await validateFile(file)
104+
if (validationErrors === null) {
105+
++errCnt;
106+
console.error('ERROR: Missing expected validation error for file:', file);
107+
108+
} else {
109+
console.log('OK.')
110+
}
111+
}
112+
113+
114+
// Exit statuses should be in the range 0 to 254.
115+
// The status 0 is used to terminate the program successfully.
116+
process.exitCode = Math.min(errCnt, 254)

tools/src/test/js/json-schema-lint-tests.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
"use strict";
22

3-
import assert from 'assert'
4-
import {readFile} from 'fs/promises'
5-
import {dirname, basename, join} from 'path'
6-
import {fileURLToPath} from 'url'
3+
import assert from 'node:assert'
4+
import {readFile} from 'node:fs/promises'
5+
import {dirname, basename, join} from 'node:path'
6+
import {fileURLToPath} from 'node:url'
77

88
import Ajv from 'ajv'
99
import addFormats from 'ajv-formats'

tools/src/test/js/package.json

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"private": true,
33
"type": "module",
44
"engines": {
5-
"node": ">=16"
5+
"node": ">=18.3"
66
},
77
"dependencies": {
88
"ajv": "^8.12.0",
@@ -12,10 +12,15 @@
1212
"npm-run-all": "^4.1.5"
1313
},
1414
"devDependencies": {
15-
"@types/node": ">=16"
15+
"@types/node": ">=18.3"
1616
},
1717
"scripts": {
1818
"test": "run-s test:*",
19-
"test:json-schema-lint": "node -- json-schema-lint-tests.js"
19+
"test:json-schema-lint": "node -- json-schema-lint-tests.js",
20+
"test:json-schema-functional": "run-s test:json-schema-functional:*",
21+
"test:json-schema-functional:1.5": "node -- json-schema-functional-tests.js -v 1.5",
22+
"test:json-schema-functional:1.4": "node -- json-schema-functional-tests.js -v 1.4",
23+
"test:json-schema-functional:1.3": "node -- json-schema-functional-tests.js -v 1.3",
24+
"test:json-schema-functional:1.2": "node -- json-schema-functional-tests.js -v 1.2"
2025
}
2126
}

0 commit comments

Comments
 (0)