Skip to content

Commit df107ea

Browse files
Merge pull request #237 from jkowalleck/schea-tests-in-php
schema validate VS test data - php
2 parents 21314a9 + f249d85 commit df107ea

3 files changed

Lines changed: 219 additions & 3 deletions

File tree

tools/src/test/php/composer.json

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,42 @@
11
{
22
"minimum-stability": "stable",
33
"require": {
4-
"php": "^7.4 || ^8.0",
4+
"php": "^8.1",
5+
"ext-dom": "*",
56
"ext-json": "*",
7+
"ext-libxml": "*",
68
"opis/json-schema": "2.3"
79
},
810
"require-dev": {
911
"roave/security-advisories": "dev-latest"
1012
},
1113
"scripts": {
1214
"test": [
13-
"@test:json-schema-lint"
15+
"@test:json-schema-lint",
16+
"@test:json-schema-functional",
17+
"@test:xml-schema-functional"
1418
],
15-
"test:json-schema-lint": "@php -f json-schema-lint-tests.php --"
19+
"test:json-schema-lint": "@php -f json-schema-lint-tests.php --",
20+
"test:json-schema-functional": [
21+
"@test:json-schema-functional:1.4",
22+
"@test:json-schema-functional:1.3",
23+
"@test:json-schema-functional:1.2"
24+
],
25+
"test:json-schema-functional:1.4": "@php -f json-schema-functional-tests.php -- -v 1.4 --",
26+
"test:json-schema-functional:1.3": "@php -f json-schema-functional-tests.php -- -v 1.3 --",
27+
"test:json-schema-functional:1.2": "@php -f json-schema-functional-tests.php -- -v 1.2 --",
28+
"test:xml-schema-functional": [
29+
"@test:xml-schema-functional:1.4",
30+
"@test:xml-schema-functional:1.3",
31+
"@test:xml-schema-functional:1.2",
32+
"@test:xml-schema-functional:1.1",
33+
"@test:xml-schema-functional:1.0"
34+
],
35+
"test:xml-schema-functional:1.4": "@php -f xml-schema-functional-tests.php -- -v 1.4 --",
36+
"test:xml-schema-functional:1.3": "@php -f xml-schema-functional-tests.php -- -v 1.3 --",
37+
"test:xml-schema-functional:1.2": "@php -f xml-schema-functional-tests.php -- -v 1.2 --",
38+
"test:xml-schema-functional:1.1": "@php -f xml-schema-functional-tests.php -- -v 1.1 --",
39+
"test:xml-schema-functional:1.0": "@php -f xml-schema-functional-tests.php -- -v 1.0 --"
1640
},
1741
"scripts-descriptions": {
1842
"test": "run all tests",
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php declare(strict_types=1);
2+
3+
/**
4+
* validate all test data for a given version of CycloneDX.
5+
* call the script via `php -f <this-file> -- -v <CDX-version>`
6+
*/
7+
8+
use Opis\JsonSchema;
9+
10+
require_once __DIR__ . '/vendor/autoload.php';
11+
12+
// region config
13+
14+
define('TESTSCHEMA_VERSION', getopt('v:')['v']);
15+
define('SCHEMA_DIR', realpath(__DIR__ . '/../../../../schema'));
16+
define('SCHEMA_FILE', SCHEMA_DIR . '/bom-' . TESTSCHEMA_VERSION . '.schema.json');
17+
define('TESTDATA_DIR', realpath(__DIR__ . '/../resources/' . TESTSCHEMA_VERSION));
18+
19+
if (empty(TESTSCHEMA_VERSION)) {
20+
throw new Exception('missing TESTSCHEMA_VERSION. expected via opt "-v"');
21+
}
22+
fwrite(STDOUT, 'DEBUG | TESTSCHEMA_VERSION = ' . TESTSCHEMA_VERSION . PHP_EOL);
23+
24+
if (!is_file(SCHEMA_FILE)) {
25+
throw new Exception('missing SCHEMA_FILE: ' . SCHEMA_FILE);
26+
}
27+
fwrite(STDOUT, 'DEBUG | SCHEMA_FILE = ' . SCHEMA_FILE . PHP_EOL);
28+
29+
if (!is_dir(TESTDATA_DIR)) {
30+
throw new Exception('missing TESTDATA_DIR: ' . TESTDATA_DIR);
31+
}
32+
fwrite(STDOUT, 'DEBUG | TESTDATA_DIR = ' . TESTDATA_DIR . PHP_EOL);
33+
34+
// endregion config
35+
36+
// region validator
37+
38+
$schemaId = uniqid('validate:cdx-test?f=' . SCHEMA_FILE . '&r=', true);
39+
$resolver = new JsonSchema\Resolvers\SchemaResolver();
40+
$resolver->registerFile($schemaId, SCHEMA_FILE);
41+
$resolver->registerPrefix('http://cyclonedx.org/schema/', SCHEMA_DIR);
42+
$validator = new JsonSchema\Validator();
43+
$validator->setResolver($resolver);
44+
$errorFormatter = new JsonSchema\Errors\ErrorFormatter();
45+
46+
/**
47+
* @param string $file file path to validate
48+
*/
49+
function validateFile(string $file): ?JsonSchema\Errors\ValidationError
50+
{
51+
global $validator, $schemaId;
52+
return $validator->validate(
53+
json_decode(file_get_contents($file), false, 1024, \JSON_THROW_ON_ERROR),
54+
$schemaId
55+
)->error();
56+
}
57+
58+
// endregion validator
59+
60+
$errCnt = 0;
61+
62+
foreach (glob(TESTDATA_DIR . '/valid-*.json') as $file) {
63+
fwrite(STDOUT, PHP_EOL . "test $file ..." . PHP_EOL);
64+
$validationError = validateFile($file);
65+
if ($validationError === null) {
66+
fwrite(STDOUT, 'OK.' . PHP_EOL);
67+
} else {
68+
++$errCnt;
69+
fwrite(STDERR, "ERROR: Unexpected validation error for file: $file" . PHP_EOL);
70+
fwrite(STDERR, json_encode(
71+
$errorFormatter->format($validationError),
72+
JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES
73+
) . PHP_EOL);
74+
}
75+
unset($validationError);
76+
}
77+
78+
foreach (glob(TESTDATA_DIR . '/invalid-*.json') as $file) {
79+
fwrite(STDOUT, PHP_EOL . "test $file ..." . PHP_EOL);
80+
$validationError = validateFile($file);
81+
if ($validationError === null) {
82+
++$errCnt;
83+
fwrite(STDERR, "ERROR: Missing expected validation error for file: $file" . PHP_EOL);
84+
} else {
85+
fwrite(STDOUT, 'OK.' . PHP_EOL);
86+
}
87+
unset($validationError);
88+
}
89+
90+
91+
// Exit statuses should be in the range 0 to 254, the exit status 255 is reserved by PHP and shall not be used.
92+
// The status 0 is used to terminate the program successfully.
93+
exit(min($errCnt, 254));
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<?php declare(strict_types=1);
2+
3+
/**
4+
* validate all test data for a given version of CycloneDX.
5+
* call the script via `php -f <this-file> -- -v <CDX-version>`
6+
*/
7+
8+
use Opis\JsonSchema;
9+
10+
require_once __DIR__ . '/vendor/autoload.php';
11+
12+
// region config
13+
14+
define('TESTSCHEMA_VERSION', getopt('v:')['v']);
15+
define('SCHEMA_DIR', realpath(__DIR__ . '/../../../../schema'));
16+
define('SCHEMA_FILE', SCHEMA_DIR . '/bom-' . TESTSCHEMA_VERSION . '.xsd');
17+
define('TESTDATA_DIR', realpath(__DIR__ . '/../resources/' . TESTSCHEMA_VERSION));
18+
19+
if (empty(TESTSCHEMA_VERSION)) {
20+
throw new Exception('missing TESTSCHEMA_VERSION. expected via opt "-v"');
21+
}
22+
fwrite(STDOUT, 'DEBUG | TESTSCHEMA_VERSION = ' . TESTSCHEMA_VERSION . PHP_EOL);
23+
24+
if (!is_file(SCHEMA_FILE)) {
25+
throw new Exception('missing SCHEMA_FILE: ' . SCHEMA_FILE);
26+
}
27+
fwrite(STDOUT, 'DEBUG | SCHEMA_FILE = ' . SCHEMA_FILE . PHP_EOL);
28+
29+
if (!is_dir(TESTDATA_DIR)) {
30+
throw new Exception('missing TESTDATA_DIR: ' . TESTDATA_DIR);
31+
}
32+
fwrite(STDOUT, 'DEBUG | TESTDATA_DIR = ' . TESTDATA_DIR . PHP_EOL);
33+
34+
// endregion config
35+
36+
// region validator
37+
38+
$xmlOptions = \LIBXML_NONET;
39+
if (\defined('LIBXML_COMPACT')) {
40+
$xmlOptions |= \LIBXML_COMPACT;
41+
}
42+
if (\defined('LIBXML_PARSEHUGE')) {
43+
$xmlOptions |= \LIBXML_PARSEHUGE;
44+
}
45+
46+
/**
47+
* @param string $file file path to validate
48+
*/
49+
function validateFile(string $file): ?LibXMLError
50+
{
51+
global $xmlOptions;
52+
53+
libxml_use_internal_errors(true);
54+
libxml_clear_errors();
55+
56+
$doc = new DOMDocument();
57+
if (!$doc->loadXML(file_get_contents($file), $xmlOptions)) {
58+
throw new Exception("failed loading file: $file" . PHP_EOL . libxml_get_last_error()->message);
59+
}
60+
61+
$valid = $doc->schemaValidate(SCHEMA_FILE);
62+
return $valid
63+
? null
64+
: libxml_get_last_error();
65+
}
66+
67+
// endregion validator
68+
69+
$errCnt = 0;
70+
71+
foreach (glob(TESTDATA_DIR . '/valid-*.xml') as $file) {
72+
fwrite(STDOUT, PHP_EOL . "test $file ..." . PHP_EOL);
73+
$validationError = validateFile($file);
74+
if ($validationError === null) {
75+
fwrite(STDOUT, 'OK.' . PHP_EOL);
76+
} else {
77+
++$errCnt;
78+
fwrite(STDERR, "ERROR: Unexpected validation error for file: $file" . PHP_EOL);
79+
fwrite(STDERR, print_r($validationError, true) . PHP_EOL);
80+
}
81+
unset($validationError);
82+
}
83+
84+
foreach (glob(TESTDATA_DIR . '/invalid-*.xml') as $file) {
85+
fwrite(STDOUT, PHP_EOL . "test $file ..." . PHP_EOL);
86+
$validationError = validateFile($file);
87+
if ($validationError === null) {
88+
++$errCnt;
89+
fwrite(STDERR, "ERROR: Missing expected validation error for file: $file" . PHP_EOL);
90+
} else {
91+
fwrite(STDOUT, 'OK.' . PHP_EOL);
92+
}
93+
unset($validationError);
94+
}
95+
96+
97+
// Exit statuses should be in the range 0 to 254, the exit status 255 is reserved by PHP and shall not be used.
98+
// The status 0 is used to terminate the program successfully.
99+
exit(min($errCnt, 254));

0 commit comments

Comments
 (0)