Skip to content

Commit 28b8510

Browse files
committed
JSON result: add $schema
fixes #43 Signed-off-by: Jan Kowalleck <[email protected]>
1 parent 9fe9d47 commit 28b8510

File tree

7 files changed

+151
-5
lines changed

7 files changed

+151
-5
lines changed

HISTORY.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
44

55
## unreleased
66

7+
* Added
8+
* Resulting JSON files hold the correct `$schema`. ([#43] via [#42])
9+
10+
[#43]: https://github.com/CycloneDX/cyclonedx-php-library/issues/43
11+
[#42]: https://github.com/CycloneDX/cyclonedx-php-library/pull/42
12+
713
## 1.3.1 - 2021-12-03
814

915
* Fixed

res/bom-1.2-strict.SNAPSHOT.schema.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
],
1212
"additionalProperties": false,
1313
"properties": {
14+
"$schema": {
15+
"type": "string",
16+
"enum": [
17+
"http://cyclonedx.org/schema/bom-1.2a.schema.json"
18+
]
19+
},
1420
"bomFormat": {
1521
"$id": "#/properties/bomFormat",
1622
"type": "string",

res/bom-1.3-strict.SNAPSHOT.schema.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
],
1212
"additionalProperties": false,
1313
"properties": {
14+
"$schema": {
15+
"type": "string",
16+
"enum": [
17+
"http://cyclonedx.org/schema/bom-1.3.schema.json"
18+
]
19+
},
1420
"bomFormat": {
1521
"$id": "#/properties/bomFormat",
1622
"type": "string",

src/Core/Serialize/JsonSerializer.php

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
namespace CycloneDX\Core\Serialize;
2525

2626
use CycloneDX\Core\Models\Bom;
27+
use CycloneDX\Core\Spec\Version;
2728
use DomainException;
2829

2930
/**
@@ -39,16 +40,38 @@ class JsonSerializer extends BaseSerializer
3940
| \JSON_UNESCAPED_SLASHES // urls become shorter
4041
| \JSON_PRETTY_PRINT;
4142

43+
/**
44+
* JSON schema `$id` that is applied.
45+
*
46+
* @var string[]|null[]
47+
* @psalm-var array<Version::V_*, ?string>
48+
*/
49+
private const SCHEMA = [
50+
Version::V_1_1 => null, // unsupported version
51+
Version::V_1_2 => 'http://cyclonedx.org/schema/bom-1.2a.schema.json',
52+
Version::V_1_3 => 'http://cyclonedx.org/schema/bom-1.3.schema.json',
53+
];
54+
55+
private function getSchemaBase(): array
56+
{
57+
$schema = self::SCHEMA[$this->getSpec()->getVersion()] ?? null;
58+
59+
return null === $schema
60+
? [] // @codeCoverageIgnore
61+
: ['$schema' => $schema];
62+
}
63+
4264
/**
4365
* @throws DomainException if something was not supported
4466
*/
4567
protected function normalize(Bom $bom): string
4668
{
69+
$schemaBase = $this->getSchemaBase();
4770
$data = (new JSON\NormalizerFactory($this->getSpec()))
4871
->makeForBom()
4972
->normalize($bom);
5073

51-
$json = json_encode($data, self::NORMALIZE_OPTIONS);
74+
$json = json_encode(array_merge($schemaBase, $data), self::NORMALIZE_OPTIONS);
5275
\assert(false !== $json); // as option JSON_THROW_ON_ERROR is expected to be set
5376

5477
return $json;

tests/Core/Serialize/JsonSerializerTest.php

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class JsonSerializerTest extends TestCase
4343
* @uses \CycloneDX\Core\Serialize\JSON\Normalizers\ComponentNormalizer
4444
* @uses \CycloneDX\Core\Serialize\BomRefDiscriminator
4545
*/
46-
public function testSerialize(): void
46+
public function testSerialize12(): void
4747
{
4848
$spec = $this->createConfiguredMock(
4949
SpecInterface::class,
@@ -60,6 +60,7 @@ public function testSerialize(): void
6060
self::assertJsonStringEqualsJsonString(
6161
<<<'JSON'
6262
{
63+
"$schema": "http://cyclonedx.org/schema/bom-1.2a.schema.json",
6364
"bomFormat": "CycloneDX",
6465
"specVersion": "1.2",
6566
"version": 0,
@@ -69,4 +70,40 @@ public function testSerialize(): void
6970
$actual
7071
);
7172
}
73+
74+
/**
75+
* @uses \CycloneDX\Core\Serialize\JSON\AbstractNormalizer
76+
* @uses \CycloneDX\Core\Serialize\JSON\NormalizerFactory
77+
* @uses \CycloneDX\Core\Serialize\JSON\Normalizers\BomNormalizer
78+
* @uses \CycloneDX\Core\Serialize\JSON\Normalizers\ComponentRepositoryNormalizer
79+
* @uses \CycloneDX\Core\Serialize\JSON\Normalizers\ComponentNormalizer
80+
* @uses \CycloneDX\Core\Serialize\BomRefDiscriminator
81+
*/
82+
public function testSerialize13(): void
83+
{
84+
$spec = $this->createConfiguredMock(
85+
SpecInterface::class,
86+
[
87+
'getVersion' => '1.3',
88+
'isSupportedFormat' => true,
89+
]
90+
);
91+
$serializer = new JsonSerializer($spec);
92+
$bom = $this->createStub(Bom::class);
93+
94+
$actual = $serializer->serialize($bom);
95+
96+
self::assertJsonStringEqualsJsonString(
97+
<<<'JSON'
98+
{
99+
"$schema": "http://cyclonedx.org/schema/bom-1.3.schema.json",
100+
"bomFormat": "CycloneDX",
101+
"specVersion": "1.3",
102+
"version": 0,
103+
"components": []
104+
}
105+
JSON,
106+
$actual
107+
);
108+
}
72109
}

tests/Core/Serialize/XmlSerializerTest.php

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,40 @@ class XmlSerializerTest extends TestCase
4343
* @uses \CycloneDX\Core\Serialize\DOM\Normalizers\ComponentNormalizer
4444
* @uses \CycloneDX\Core\Serialize\BomRefDiscriminator
4545
*/
46-
public function testSerialize(): void
46+
public function testSerialize11(): void
47+
{
48+
$spec = $this->createConfiguredMock(
49+
SpecInterface::class,
50+
[
51+
'getVersion' => '1.1',
52+
'isSupportedFormat' => true,
53+
]
54+
);
55+
$serializer = new XmlSerializer($spec);
56+
$bom = $this->createStub(Bom::class);
57+
58+
$actual = $serializer->serialize($bom);
59+
60+
self::assertXmlStringEqualsXmlString(
61+
<<<'XML'
62+
<?xml version="1.0" encoding="UTF-8"?>
63+
<bom xmlns="http://cyclonedx.org/schema/bom/1.1" version="0">
64+
<components/>
65+
</bom>
66+
XML,
67+
$actual
68+
);
69+
}
70+
71+
/**
72+
* @uses \CycloneDX\Core\Serialize\DOM\AbstractNormalizer
73+
* @uses \CycloneDX\Core\Serialize\DOM\NormalizerFactory
74+
* @uses \CycloneDX\Core\Serialize\DOM\Normalizers\BomNormalizer
75+
* @uses \CycloneDX\Core\Serialize\DOM\Normalizers\ComponentRepositoryNormalizer
76+
* @uses \CycloneDX\Core\Serialize\DOM\Normalizers\ComponentNormalizer
77+
* @uses \CycloneDX\Core\Serialize\BomRefDiscriminator
78+
*/
79+
public function testSerialize12(): void
4780
{
4881
$spec = $this->createConfiguredMock(
4982
SpecInterface::class,
@@ -67,4 +100,37 @@ public function testSerialize(): void
67100
$actual
68101
);
69102
}
103+
104+
/**
105+
* @uses \CycloneDX\Core\Serialize\DOM\AbstractNormalizer
106+
* @uses \CycloneDX\Core\Serialize\DOM\NormalizerFactory
107+
* @uses \CycloneDX\Core\Serialize\DOM\Normalizers\BomNormalizer
108+
* @uses \CycloneDX\Core\Serialize\DOM\Normalizers\ComponentRepositoryNormalizer
109+
* @uses \CycloneDX\Core\Serialize\DOM\Normalizers\ComponentNormalizer
110+
* @uses \CycloneDX\Core\Serialize\BomRefDiscriminator
111+
*/
112+
public function testSerialize13(): void
113+
{
114+
$spec = $this->createConfiguredMock(
115+
SpecInterface::class,
116+
[
117+
'getVersion' => '1.3',
118+
'isSupportedFormat' => true,
119+
]
120+
);
121+
$serializer = new XmlSerializer($spec);
122+
$bom = $this->createStub(Bom::class);
123+
124+
$actual = $serializer->serialize($bom);
125+
126+
self::assertXmlStringEqualsXmlString(
127+
<<<'XML'
128+
<?xml version="1.0" encoding="UTF-8"?>
129+
<bom xmlns="http://cyclonedx.org/schema/bom/1.3" version="0">
130+
<components/>
131+
</bom>
132+
XML,
133+
$actual
134+
);
135+
}
70136
}

tests/Core/SerializeToJsonTest.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,9 @@ public function testSchema12(Bom $bom): void
7575
$validator = new JsonStrictValidator($spec);
7676

7777
$json = $serializer->serialize($bom);
78-
$validationErrors = $validator->validateString($json);
78+
self::assertJson($json);
7979

80+
$validationErrors = $validator->validateString($json);
8081
self::assertNull($validationErrors);
8182
}
8283

@@ -99,8 +100,9 @@ public function testSchema13(Bom $bom): void
99100
$validator = new JsonStrictValidator($spec);
100101

101102
$json = $serializer->serialize($bom);
102-
$validationErrors = $validator->validateString($json);
103+
self::assertJson($json);
103104

105+
$validationErrors = $validator->validateString($json);
104106
self::assertNull($validationErrors);
105107
}
106108

0 commit comments

Comments
 (0)