| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
| file LICENSE.rst or https://cmake.org/licensing for details. */ |
| #include <iostream> |
| #include <string> |
| #include <vector> |
| |
| #include <cm/optional> |
| |
| #include <cm3p/json/reader.h> |
| #include <cm3p/json/value.h> |
| |
| #include "cmSPDXSerializer.h" |
| |
| namespace { |
| |
| std::string const nonOptional(R"================({ |
| "@context": "https://spdx.org/rdf/3.0.1/spdx-context.jsonld", |
| "@graph": [ |
| { |
| "@id": "_:contentIdentifier_0", |
| "contentIdentifierType": "INVALID_CONTENT_IDENTIFIER_TYPE_ID", |
| "contentIdentifierValue": "", |
| "type": "ContentIdentifier" |
| }, |
| { |
| "@id": "_:creationInfo_0", |
| "created": "", |
| "createdBy": [], |
| "type": "CreationInfo" |
| }, |
| { |
| "@id": "_:creationInfo_1", |
| "created": "", |
| "createdBy": [], |
| "type": "CreationInfo" |
| }, |
| { |
| "@id": "_:dictionaryEntry_0", |
| "key": "", |
| "type": "DictionaryEntry" |
| }, |
| { |
| "@id": "_:externalIdentifier_0", |
| "externalIdentifierType": "INVALID_EXTERNAL_IDENTIFIER_TYPE_ID", |
| "identifier": "", |
| "type": "ExternalIdentifier" |
| }, |
| { |
| "@id": "_:externalMap_0", |
| "externalSpdxId": "", |
| "type": "ExternalMap" |
| }, |
| { |
| "@id": "_:externalRef_0", |
| "type": "ExternalRef" |
| }, |
| { |
| "@id": "_:hash_0", |
| "algorithm": "INVALID_HASH_TYPE_ID", |
| "hashValue": "", |
| "type": "Hash" |
| }, |
| { |
| "@id": "_:namespaceMap_0", |
| "namespace": "", |
| "prefix": "", |
| "type": "NamespaceMap" |
| }, |
| { |
| "@id": "_:packageVerificationCode_0", |
| "algorithm": "INVALID_HASH_TYPE_ID", |
| "hashValue": "", |
| "type": "PackageVerificationCode" |
| }, |
| { |
| "@id": "_:positiveIntegerRange_0", |
| "beginIntegerRange": 0, |
| "endIntegerRange": 0, |
| "type": "PositiveIntegerRange" |
| }, |
| { |
| "creationInfo": "_:creationInfo_0", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd0", |
| "type": "Agent" |
| }, |
| { |
| "annotationType": "INVALID_ANNOTATION_TYPE_ID", |
| "creationInfo": "_:creationInfo_0", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd1", |
| "subject": "", |
| "type": "Annotation" |
| }, |
| { |
| "creationInfo": "_:creationInfo_0", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd10", |
| "type": "SpdxDocument" |
| }, |
| { |
| "creationInfo": "_:creationInfo_0", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd11", |
| "type": "Tool" |
| }, |
| { |
| "creationInfo": "_:creationInfo_0", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd12", |
| "type": "File" |
| }, |
| { |
| "creationInfo": "_:creationInfo_0", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd13", |
| "type": "Package" |
| }, |
| { |
| "context": "", |
| "creationInfo": "_:creationInfo_0", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd14", |
| "type": "Sbom" |
| }, |
| { |
| "creationInfo": "_:creationInfo_0", |
| "snippetFromFile": "", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd15", |
| "type": "Snippet" |
| }, |
| { |
| "creationInfo": "_:creationInfo_0", |
| "licenseExpression": "", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd16", |
| "type": "LicenseExpression" |
| }, |
| { |
| "creationInfo": "_:creationInfo_0", |
| "licenseText": "", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd17", |
| "type": "SimpleLicensingText" |
| }, |
| { |
| "context": "", |
| "creationInfo": "_:creationInfo_0", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd2", |
| "type": "Bom" |
| }, |
| { |
| "context": "", |
| "creationInfo": "_:creationInfo_0", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd3", |
| "type": "Bundle" |
| }, |
| { |
| "creationInfo": "_:creationInfo_0", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd4", |
| "type": "IndividualElement" |
| }, |
| { |
| "creationInfo": "_:creationInfo_0", |
| "from": "", |
| "relationshipType": "INVALID_RELATIONSHIP_TYPE_ID", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd5", |
| "to": [], |
| "type": "LifecycleScopedRelationship" |
| }, |
| { |
| "creationInfo": "_:creationInfo_0", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd6", |
| "type": "Organization" |
| }, |
| { |
| "creationInfo": "_:creationInfo_0", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd7", |
| "type": "Person" |
| }, |
| { |
| "creationInfo": "_:creationInfo_0", |
| "from": "", |
| "relationshipType": "INVALID_RELATIONSHIP_TYPE_ID", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd8", |
| "to": [], |
| "type": "Relationship" |
| }, |
| { |
| "creationInfo": "_:creationInfo_0", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd9", |
| "type": "SoftwareAgent" |
| } |
| ] |
| })================"); |
| |
| std::string const Optional(R"================({ |
| "@context": "https://spdx.org/rdf/3.0.1/spdx-context.jsonld", |
| "@graph": [ |
| { |
| "@id": "_:contentIdentifier_0", |
| "contentIdentifierType": "gitoid", |
| "contentIdentifierValue": "ContentIdentifierValue", |
| "type": "ContentIdentifier" |
| }, |
| { |
| "@id": "_:creationInfo_0", |
| "created": "", |
| "createdBy": [], |
| "type": "CreationInfo" |
| }, |
| { |
| "@id": "_:creationInfo_1", |
| "Comment": "Comment", |
| "created": "Created", |
| "createdBy": [ |
| "testRef" |
| ], |
| "createdUsing": [ |
| "testRef" |
| ], |
| "type": "CreationInfo" |
| }, |
| { |
| "@id": "_:dictionaryEntry_0", |
| "key": "Key", |
| "type": "DictionaryEntry", |
| "value": "Value" |
| }, |
| { |
| "@id": "_:externalIdentifier_0", |
| "comment": "Comment", |
| "externalIdentifierType": "other", |
| "identifier": "Identifier", |
| "identifierLocator": [ |
| "IdentifierLocator" |
| ], |
| "issuingAuthority": "IssuingAuthority", |
| "type": "ExternalIdentifier" |
| }, |
| { |
| "@id": "_:externalMap_0", |
| "definingArtifact": "testRef", |
| "externalSpdxId": "ExternalSpdxId", |
| "integrityMethod": [ |
| "testRef" |
| ], |
| "locationHint": "LocationHint", |
| "type": "ExternalMap" |
| }, |
| { |
| "@id": "_:externalRef_0", |
| "comment": "Comment", |
| "contentType": "ContentType", |
| "externalRefType": "other", |
| "locator": [ |
| "Locator" |
| ], |
| "type": "ExternalRef" |
| }, |
| { |
| "@id": "_:hash_0", |
| "algorithm": "other", |
| "hashValue": "HashValue", |
| "type": "Hash" |
| }, |
| { |
| "@id": "_:namespaceMap_0", |
| "namespace": "Namespace", |
| "prefix": "Namespace", |
| "type": "NamespaceMap" |
| }, |
| { |
| "@id": "_:packageVerificationCode_0", |
| "algorithm": "other", |
| "hashValue": "HashValue", |
| "type": "PackageVerificationCode" |
| }, |
| { |
| "@id": "_:positiveIntegerRange_0", |
| "beginIntegerRange": 1, |
| "endIntegerRange": 2, |
| "type": "PositiveIntegerRange" |
| }, |
| { |
| "comment": "Comment", |
| "creationInfo": "_:creationInfo_0", |
| "description": "Description", |
| "extension": [ |
| "testRef" |
| ], |
| "externalIdentifier": [ |
| "testRef" |
| ], |
| "externalRef": [ |
| "testRef" |
| ], |
| "name": "Name", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd0", |
| "summary": "Summary", |
| "type": "Agent", |
| "verifiedUsing": [ |
| "testRef" |
| ] |
| }, |
| { |
| "annotationType": "other", |
| "contentType": "ContentType", |
| "creationInfo": "_:creationInfo_0", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd1", |
| "statement": "Statement", |
| "subject": "testRef", |
| "type": "Annotation" |
| }, |
| { |
| "creationInfo": "_:creationInfo_0", |
| "dataLicense": "testRef", |
| "externalMap": "testRef", |
| "namespaceMap": "testRef", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd10", |
| "type": "SpdxDocument" |
| }, |
| { |
| "creationInfo": "_:creationInfo_0", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd11", |
| "type": "Tool" |
| }, |
| { |
| "additionalPurpose": [ |
| "other" |
| ], |
| "attributionText": "AttributionText", |
| "contentIdentifier": "testRef", |
| "contentType": "ContentType", |
| "copyrightText": "CopyrightText", |
| "creationInfo": "_:creationInfo_0", |
| "fileKind": "file", |
| "primaryPurpose": "file", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd12", |
| "type": "File" |
| }, |
| { |
| "creationInfo": "_:creationInfo_0", |
| "downloadLocation": "DownloadLocation", |
| "homePage": "HomePage", |
| "packageUrl": "PackageUrl", |
| "packageVersion": "PackageVersion", |
| "sourceInfo": "SourceInfo", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd13", |
| "type": "Package" |
| }, |
| { |
| "context": "", |
| "creationInfo": "_:creationInfo_0", |
| "sbomType": [ |
| "build" |
| ], |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd14", |
| "type": "Sbom" |
| }, |
| { |
| "byteRange": "testRef", |
| "creationInfo": "_:creationInfo_0", |
| "lineRange": "testRef", |
| "snippetFromFile": "testRef", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd15", |
| "type": "Snippet" |
| }, |
| { |
| "creationInfo": "_:creationInfo_0", |
| "customIdToUri": [ |
| "testRef" |
| ], |
| "licenseExpression": "LicenseExpression", |
| "licenseListVersion": "LicenseListVersion", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd16", |
| "type": "LicenseExpression" |
| }, |
| { |
| "creationInfo": "_:creationInfo_0", |
| "licenseText": "LicenseText", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd17", |
| "type": "SimpleLicensingText" |
| }, |
| { |
| "context": "Context", |
| "creationInfo": "_:creationInfo_0", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd2", |
| "type": "Bom" |
| }, |
| { |
| "context": "", |
| "creationInfo": "_:creationInfo_0", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd3", |
| "type": "Bundle" |
| }, |
| { |
| "creationInfo": "_:creationInfo_0", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd4", |
| "type": "IndividualElement" |
| }, |
| { |
| "completeness": "noAssertion", |
| "creationInfo": "_:creationInfo_0", |
| "endTime": "EndTime", |
| "from": "testRef", |
| "relationshipType": "other", |
| "scope": "other", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd5", |
| "startTime": "StartTime", |
| "to": [ |
| "testRef" |
| ], |
| "type": "LifecycleScopedRelationship" |
| }, |
| { |
| "creationInfo": "_:creationInfo_0", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd6", |
| "type": "Organization" |
| }, |
| { |
| "creationInfo": "_:creationInfo_0", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd7", |
| "type": "Person" |
| }, |
| { |
| "creationInfo": "_:creationInfo_0", |
| "from": "", |
| "relationshipType": "INVALID_RELATIONSHIP_TYPE_ID", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd8", |
| "to": [], |
| "type": "Relationship" |
| }, |
| { |
| "creationInfo": "_:creationInfo_0", |
| "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd9", |
| "type": "SoftwareAgent" |
| } |
| ] |
| })================"); |
| } |
| |
| int testNonOptional() |
| { |
| cmSPDXSimpleGraph graph("https://cmake.org/testSPDXSerialization-gnrtd"); |
| |
| // Core |
| graph.insert<cmSPDXAgent>(); |
| graph.insert<cmSPDXAnnotation>(); |
| graph.insert<cmSPDXBom>(); |
| graph.insert<cmSPDXBundle>(); |
| graph.insert<cmSPDXCreationInfo>(); |
| graph.insert<cmSPDXDictionaryEntry>(); |
| graph.insert<cmSPDXExternalIdentifier>(); |
| graph.insert<cmSPDXExternalMap>(); |
| graph.insert<cmSPDXExternalRef>(); |
| graph.insert<cmSPDXHash>(); |
| graph.insert<cmSPDXIndividualElement>(); |
| graph.insert<cmSPDXLifecycleScopedRelationship>(); |
| graph.insert<cmSPDXNamespaceMap>(); |
| graph.insert<cmSPDXOrganization>(); |
| graph.insert<cmSPDXPackageVerificationCode>(); |
| graph.insert<cmSPDXPerson>(); |
| graph.insert<cmSPDXPositiveIntegerRange>(); |
| graph.insert<cmSPDXRelationship>(); |
| graph.insert<cmSPDXSoftwareAgent>(); |
| graph.insert<cmSPDXSpdxDocument>(); |
| graph.insert<cmSPDXTool>(); |
| |
| // Software |
| graph.insert<cmSPDXContentIdentifier>(); |
| graph.insert<cmSPDXFile>(); |
| graph.insert<cmSPDXPackage>(); |
| graph.insert<cmSPDXSbom>(); |
| graph.insert<cmSPDXSnippet>(); |
| |
| // SimpleLicensing |
| graph.insert<cmSPDXLicenseExpression>(); |
| graph.insert<cmSPDXSimpleLicensingText>(); |
| |
| Json::Value root; |
| Json::Reader().parse(nonOptional.c_str(), root); |
| |
| std::cout << "NonOptional SPDX:"; |
| std::cout << "\nConstructed Graph: " << graph.toJsonLD().toStyledString(); |
| std::cout << "\nComparison Graph:" << root.toStyledString() << "\n"; |
| |
| // Convert to string to disregard differences in number signedness |
| return root.toStyledString() == graph.toJsonLD().toStyledString(); |
| }; |
| |
| int testOptional() |
| { |
| cmSPDXSimpleGraph graph("https://cmake.org/testSPDXSerialization-gnrtd"); |
| |
| cmSPDXIdentifierReference ident("testRef"); |
| |
| // Core |
| auto& agent = graph.insert<cmSPDXAgent>(); |
| agent.Comment = "Comment"; |
| agent.Description = "Description"; |
| agent.Extension.emplace().push_back(ident); |
| agent.ExternalIdentifier.emplace().push_back(ident); |
| agent.ExternalRef.emplace().push_back(ident); |
| agent.Name = "Name"; |
| agent.Summary = "Summary"; |
| agent.VerifiedUsing.emplace().push_back(ident); |
| |
| auto& annotation = graph.insert<cmSPDXAnnotation>(); |
| annotation.AnnotationType = cmSPDXAnnotationType::OTHER; |
| annotation.ContentType = "ContentType"; |
| annotation.Statement = "Statement"; |
| annotation.Subject = ident; |
| |
| auto& bom = graph.insert<cmSPDXBom>(); |
| bom.Context = "Context"; |
| |
| graph.insert<cmSPDXBundle>(); |
| |
| auto& creationInfo = graph.insert<cmSPDXCreationInfo>(); |
| creationInfo.Comment = "Comment"; |
| creationInfo.Created = "Created"; |
| creationInfo.CreatedBy.push_back(ident); |
| creationInfo.CreatedUsing.emplace().push_back(ident); |
| |
| auto& dictionaryEntry = graph.insert<cmSPDXDictionaryEntry>(); |
| dictionaryEntry.Key = "Key"; |
| dictionaryEntry.Value = "Value"; |
| |
| auto& externalIdentifier = graph.insert<cmSPDXExternalIdentifier>(); |
| externalIdentifier.Comment = "Comment"; |
| externalIdentifier.ExternalIdentifierType = |
| cmSPDXExternalIdentifierType::OTHER; |
| externalIdentifier.Identifier = "Identifier"; |
| externalIdentifier.IdentifierLocator.emplace().push_back( |
| "IdentifierLocator"); |
| externalIdentifier.IssuingAuthority = "IssuingAuthority"; |
| |
| auto& externalMap = graph.insert<cmSPDXExternalMap>(); |
| externalMap.DefiningArtifact = ident; |
| externalMap.ExternalSpdxId = "ExternalSpdxId"; |
| externalMap.LocationHint = "LocationHint"; |
| externalMap.IntegrityMethod.emplace().push_back(ident); |
| |
| auto& externalRef = graph.insert<cmSPDXExternalRef>(); |
| externalRef.Comment = "Comment"; |
| externalRef.ContentType = "ContentType"; |
| externalRef.ExternalRefType = cmSPDXExternalRefType::OTHER; |
| externalRef.Locator.emplace().push_back("Locator"); |
| |
| auto& hash = graph.insert<cmSPDXHash>(); |
| hash.Algorithm = cmSPDXHashAlgorithm::OTHER; |
| hash.HashValue = "HashValue"; |
| |
| graph.insert<cmSPDXIndividualElement>(); |
| |
| auto& lifecycleScopedRelationship = |
| graph.insert<cmSPDXLifecycleScopedRelationship>(); |
| lifecycleScopedRelationship.Completeness = |
| cmSPDXRelationshipCompletenessType::NO_ASSERTION; |
| lifecycleScopedRelationship.EndTime = "EndTime"; |
| lifecycleScopedRelationship.From = ident; |
| lifecycleScopedRelationship.RelationshipType = cmSPDXRelationshipType::OTHER; |
| lifecycleScopedRelationship.StartTime = "StartTime"; |
| lifecycleScopedRelationship.To.push_back(ident); |
| lifecycleScopedRelationship.Scope = cmSPDXLifecycleScopeType::OTHER; |
| |
| auto& namespaceMap = graph.insert<cmSPDXNamespaceMap>(); |
| namespaceMap.Namespace = "Namespace"; |
| namespaceMap.Prefix = "Prefix"; |
| |
| graph.insert<cmSPDXOrganization>(); |
| |
| auto& packageVerificationCode = |
| graph.insert<cmSPDXPackageVerificationCode>(); |
| packageVerificationCode.Algorithm = cmSPDXHashAlgorithm::OTHER; |
| packageVerificationCode.HashValue = "HashValue"; |
| packageVerificationCode.PackageVerificationCodeExcludedFile.emplace() |
| .push_back("PacakgeVerificationCodeExcludeFile"); |
| |
| graph.insert<cmSPDXPerson>(); |
| |
| auto& positiveIntegerRange = graph.insert<cmSPDXPositiveIntegerRange>(); |
| positiveIntegerRange.BeginIntegerRange = 1; |
| positiveIntegerRange.EndIntegerRange = 2; |
| |
| graph.insert<cmSPDXRelationship>(); |
| |
| graph.insert<cmSPDXSoftwareAgent>(); |
| |
| auto& spdxDocument = graph.insert<cmSPDXSpdxDocument>(); |
| spdxDocument.DataLicense = ident; |
| spdxDocument.ExternalMap = ident; |
| spdxDocument.NamespaceMap = ident; |
| |
| graph.insert<cmSPDXTool>(); |
| |
| // Software |
| auto& contentIdentifier = graph.insert<cmSPDXContentIdentifier>(); |
| contentIdentifier.ContentIdentifierType = |
| cmSPDXContentIdentifierType::GITOID; |
| contentIdentifier.ContentIdentifierValue = "ContentIdentifierValue"; |
| |
| auto& file = graph.insert<cmSPDXFile>(); |
| file.AdditionalPurpose.emplace().push_back(cmSPDXSoftwarePurpose::OTHER); |
| file.AttributionText = "AttributionText"; |
| file.ContentIdentifier = ident; |
| file.CopyrightText = "CopyrightText"; |
| file.PrimaryPurpose = cmSPDXSoftwarePurpose::FILE; |
| file.ContentType = "ContentType"; |
| file.FileKind = cmSPDXFileKindType::FILE; |
| |
| auto& package = graph.insert<cmSPDXPackage>(); |
| package.DownloadLocation = "DownloadLocation"; |
| package.HomePage = "HomePage"; |
| package.PackageUrl = "PackageUrl"; |
| package.PackageVersion = "PackageVersion"; |
| package.SourceInfo = "SourceInfo"; |
| |
| auto& sbom = graph.insert<cmSPDXSbom>(); |
| sbom.SbomType.emplace().push_back(cmSPDXSbomType::BUILD); |
| |
| auto& snippet = graph.insert<cmSPDXSnippet>(); |
| snippet.ByteRange = ident; |
| snippet.LineRange = ident; |
| snippet.SnippetFromFile = ident; |
| |
| // SimpleLicensing |
| auto& licenseExpression = graph.insert<cmSPDXLicenseExpression>(); |
| licenseExpression.CustomIdToUri.emplace().push_back(ident); |
| licenseExpression.LicenseExpression = "LicenseExpression"; |
| licenseExpression.LicenseListVersion = "LicenseListVersion"; |
| |
| auto& simpleLicensingText = graph.insert<cmSPDXSimpleLicensingText>(); |
| simpleLicensingText.LicenseText = "LicenseText"; |
| |
| Json::Value root; |
| Json::Reader().parse(Optional.c_str(), root); |
| |
| std::cout << "Optional SPDX:"; |
| std::cout << "\nConstructed Graph: " << graph.toJsonLD().toStyledString(); |
| std::cout << "\nComparison Graph:" << root.toStyledString() << "\n"; |
| |
| // Convert to string to disregard differences in number signedness |
| return root.toStyledString() == graph.toJsonLD().toStyledString(); |
| }; |
| |
| int testSPDXSerializer(int /* argc */, char* /* argv */[]) |
| { |
| if (!testNonOptional()) |
| return -1; |
| |
| if (!testOptional()) |
| return -1; |
| |
| return 0; |
| } |