Skip to content

Commit

Permalink
JSON result: add $schema
Browse files Browse the repository at this point in the history
fixes #43

Signed-off-by: Jan Kowalleck <[email protected]>
  • Loading branch information
jkowalleck committed Dec 20, 2021
1 parent 9fe9d47 commit 28b8510
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 5 deletions.
6 changes: 6 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.

## unreleased

* Added
* Resulting JSON files hold the correct `$schema`. ([#43] via [#42])

[#43]: https://github.com/CycloneDX/cyclonedx-php-library/issues/43
[#42]: https://github.com/CycloneDX/cyclonedx-php-library/pull/42

## 1.3.1 - 2021-12-03

* Fixed
Expand Down
6 changes: 6 additions & 0 deletions res/bom-1.2-strict.SNAPSHOT.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@
],
"additionalProperties": false,
"properties": {
"$schema": {
"type": "string",
"enum": [
"http://cyclonedx.org/schema/bom-1.2a.schema.json"
]
},
"bomFormat": {
"$id": "#/properties/bomFormat",
"type": "string",
Expand Down
6 changes: 6 additions & 0 deletions res/bom-1.3-strict.SNAPSHOT.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@
],
"additionalProperties": false,
"properties": {
"$schema": {
"type": "string",
"enum": [
"http://cyclonedx.org/schema/bom-1.3.schema.json"
]
},
"bomFormat": {
"$id": "#/properties/bomFormat",
"type": "string",
Expand Down
25 changes: 24 additions & 1 deletion src/Core/Serialize/JsonSerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
namespace CycloneDX\Core\Serialize;

use CycloneDX\Core\Models\Bom;
use CycloneDX\Core\Spec\Version;
use DomainException;

/**
Expand All @@ -39,16 +40,38 @@ class JsonSerializer extends BaseSerializer
| \JSON_UNESCAPED_SLASHES // urls become shorter
| \JSON_PRETTY_PRINT;

/**
* JSON schema `$id` that is applied.
*
* @var string[]|null[]
* @psalm-var array<Version::V_*, ?string>
*/
private const SCHEMA = [
Version::V_1_1 => null, // unsupported version
Version::V_1_2 => 'http://cyclonedx.org/schema/bom-1.2a.schema.json',
Version::V_1_3 => 'http://cyclonedx.org/schema/bom-1.3.schema.json',
];

private function getSchemaBase(): array
{
$schema = self::SCHEMA[$this->getSpec()->getVersion()] ?? null;

return null === $schema
? [] // @codeCoverageIgnore
: ['$schema' => $schema];
}

/**
* @throws DomainException if something was not supported
*/
protected function normalize(Bom $bom): string
{
$schemaBase = $this->getSchemaBase();
$data = (new JSON\NormalizerFactory($this->getSpec()))
->makeForBom()
->normalize($bom);

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

return $json;
Expand Down
39 changes: 38 additions & 1 deletion tests/Core/Serialize/JsonSerializerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class JsonSerializerTest extends TestCase
* @uses \CycloneDX\Core\Serialize\JSON\Normalizers\ComponentNormalizer
* @uses \CycloneDX\Core\Serialize\BomRefDiscriminator
*/
public function testSerialize(): void
public function testSerialize12(): void
{
$spec = $this->createConfiguredMock(
SpecInterface::class,
Expand All @@ -60,6 +60,7 @@ public function testSerialize(): void
self::assertJsonStringEqualsJsonString(
<<<'JSON'
{
"$schema": "http://cyclonedx.org/schema/bom-1.2a.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.2",
"version": 0,
Expand All @@ -69,4 +70,40 @@ public function testSerialize(): void
$actual
);
}

/**
* @uses \CycloneDX\Core\Serialize\JSON\AbstractNormalizer
* @uses \CycloneDX\Core\Serialize\JSON\NormalizerFactory
* @uses \CycloneDX\Core\Serialize\JSON\Normalizers\BomNormalizer
* @uses \CycloneDX\Core\Serialize\JSON\Normalizers\ComponentRepositoryNormalizer
* @uses \CycloneDX\Core\Serialize\JSON\Normalizers\ComponentNormalizer
* @uses \CycloneDX\Core\Serialize\BomRefDiscriminator
*/
public function testSerialize13(): void
{
$spec = $this->createConfiguredMock(
SpecInterface::class,
[
'getVersion' => '1.3',
'isSupportedFormat' => true,
]
);
$serializer = new JsonSerializer($spec);
$bom = $this->createStub(Bom::class);

$actual = $serializer->serialize($bom);

self::assertJsonStringEqualsJsonString(
<<<'JSON'
{
"$schema": "http://cyclonedx.org/schema/bom-1.3.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.3",
"version": 0,
"components": []
}
JSON,
$actual
);
}
}
68 changes: 67 additions & 1 deletion tests/Core/Serialize/XmlSerializerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,40 @@ class XmlSerializerTest extends TestCase
* @uses \CycloneDX\Core\Serialize\DOM\Normalizers\ComponentNormalizer
* @uses \CycloneDX\Core\Serialize\BomRefDiscriminator
*/
public function testSerialize(): void
public function testSerialize11(): void
{
$spec = $this->createConfiguredMock(
SpecInterface::class,
[
'getVersion' => '1.1',
'isSupportedFormat' => true,
]
);
$serializer = new XmlSerializer($spec);
$bom = $this->createStub(Bom::class);

$actual = $serializer->serialize($bom);

self::assertXmlStringEqualsXmlString(
<<<'XML'
<?xml version="1.0" encoding="UTF-8"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.1" version="0">
<components/>
</bom>
XML,
$actual
);
}

/**
* @uses \CycloneDX\Core\Serialize\DOM\AbstractNormalizer
* @uses \CycloneDX\Core\Serialize\DOM\NormalizerFactory
* @uses \CycloneDX\Core\Serialize\DOM\Normalizers\BomNormalizer
* @uses \CycloneDX\Core\Serialize\DOM\Normalizers\ComponentRepositoryNormalizer
* @uses \CycloneDX\Core\Serialize\DOM\Normalizers\ComponentNormalizer
* @uses \CycloneDX\Core\Serialize\BomRefDiscriminator
*/
public function testSerialize12(): void
{
$spec = $this->createConfiguredMock(
SpecInterface::class,
Expand All @@ -67,4 +100,37 @@ public function testSerialize(): void
$actual
);
}

/**
* @uses \CycloneDX\Core\Serialize\DOM\AbstractNormalizer
* @uses \CycloneDX\Core\Serialize\DOM\NormalizerFactory
* @uses \CycloneDX\Core\Serialize\DOM\Normalizers\BomNormalizer
* @uses \CycloneDX\Core\Serialize\DOM\Normalizers\ComponentRepositoryNormalizer
* @uses \CycloneDX\Core\Serialize\DOM\Normalizers\ComponentNormalizer
* @uses \CycloneDX\Core\Serialize\BomRefDiscriminator
*/
public function testSerialize13(): void
{
$spec = $this->createConfiguredMock(
SpecInterface::class,
[
'getVersion' => '1.3',
'isSupportedFormat' => true,
]
);
$serializer = new XmlSerializer($spec);
$bom = $this->createStub(Bom::class);

$actual = $serializer->serialize($bom);

self::assertXmlStringEqualsXmlString(
<<<'XML'
<?xml version="1.0" encoding="UTF-8"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.3" version="0">
<components/>
</bom>
XML,
$actual
);
}
}
6 changes: 4 additions & 2 deletions tests/Core/SerializeToJsonTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,9 @@ public function testSchema12(Bom $bom): void
$validator = new JsonStrictValidator($spec);

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

$validationErrors = $validator->validateString($json);
self::assertNull($validationErrors);
}

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

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

$validationErrors = $validator->validateString($json);
self::assertNull($validationErrors);
}

Expand Down

0 comments on commit 28b8510

Please sign in to comment.