aboutsummaryrefslogtreecommitdiff
path: root/rdfloader
diff options
context:
space:
mode:
authorRishabh Bhatnagar <bhatnagarrishabh4@gmail.com>2020-09-04 16:59:47 +0530
committerRishabh Bhatnagar <bhatnagarrishabh4@gmail.com>2020-09-04 16:59:47 +0530
commit08d5f11734e6426ebc87e261e2ce42c0260c4d0d (patch)
treeab1682375dc11dfca27ba41a27c5ccbbc86e23a4 /rdfloader
parent84fab30a66a136c293769b182265c62e6665b302 (diff)
downloadspdx-tools-08d5f11734e6426ebc87e261e2ce42c0260c4d0d.tar.gz
Add Tests And Bug Fixes For Remaining Files
- setting file referenced in the range to parser files instead of the Unpackaged Files. - externalReference now requires just a node rather than a triple. - tidied and DRYed parsing of Snippet range. - allow licenseInfoInFile of File to be AnyLicenseInfo instead of SimpleLicensingInfo. - change signature of getSnippetInformation from Triple To Node. - add simpleLicensingInfo switch in the anyLicensingInfo switch. - change input of getExternaelDocumentRef from triples to Node for easier prototyping. - remove unused methods in utils - remove parser association from utils functions Signed-off-by: Rishabh Bhatnagar <bhatnagarrishabh4@gmail.com>
Diffstat (limited to 'rdfloader')
-rw-r--r--rdfloader/parser2v2/constants.go1
-rw-r--r--rdfloader/parser2v2/parse_annotation.go3
-rw-r--r--rdfloader/parser2v2/parse_annotation_test.go2
-rw-r--r--rdfloader/parser2v2/parse_creation_info_test.go5
-rw-r--r--rdfloader/parser2v2/parse_file.go21
-rw-r--r--rdfloader/parser2v2/parse_file_test.go66
-rw-r--r--rdfloader/parser2v2/parse_license.go4
-rw-r--r--rdfloader/parser2v2/parse_license_test.go37
-rw-r--r--rdfloader/parser2v2/parse_package.go75
-rw-r--r--rdfloader/parser2v2/parse_package_test.go678
-rw-r--r--rdfloader/parser2v2/parse_relationship.go15
-rw-r--r--rdfloader/parser2v2/parse_relationship_test.go69
-rw-r--r--rdfloader/parser2v2/parse_review.go2
-rw-r--r--rdfloader/parser2v2/parse_snippet_info.go203
-rw-r--r--rdfloader/parser2v2/parse_snippet_info_test.go532
-rw-r--r--rdfloader/parser2v2/parse_spdx_document.go16
-rw-r--r--rdfloader/parser2v2/parse_spdx_document_test.go238
-rw-r--r--rdfloader/parser2v2/parser.go19
-rw-r--r--rdfloader/parser2v2/parser_test.go161
-rw-r--r--rdfloader/parser2v2/types.go7
-rw-r--r--rdfloader/parser2v2/utils.go42
-rw-r--r--rdfloader/parser2v2/utils_test.go287
-rw-r--r--rdfloader/rdfloader_test.go32
23 files changed, 2213 insertions, 302 deletions
diff --git a/rdfloader/parser2v2/constants.go b/rdfloader/parser2v2/constants.go
index dea7e68..063f2b8 100644
--- a/rdfloader/parser2v2/constants.go
+++ b/rdfloader/parser2v2/constants.go
@@ -91,6 +91,7 @@ var (
SPDX_DISJUNCTIVE_LICENSE_SET = NS_SPDX + "DisjunctiveLicenseSet"
SPDX_CONJUNCTIVE_LICENSE_SET = NS_SPDX + "ConjunctiveLicenseSet"
SPDX_EXTRACTED_LICENSING_INFO = NS_SPDX + "ExtractedLicensingInfo"
+ SPDX_SIMPLE_LICENSING_INFO = NS_SPDX + "SimpleLicensingInfo"
SPDX_NONE_CAPS = NS_SPDX + "NONE"
SPDX_NOASSERTION_CAPS = NS_SPDX + "NOASSERTION"
SPDX_NONE_SMALL = NS_SPDX + "none"
diff --git a/rdfloader/parser2v2/parse_annotation.go b/rdfloader/parser2v2/parse_annotation.go
index 6a47d84..01a6b66 100644
--- a/rdfloader/parser2v2/parse_annotation.go
+++ b/rdfloader/parser2v2/parse_annotation.go
@@ -3,6 +3,7 @@
package parser2v2
import (
+ "errors"
"fmt"
gordfParser "github.com/RishabhBhatnagar/gordf/rdfloader/parser"
"github.com/spdx/tools-golang/spdx"
@@ -42,7 +43,7 @@ func (parser *rdfParser2_2) parseAnnotationFromNode(node *gordfParser.Node) (err
func setAnnotationToParser(parser *rdfParser2_2, annotation *spdx.Annotation2_2) error {
if parser.doc == nil {
- return fmt.Errorf("uninitialized spdx document")
+ return errors.New("uninitialized spdx document")
}
if parser.doc.Annotations == nil {
parser.doc.Annotations = []*spdx.Annotation2_2{}
diff --git a/rdfloader/parser2v2/parse_annotation_test.go b/rdfloader/parser2v2/parse_annotation_test.go
index 8c6fdcf..377ac57 100644
--- a/rdfloader/parser2v2/parse_annotation_test.go
+++ b/rdfloader/parser2v2/parse_annotation_test.go
@@ -11,7 +11,7 @@ func Test_setAnnotatorFromString(t *testing.T) {
input := ""
err := setAnnotatorFromString(input, ann)
if err == nil {
- t.Errorf("should've raised an error for an empty string")
+ t.Error("should've raised an error for an empty string")
}
// TestCase 2: Invalid annotator type
diff --git a/rdfloader/parser2v2/parse_creation_info_test.go b/rdfloader/parser2v2/parse_creation_info_test.go
index fbe28b5..e18043c 100644
--- a/rdfloader/parser2v2/parse_creation_info_test.go
+++ b/rdfloader/parser2v2/parse_creation_info_test.go
@@ -42,10 +42,7 @@ func Test_rdfParser2_2_parseCreationInfoFromNode(t *testing.T) {
<spdx:CreationInfo>
<spdx:licenseListVersion>2.6</spdx:licenseListVersion>
<spdx:creator>Person Unknown</spdx:creator>
- <spdx:creator>Organization: </spdx:creator>
- <spdx:creator>Tool: spdx2</spdx:creator>
<spdx:created>2018-08-24T19:55:34Z</spdx:created>
- <spdx:unknownPredicate />
</spdx:CreationInfo>
`)
ciNode := parser.gordfParserObj.Triples[0].Subject
@@ -104,4 +101,4 @@ func Test_rdfParser2_2_parseCreationInfoFromNode(t *testing.T) {
if ci.CreatorComment != expectedComment {
t.Errorf("expected %s, found %s", expectedComment, ci.CreatorComment)
}
-} \ No newline at end of file
+}
diff --git a/rdfloader/parser2v2/parse_file.go b/rdfloader/parser2v2/parse_file.go
index a080808..267df7e 100644
--- a/rdfloader/parser2v2/parse_file.go
+++ b/rdfloader/parser2v2/parse_file.go
@@ -45,7 +45,7 @@ func (parser *rdfParser2_2) getFileFromNode(fileNode *gordfParser.Node) (file *s
file.LicenseConcluded = anyLicense.ToLicenseString()
case SPDX_LICENSE_INFO_IN_FILE: // 4.6
// cardinality: min 1
- lic, err := parser.getLicenseInfoInFileFromNode(subTriple.Object)
+ lic, err := parser.getAnyLicenseFromNode(subTriple.Object)
if err != nil {
return nil, fmt.Errorf("error parsing licenseInfoInFile: %v", err)
}
@@ -181,22 +181,3 @@ func getNoticeTextFromNode(node *gordfParser.Node) string {
return node.ID
}
}
-
-func (parser *rdfParser2_2) getLicenseInfoInFileFromNode(node *gordfParser.Node) (AnyLicenseInfo, error) {
- // LicenseInfoInFile can either be NONE | NOASSERTION | SimpleLicensingInfo
- // return type is kept as AnyLicenseInfo because, we can have
- // either SpecialLicense or SimpleLicensingInfo as the output
- switch node.ID {
- case SPDX_NOASSERTION_CAPS, SPDX_NOASSERTION_SMALL:
- return SpecialLicense{
- value: NOASSERTION,
- }, nil
- case SPDX_NONE_CAPS, SPDX_NONE_SMALL:
- return SpecialLicense{
- value: NONE,
- }, nil
- }
-
- // the license must be a SimpleLicense
- return parser.getSimpleLicensingInfoFromNode(node)
-}
diff --git a/rdfloader/parser2v2/parse_file_test.go b/rdfloader/parser2v2/parse_file_test.go
index e9fa16c..0d7022a 100644
--- a/rdfloader/parser2v2/parse_file_test.go
+++ b/rdfloader/parser2v2/parse_file_test.go
@@ -424,10 +424,22 @@ func Test_rdfParser2_2_getFileFromNode(t *testing.T) {
fileNode = gordfWriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_FILE)[0].Subject
_, err = parser.getFileFromNode(fileNode)
if err == nil {
- t.Errorf("should've raised an error stating invalid predicate for a file")
+ t.Error("should've raised an error stating invalid predicate for a file")
}
- // TestCase 9: all valid attribute and it's values.
+ // TestCase 9: invalid licenseInfoInFile.
+ parser, _ = parserFromBodyContent(`
+ <spdx:File rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9.tar.gz_1535120734-spdx.rdf#SPDXRef-item177">
+ <spdx:licenseInfoInFile rdf:resource="http://spdx.org/licenses/DC0-1.0" />
+ </spdx:File>
+ `)
+ fileNode = gordfWriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_FILE)[0].Subject
+ _, err = parser.getFileFromNode(fileNode)
+ if err == nil {
+ t.Error("should've raised an error stating invalid licenseInfoInFile for a file")
+ }
+
+ // TestCase 10: all valid attribute and it's values.
parser, _ = parserFromBodyContent(`
<spdx:File rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9.tar.gz_1535120734-spdx.rdf#SPDXRef-item177">
<spdx:fileName>time-1.9/ChangeLog</spdx:fileName>
@@ -649,53 +661,3 @@ func Test_getNoticeTextFromNode(t *testing.T) {
t.Errorf("expected text, found %s", output)
}
}
-
-func Test_rdfParser2_2_getLicenseInfoInFileFromNode(t *testing.T) {
- parser, _ := parserFromBodyContent(``)
-
- // TestCase 1: noassertion License
- lic, err := parser.getLicenseInfoInFileFromNode(&gordfParser.Node{
- NodeType: gordfParser.RESOURCELITERAL,
- ID: SPDX_NOASSERTION_CAPS,
- })
- if err != nil {
- t.Errorf("error parsing a valid license")
- }
- if lic.ToLicenseString() != "NOASSERTION" {
- t.Errorf("expected %s, found %s", "NOASSERTION", lic.ToLicenseString())
- }
-
- // TestCase 2: none License
- lic, err = parser.getLicenseInfoInFileFromNode(&gordfParser.Node{
- NodeType: gordfParser.RESOURCELITERAL,
- ID: SPDX_NONE_CAPS,
- })
- if err != nil {
- t.Errorf("error parsing a valid license")
- }
- if lic.ToLicenseString() != "NONE" {
- t.Errorf("expected %s, found %s", "NONE", lic.ToLicenseString())
- }
-
- // TestCase 3: invalid license
- // TestCase 1: noassertion License
- node := &gordfParser.Node{
- NodeType: gordfParser.BLANK,
- ID: "N0",
- }
- parser.gordfParserObj.Triples = append(parser.gordfParserObj.Triples, &gordfParser.Triple{
- Subject: node,
- Predicate: &gordfParser.Node{
- NodeType: gordfParser.IRI,
- ID: NS_SPDX + "invalidAttribute",
- },
- Object: &gordfParser.Node{
- NodeType: gordfParser.IRI,
- ID: NS_SPDX + "weirdLicense",
- },
- })
- lic, err = parser.getLicenseInfoInFileFromNode(node)
- if err == nil {
- t.Errorf("should've raised an error parsing an invalid license")
- }
-}
diff --git a/rdfloader/parser2v2/parse_license.go b/rdfloader/parser2v2/parse_license.go
index 4ebdccf..97ebc76 100644
--- a/rdfloader/parser2v2/parse_license.go
+++ b/rdfloader/parser2v2/parse_license.go
@@ -23,7 +23,7 @@ func (parser *rdfParser2_2) getAnyLicenseFromNode(node *gordfParser.Node) (AnyLi
}
// we have some attributes associated with the license node.
- nodeType, err := parser.getNodeTypeFromTriples(associatedTriples, node)
+ nodeType, err := getNodeTypeFromTriples(associatedTriples, node)
if err != nil {
return nil, fmt.Errorf("error parsing license triple: %v", err)
}
@@ -40,6 +40,8 @@ func (parser *rdfParser2_2) getAnyLicenseFromNode(node *gordfParser.Node) (AnyLi
return parser.getWithExceptionOperatorFromNode(node)
case SPDX_OR_LATER_OPERATOR:
return parser.getOrLaterOperatorFromNode(node)
+ case SPDX_SIMPLE_LICENSING_INFO:
+ return parser.getSimpleLicensingInfoFromNode(node)
}
return nil, fmt.Errorf("Unknown subTag (%s) found while parsing AnyLicense", nodeType)
}
diff --git a/rdfloader/parser2v2/parse_license_test.go b/rdfloader/parser2v2/parse_license_test.go
index 942ed4f..5a8efbb 100644
--- a/rdfloader/parser2v2/parse_license_test.go
+++ b/rdfloader/parser2v2/parse_license_test.go
@@ -182,12 +182,15 @@ func Test_rdfParser2_2_getAnyLicenseFromNode(t *testing.T) {
t.Errorf("expected license to be of type OrLaterOperator, found %v", reflect.TypeOf(lic))
}
- // TestCase 7: checking if any random node which is not associated with any
- // rdf:type triple raises an error
- parser, _ = parserFromBodyContent(``)
- bnodeGetter := gordfParser.BlankNodeGetter{}
- bnode := bnodeGetter.Get()
- _, err = parser.getAnyLicenseFromNode(&bnode)
+ // TestCase 7: checking if an unknown license raises an error.
+ parser, _ = parserFromBodyContent(`
+ <spdx:UnknownLicense>
+ <spdx:unknownTag />
+ </spdx:UnknownLicense>
+ `)
+ node := parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getAnyLicenseFromNode(node)
+ t.Log(err)
if err == nil {
t.Errorf("should've raised an error for invalid input")
}
@@ -215,7 +218,7 @@ func Test_rdfParser2_2_getConjunctiveLicenseSetFromNode(t *testing.T) {
// TestCase 2: invalid predicate in the licenseSet.
parser, _ = parserFromBodyContent(`
<spdx:ConjunctiveLicenseSet>
- <spdx:member rdf:resource="http://spdx.org/licenses/Unknown"/>
+ <spdx:member rdf:resource="http://spdx.org/licenses/CC0-1.0"/>
<spdx:member rdf:resource="http://spdx.org/licenses/LGPL-2.0"/>
<spdx:unknownTag />
</spdx:ConjunctiveLicenseSet>
@@ -551,7 +554,25 @@ func Test_rdfParser2_2_getOrLaterOperatorFromNode(t *testing.T) {
t.Error("expected an error due to invalid predicate, got <nil>")
}
- // TestCase 3: valid input
+ // TestCase 5: invalid member
+ parser, _ = parserFromBodyContent(`
+ <spdx:OrLaterOperator>
+ <spdx:member>
+ <spdx:SimpleLicensingInfo>
+ <spdx:invalidTag />
+ <spdx:licenseId>LicenseRef-Freeware</spdx:licenseId>
+ <spdx:name>freeware</spdx:name>
+ </spdx:SimpleLicensingInfo>
+ </spdx:member>
+ </spdx:OrLaterOperator>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getOrLaterOperatorFromNode(node)
+ if err == nil {
+ t.Errorf("expected an error parsing invalid license member, got %v", err)
+ }
+
+ // TestCase 4: valid input
parser, _ = parserFromBodyContent(`
<spdx:OrLaterOperator>
<spdx:member>
diff --git a/rdfloader/parser2v2/parse_package.go b/rdfloader/parser2v2/parse_package.go
index 089f3bf..9cff68c 100644
--- a/rdfloader/parser2v2/parse_package.go
+++ b/rdfloader/parser2v2/parse_package.go
@@ -37,33 +37,21 @@ func (parser *rdfParser2_2) getPackageFromNode(packageNode *gordfParser.Node) (p
case SPDX_SUPPLIER: // 3.5
// cardinality: max 1
err = setPackageSupplier(pkg, subTriple.Object.ID)
- if err != nil {
- return nil, err
- }
case SPDX_ORIGINATOR: // 3.6
// cardinality: max 1
err = setPackageOriginator(pkg, subTriple.Object.ID)
- if err != nil {
- return nil, err
- }
case SPDX_DOWNLOAD_LOCATION: // 3.7
// cardinality: exactly 1
- err = setDocumentLocationFromURI(subTriple.Object.ID, pkg)
- if err != nil {
- return nil, err
- }
+ err = setDocumentLocationFromURI(pkg, subTriple.Object.ID)
case SPDX_FILES_ANALYZED: // 3.8
// cardinality: max 1
- err = setFilesAnalyzed(subTriple.Object.ID, pkg)
- if err != nil {
- err = fmt.Errorf("error setting a filesAnalyzed attribute of a package: %v", err)
- }
+ err = setFilesAnalyzed(pkg, subTriple.Object.ID)
case SPDX_PACKAGE_VERIFICATION_CODE: // 3.9
// cardinality: max 1
err = parser.setPackageVerificationCode(pkg, subTriple.Object)
case SPDX_CHECKSUM: // 3.10
// cardinality: min 0
- err = setPackageChecksum(parser, pkg, subTriple.Object)
+ err = parser.setPackageChecksum(pkg, subTriple.Object)
case DOAP_HOMEPAGE: // 3.11
// cardinality: max 1
// homepage must be a valid Uri
@@ -108,33 +96,27 @@ func (parser *rdfParser2_2) getPackageFromNode(packageNode *gordfParser.Node) (p
pkg.PackageComment = subTriple.Object.ID
case SPDX_EXTERNAL_REF: // 3.21
// cardinality: min 0
- externalDocRef, err := parser.getPackageExternalRef(subTriple)
+ externalDocRef, err := parser.getPackageExternalRef(subTriple.Object)
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("error parsing externalRef of a package: %v", err)
}
pkg.PackageExternalReferences = append(pkg.PackageExternalReferences, externalDocRef)
case SPDX_HAS_FILE: // 3.22
// cardinality: min 0
file, err := parser.getFileFromNode(subTriple.Object)
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("error setting file inside a package: %v", err)
}
parser.setFileToPackage(pkg, file)
case SPDX_RELATIONSHIP:
// cardinality: min 0
- err := parser.parseRelationship(subTriple)
- if err != nil {
- return nil, err
- }
+ err = parser.parseRelationship(subTriple)
case SPDX_ATTRIBUTION_TEXT:
// cardinality: min 0
pkg.PackageAttributionTexts = append(pkg.PackageAttributionTexts, subTriple.Object.ID)
case SPDX_ANNOTATION:
// cardinality: min 0
- err := parser.parseAnnotationFromNode(subTriple.Object)
- if err != nil {
- return nil, err
- }
+ err = parser.parseAnnotationFromNode(subTriple.Object)
default:
return nil, fmt.Errorf("unknown predicate id %s while parsing a package", subTriple.Predicate.ID)
}
@@ -147,13 +129,13 @@ func (parser *rdfParser2_2) getPackageFromNode(packageNode *gordfParser.Node) (p
}
// parses externalReference found in the package by the associated triple.
-func (parser *rdfParser2_2) getPackageExternalRef(triple *gordfParser.Triple) (externalDocRef *spdx.PackageExternalReference2_2, err error) {
+func (parser *rdfParser2_2) getPackageExternalRef(node *gordfParser.Node) (externalDocRef *spdx.PackageExternalReference2_2, err error) {
externalDocRef = &spdx.PackageExternalReference2_2{}
- for _, subTriple := range parser.nodeToTriples(triple.Object) {
- switch subTriple.Predicate.ID {
+ for _, triple := range parser.nodeToTriples(node) {
+ switch triple.Predicate.ID {
case SPDX_REFERENCE_CATEGORY:
// cardinality: exactly 1
- switch subTriple.Object.ID {
+ switch triple.Object.ID {
case SPDX_REFERENCE_CATEGORY_SECURITY:
externalDocRef.Category = "SECURITY"
case SPDX_REFERENCE_CATEGORY_PACKAGE_MANAGER:
@@ -161,7 +143,7 @@ func (parser *rdfParser2_2) getPackageExternalRef(triple *gordfParser.Triple) (e
case SPDX_REFERENCE_CATEGORY_OTHER:
externalDocRef.Category = "OTHER"
default:
- return nil, fmt.Errorf("unknown packageManager predicate uri %s", subTriple.Predicate.ID)
+ return nil, fmt.Errorf("unknown packageManager uri %s", triple.Predicate.ID)
}
case RDF_TYPE:
continue
@@ -172,15 +154,15 @@ func (parser *rdfParser2_2) getPackageExternalRef(triple *gordfParser.Triple) (e
// 1. contextualExample,
// 2. documentation and,
// 3. externalReferenceSite
- externalDocRef.RefType = subTriple.Object.ID
+ externalDocRef.RefType = triple.Object.ID
case SPDX_REFERENCE_LOCATOR:
// cardinality: exactly 1
- externalDocRef.Locator = subTriple.Object.ID
+ externalDocRef.Locator = triple.Object.ID
case RDFS_COMMENT:
// cardinality: max 1
- externalDocRef.ExternalRefComment = subTriple.Object.ID
+ externalDocRef.ExternalRefComment = triple.Object.ID
default:
- return nil, fmt.Errorf("unknown package external reference predicate id %s", subTriple.Predicate.ID)
+ return nil, fmt.Errorf("unknown package external reference predicate id %s", triple.Predicate.ID)
}
}
return
@@ -205,6 +187,8 @@ func (parser *rdfParser2_2) setPackageVerificationCode(pkg *spdx.Package2_2, nod
return nil
}
+// appends the file to the package and also sets the assocWithPackage for the
+// file to indicate the file is associated with a package
func (parser *rdfParser2_2) setFileToPackage(pkg *spdx.Package2_2, file *spdx.File2_2) {
if pkg.Files == nil {
pkg.Files = map[spdx.ElementID]*spdx.File2_2{}
@@ -263,9 +247,9 @@ func setPackageOriginator(pkg *spdx.Package2_2, value string) error {
}
// validates the uri and sets the location if it is valid
-func setDocumentLocationFromURI(locationURI string, pkg *spdx.Package2_2) error {
+func setDocumentLocationFromURI(pkg *spdx.Package2_2, locationURI string) error {
switch locationURI {
- case SPDX_NOASSERTION_CAPS, SPDX_NOASSERTION_CAPS:
+ case SPDX_NOASSERTION_CAPS, SPDX_NOASSERTION_SMALL:
pkg.PackageDownloadLocation = "NOASSERTION"
case SPDX_NONE_CAPS, SPDX_NONE_SMALL:
pkg.PackageDownloadLocation = "NONE"
@@ -280,23 +264,16 @@ func setDocumentLocationFromURI(locationURI string, pkg *spdx.Package2_2) error
// sets the FilesAnalyzed attribute to the given package
// boolValue is a string of type "true" or "false"
-func setFilesAnalyzed(boolValue string, pkg *spdx.Package2_2) error {
+func setFilesAnalyzed(pkg *spdx.Package2_2, boolValue string) (err error) {
pkg.IsFilesAnalyzedTagPresent = true
- switch strings.TrimSpace(boolValue) {
- case "true":
- pkg.FilesAnalyzed = true
- case "false":
- pkg.FilesAnalyzed = false
- default:
- return fmt.Errorf("filesAnalyzed can be either true/false. found %s", boolValue)
- }
- return nil
+ pkg.FilesAnalyzed, err = boolFromString(boolValue)
+ return err
}
-func setPackageChecksum(parser *rdfParser2_2, pkg *spdx.Package2_2, node *gordfParser.Node) error {
+func (parser *rdfParser2_2) setPackageChecksum(pkg *spdx.Package2_2, node *gordfParser.Node) error {
checksumAlgorithm, checksumValue, err := parser.getChecksumFromNode(node)
if err != nil {
- return err
+ return fmt.Errorf("error getting checksum algorithm and value from %v", node)
}
switch checksumAlgorithm {
case "MD5":
diff --git a/rdfloader/parser2v2/parse_package_test.go b/rdfloader/parser2v2/parse_package_test.go
new file mode 100644
index 0000000..bc16ea9
--- /dev/null
+++ b/rdfloader/parser2v2/parse_package_test.go
@@ -0,0 +1,678 @@
+package parser2v2
+
+import (
+ gordfParser "github.com/RishabhBhatnagar/gordf/rdfloader/parser"
+ "github.com/spdx/tools-golang/spdx"
+ "reflect"
+ "testing"
+)
+
+func Test_setPackageSupplier(t *testing.T) {
+ var err error
+
+ // TestCase 1: no assertion must set PackageSupplierNOASSERTION field to true
+ pkg := &spdx.Package2_2{}
+ err = setPackageSupplier(pkg, "NOASSERTION")
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if !pkg.PackageSupplierNOASSERTION {
+ t.Errorf("PackageSupplierNOASSERTION must've been set to true")
+ }
+
+ // TestCase 2: lower-case noassertion must also set the
+ // PackageSupplierNOASSERTION to true.
+ pkg = &spdx.Package2_2{}
+ err = setPackageSupplier(pkg, "noassertion")
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if !pkg.PackageSupplierNOASSERTION {
+ t.Errorf("PackageSupplierNOASSERTION must've been set to true")
+ }
+
+ // TestCase 3: invalid input without colon separator. must raise an error
+ pkg = &spdx.Package2_2{}
+ input := "string without colon separator"
+ err = setPackageSupplier(pkg, input)
+ if err == nil {
+ t.Errorf("invalid input \"%s\" didn't raise an error", input)
+ }
+
+ // TestCase 4: Valid Person
+ pkg = &spdx.Package2_2{}
+ personName := "Rishabh Bhatnagar"
+ input = "Person: " + personName
+ err = setPackageSupplier(pkg, input)
+ if err != nil {
+ t.Errorf("unexpected error: %v", err)
+ }
+ if pkg.PackageSupplierPerson != personName {
+ t.Errorf("PackageSupplierPerson should be %s. found %s", personName, pkg.PackageSupplierPerson)
+ }
+
+ // TestCase 5: Valid Organization
+ pkg = &spdx.Package2_2{}
+ orgName := "SPDX"
+ input = "Organization: " + orgName
+ err = setPackageSupplier(pkg, input)
+ if err != nil {
+ t.Errorf("unexpected error: %v", err)
+ }
+ if pkg.PackageSupplierOrganization != orgName {
+ t.Errorf("PackageSupplierPerson should be %s. found %s", orgName, pkg.PackageSupplierOrganization)
+ }
+
+ // TestCase 6: Invalid EntityType
+ pkg = &spdx.Package2_2{}
+ input = "InvalidEntity: entity"
+ err = setPackageSupplier(pkg, input)
+ if err == nil {
+ t.Errorf("invalid entity should've raised an error")
+ }
+}
+
+func Test_setPackageOriginator(t *testing.T) {
+ var err error
+
+ // TestCase 1: no assertion must set PackageSupplierNOASSERTION field to true
+ pkg := &spdx.Package2_2{}
+ err = setPackageOriginator(pkg, "NOASSERTION")
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if !pkg.PackageOriginatorNOASSERTION {
+ t.Errorf("PackageOriginatorNOASSERTION must've been set to true")
+ }
+
+ // TestCase 2: lower-case noassertion must also set the
+ // PackageOriginatorNOASSERTION to true.
+ pkg = &spdx.Package2_2{}
+ err = setPackageOriginator(pkg, "noassertion")
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if !pkg.PackageOriginatorNOASSERTION {
+ t.Errorf("PackageOriginatorNOASSERTION must've been set to true")
+ }
+
+ // TestCase 3: invalid input without colon separator. must raise an error
+ pkg = &spdx.Package2_2{}
+ input := "string without colon separator"
+ err = setPackageOriginator(pkg, input)
+ if err == nil {
+ t.Errorf("invalid input \"%s\" didn't raise an error", input)
+ }
+
+ // TestCase 4: Valid Person
+ pkg = &spdx.Package2_2{}
+ personName := "Rishabh Bhatnagar"
+ input = "Person: " + personName
+ err = setPackageOriginator(pkg, input)
+ if err != nil {
+ t.Errorf("unexpected error: %v", err)
+ }
+ if pkg.PackageOriginatorPerson != personName {
+ t.Errorf("PackageOriginatorPerson should be %s. found %s", personName, pkg.PackageOriginatorPerson)
+ }
+
+ // TestCase 5: Valid Organization
+ pkg = &spdx.Package2_2{}
+ orgName := "SPDX"
+ input = "Organization: " + orgName
+ err = setPackageOriginator(pkg, input)
+ if err != nil {
+ t.Errorf("unexpected error: %v", err)
+ }
+ if pkg.PackageOriginatorOrganization != orgName {
+ t.Errorf("PackageOriginatorOrganization should be %s. found %s", orgName, pkg.PackageOriginatorOrganization)
+ }
+
+ // TestCase 6: Invalid EntityType
+ pkg = &spdx.Package2_2{}
+ input = "InvalidEntity: entity"
+ err = setPackageOriginator(pkg, input)
+ if err == nil {
+ t.Errorf("invalid entity should've raised an error")
+ }
+}
+
+func Test_rdfParser2_2_setPackageVerificationCode(t *testing.T) {
+ var parser *rdfParser2_2
+ var node *gordfParser.Node
+ var pkg *spdx.Package2_2
+ var err error
+
+ // TestCase 1: invalid predicate must raise an error
+ parser, _ = parserFromBodyContent(`
+ <spdx:PackageVerificationCode>
+ <spdx:invalidPredicate />
+ <spdx:packageVerificationCodeValue>cbceb8b5689b75a584efe35587b5d41bd48820ce</spdx:packageVerificationCodeValue>
+ <spdx:packageVerificationCodeExcludedFile>./package.spdx</spdx:packageVerificationCodeExcludedFile>
+ </spdx:PackageVerificationCode>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ pkg = &spdx.Package2_2{}
+ err = parser.setPackageVerificationCode(pkg, node)
+ if err == nil {
+ t.Errorf("expected an error due to invalid predicate, got <nil>")
+ }
+
+ // TestCase 2: valid input
+ parser, _ = parserFromBodyContent(`
+ <spdx:PackageVerificationCode>
+ <spdx:packageVerificationCodeValue>cbceb8b5689b75a584efe35587b5d41bd48820ce</spdx:packageVerificationCodeValue>
+ <spdx:packageVerificationCodeExcludedFile>./package.spdx</spdx:packageVerificationCodeExcludedFile>
+ </spdx:PackageVerificationCode>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ pkg = &spdx.Package2_2{}
+ err = parser.setPackageVerificationCode(pkg, node)
+ if err != nil {
+ t.Errorf("unexpected error: %v", err)
+ }
+ expectedValue := "cbceb8b5689b75a584efe35587b5d41bd48820ce"
+ if pkg.PackageVerificationCode != expectedValue {
+ t.Errorf("expected %v, got %v", expectedValue, pkg.PackageVerificationCode)
+ }
+ expectedExcludedFile := "./package.spdx"
+ if pkg.PackageVerificationCodeExcludedFile != expectedExcludedFile {
+ t.Errorf("expected %v, got %v", expectedExcludedFile, pkg.PackageVerificationCodeExcludedFile)
+ }
+}
+
+func Test_rdfParser2_2_getPackageExternalRef(t *testing.T) {
+ var extRef *spdx.PackageExternalReference2_2
+ var err error
+ var parser *rdfParser2_2
+ var node *gordfParser.Node
+
+ // TestCase 1: invalid reference category
+ parser, _ = parserFromBodyContent(`
+ <spdx:ExternalRef>
+ <spdx:referenceLocator>cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*</spdx:referenceLocator>
+ <spdx:referenceType>
+ <spdx:ReferenceType rdf:about="http://spdx.org/rdf/references/cpe23Type"/>
+ </spdx:referenceType>
+ <spdx:referenceCategory rdf:resource="http://spdx.org/rdf/terms#referenceCategory_invalid"/>
+ </spdx:ExternalRef>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ extRef, err = parser.getPackageExternalRef(node)
+ if err == nil {
+ t.Errorf("expected an error due to invalid referenceCategory, got <nil>")
+ }
+
+ // TestCase 2: invalid predicate
+ parser, _ = parserFromBodyContent(`
+ <spdx:ExternalRef>
+ <spdx:unknownPredicate />
+ <spdx:referenceLocator>cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*</spdx:referenceLocator>
+ <spdx:referenceType>
+ <spdx:ReferenceType rdf:about="http://spdx.org/rdf/references/cpe23Type"/>
+ </spdx:referenceType>
+ <spdx:referenceCategory rdf:resource="http://spdx.org/rdf/terms#referenceCategory_security"/>
+ </spdx:ExternalRef>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ extRef, err = parser.getPackageExternalRef(node)
+ if err == nil {
+ t.Errorf("expected an error due to invalid referenceCategory, got <nil>")
+ }
+
+ // TestCase 3: valid example (referenceCategory_security)
+ parser, _ = parserFromBodyContent(`
+ <spdx:ExternalRef>
+ <spdx:referenceLocator>cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*</spdx:referenceLocator>
+ <spdx:referenceType>
+ <spdx:ReferenceType rdf:about="http://spdx.org/rdf/references/cpe23Type"/>
+ </spdx:referenceType>
+ <spdx:referenceCategory rdf:resource="http://spdx.org/rdf/terms#referenceCategory_security"/>
+ <rdfs:comment>comment</rdfs:comment>
+ </spdx:ExternalRef>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ extRef, err = parser.getPackageExternalRef(node)
+ if err != nil {
+ t.Fatalf("unexpected error parsing a valid example: %v", err)
+ }
+ expectedExtRef := &spdx.PackageExternalReference2_2{
+ Locator: "cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*",
+ RefType: "http://spdx.org/rdf/references/cpe23Type",
+ Category: "SECURITY",
+ ExternalRefComment: "comment",
+ }
+ if !reflect.DeepEqual(extRef, expectedExtRef) {
+ t.Errorf("expected: \n%+v\ngot: \n%+v", expectedExtRef, extRef)
+ }
+
+ // TestCase 4: valid example (referenceCategory_packageManager)
+ parser, _ = parserFromBodyContent(`
+ <spdx:ExternalRef>
+ <spdx:referenceLocator>cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*</spdx:referenceLocator>
+ <spdx:referenceType>
+ <spdx:ReferenceType rdf:about="http://spdx.org/rdf/references/cpe23Type"/>
+ </spdx:referenceType>
+ <spdx:referenceCategory rdf:resource="http://spdx.org/rdf/terms#referenceCategory_packageManager"/>
+ <rdfs:comment>comment</rdfs:comment>
+ </spdx:ExternalRef>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ extRef, err = parser.getPackageExternalRef(node)
+ if err != nil {
+ t.Fatalf("unexpected error parsing a valid example: %v", err)
+ }
+ expectedExtRef = &spdx.PackageExternalReference2_2{
+ Locator: "cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*",
+ RefType: "http://spdx.org/rdf/references/cpe23Type",
+ Category: "PACKAGE-MANAGER",
+ ExternalRefComment: "comment",
+ }
+ if !reflect.DeepEqual(extRef, expectedExtRef) {
+ t.Errorf("expected: \n%+v\ngot: \n%+v", expectedExtRef, extRef)
+ }
+
+ // TestCase 5: valid example (referenceCategory_other)
+ parser, _ = parserFromBodyContent(`
+ <spdx:ExternalRef>
+ <spdx:referenceLocator>cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*</spdx:referenceLocator>
+ <spdx:referenceType>
+ <spdx:ReferenceType rdf:about="http://spdx.org/rdf/references/cpe23Type"/>
+ </spdx:referenceType>
+ <spdx:referenceCategory rdf:resource="http://spdx.org/rdf/terms#referenceCategory_other"/>
+ <rdfs:comment>comment</rdfs:comment>
+ </spdx:ExternalRef>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ extRef, err = parser.getPackageExternalRef(node)
+ if err != nil {
+ t.Fatalf("unexpected error parsing a valid example: %v", err)
+ }
+ expectedExtRef = &spdx.PackageExternalReference2_2{
+ Locator: "cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*",
+ RefType: "http://spdx.org/rdf/references/cpe23Type",
+ Category: "OTHER",
+ ExternalRefComment: "comment",
+ }
+ if !reflect.DeepEqual(extRef, expectedExtRef) {
+ t.Errorf("expected: \n%+v\ngot: \n%+v", expectedExtRef, extRef)
+ }
+}
+
+func Test_rdfParser2_2_getPackageFromNode(t *testing.T) {
+ var parser *rdfParser2_2
+ var node *gordfParser.Node
+ var err error
+
+ // TestCase 1: invalid elementId
+ parser, _ = parserFromBodyContent(`
+ <spdx:Package rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9#upload2">
+ <spdx:name>time-1.9.tar.gz</spdx:name>
+ </spdx:Package>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getPackageFromNode(node)
+ if err == nil {
+ t.Errorf("expected an error(missing SPDXRef- prefix), found %v", err)
+ }
+
+ // TestCase 2: Invalid License Concluded must raise an error:
+ parser, _ = parserFromBodyContent(`
+ <spdx:Package rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9#SPDXRef-upload2">
+ <spdx:licenseConcluded rdf:resource="http://spdx.org/licenses/IPL-3.0"/>
+ </spdx:Package>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getPackageFromNode(node)
+ if err == nil {
+ t.Errorf("expected an error(invalid license), found %v", err)
+ }
+
+ // TestCase 2: Invalid License Declared must raise an error:
+ parser, _ = parserFromBodyContent(`
+ <spdx:Package rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9#SPDXRef-upload2">
+ <spdx:licenseDeclared rdf:resource="http://spdx.org/licenses/IPL-3.0"/>
+ </spdx:Package>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getPackageFromNode(node)
+ if err == nil {
+ t.Errorf("expected an error(invalid license), found %v", err)
+ }
+
+ // TestCase 3: Invalid ExternalRef
+ parser, _ = parserFromBodyContent(`
+ <spdx:Package rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9#SPDXRef-upload2">
+ <spdx:externalRef>
+ <spdx:ExternalRef>
+ <spdx:referenceLocator>cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*</spdx:referenceLocator>
+ <spdx:referenceType>
+ <spdx:ReferenceType rdf:about="http://spdx.org/rdf/references/cpe23Type"/>
+ </spdx:referenceType>
+ <spdx:referenceCategory rdf:resource="http://spdx.org/rdf/terms#referenceCategory_invalid"/>
+ </spdx:ExternalRef>
+ </spdx:externalRef>
+ </spdx:Package>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getPackageFromNode(node)
+ if err == nil {
+ t.Errorf("expected an error(invalid externalRef), found %v", err)
+ }
+
+ // TestCase 4: invalid file must raise an error
+ parser, _ = parserFromBodyContent(`
+ <spdx:Package rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9#SPDXRef-upload2">
+ <spdx:hasFile>
+ <spdx:File rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9.tar.gz_1535120734-spdx.rdf#item8"/>
+ </spdx:hasFile>
+ </spdx:Package>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getPackageFromNode(node)
+ if err == nil {
+ t.Errorf("expected an error(invalid file), found %v", err)
+ }
+
+ // TestCase 5: invalid predicate must raise an error
+ parser, _ = parserFromBodyContent(`
+ <spdx:Package rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9#SPDXRef-upload2">
+ <spdx:hasFiles>
+ <spdx:File rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9.tar.gz_1535120734-spdx.rdf#item8"/>
+ </spdx:hasFiles>
+ </spdx:Package>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getPackageFromNode(node)
+ if err == nil {
+ t.Errorf("expected an error(invalid predicate), found %v", err)
+ }
+
+ // TestCase 6: invalid annotation must raise an error
+ parser, _ = parserFromBodyContent(`
+ <spdx:Package rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9#SPDXRef-upload2">
+ <spdx:annotation>
+ <spdx:Annotation>
+ <spdx:unknownAttribute />
+ </spdx:Annotation>
+ </spdx:annotation>
+ </spdx:Package>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getPackageFromNode(node)
+ if err == nil {
+ t.Errorf("expected an error(invalid annotation), found %v", err)
+ }
+
+ // TestCase 6: invalid homepage must raise an error
+ parser, _ = parserFromBodyContent(`
+ <spdx:Package rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9#SPDXRef-upload2">
+ <doap:homepage>u r i</doap:homepage>
+ </spdx:Package>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getPackageFromNode(node)
+ if err == nil {
+ t.Errorf("expected an error(invalid homepage uri), found %v", err)
+ }
+
+ // TestCase 7: everything valid
+ parser, _ = parserFromBodyContent(`
+ <spdx:Package rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9#SPDXRef-upload2">
+ <spdx:name>Test Package</spdx:name>
+ <spdx:versionInfo>1.1.1</spdx:versionInfo>
+ <spdx:packageFileName>time-1.9.tar.gz</spdx:packageFileName>
+ <spdx:supplier>Person: Jane Doe (jane.doe@example.com)</spdx:supplier>
+ <spdx:originator>Organization: SPDX</spdx:originator>
+ <spdx:downloadLocation rdf:resource="http://spdx.org/rdf/terms#noassertion" />
+ <spdx:filesAnalyzed>true</spdx:filesAnalyzed>
+ <spdx:packageVerificationCode>
+ <spdx:PackageVerificationCode>
+ <spdx:packageVerificationCodeValue>cbceb8b5689b75a584efe35587b5d41bd48820ce</spdx:packageVerificationCodeValue>
+ <spdx:packageVerificationCodeExcludedFile>./package.spdx</spdx:packageVerificationCodeExcludedFile>
+ </spdx:PackageVerificationCode>
+ </spdx:packageVerificationCode>
+ <spdx:checksum>
+ <spdx:Checksum>
+ <spdx:algorithm rdf:resource="http://spdx.org/rdf/terms#checksumAlgorithm_sha1" />
+ <spdx:checksumValue>75068c26abbed3ad3980685bae21d7202d288317</spdx:checksumValue>
+ </spdx:Checksum>
+ </spdx:checksum>
+ <doap:homepage>http://www.openjena.org/</doap:homepage>
+ <spdx:sourceInfo>uses glibc-2_11-branch from git://sourceware.org/git/glibc.git.</spdx:sourceInfo>
+ <spdx:licenseConcluded>
+ <spdx:DisjunctiveLicenseSet>
+ <spdx:member rdf:resource="http://spdx.org/licenses/Nokia"/>
+ <spdx:member rdf:resource="http://spdx.org/licenses/LGPL-2.0"/>
+ </spdx:DisjunctiveLicenseSet>
+ </spdx:licenseConcluded>
+ <spdx:licenseInfoFromFiles rdf:resource="http://spdx.org/rdf/terms#noassertion" />
+ <spdx:licenseDeclared rdf:resource="http://spdx.org/rdf/terms#noassertion" />
+ <spdx:licenseComments>Other versions available for a commercial license</spdx:licenseComments>
+ <spdx:copyrightText rdf:resource="http://spdx.org/rdf/terms#noassertion" />
+ <spdx:summary> Package for Testing </spdx:summary>
+ <spdx:description> Some tags are taken from other spdx autogenerated files </spdx:description>
+ <rdfs:comment>no comments</rdfs:comment>
+ <spdx:externalRef>
+ <spdx:ExternalRef>
+ <spdx:referenceLocator>cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*</spdx:referenceLocator>
+ <spdx:referenceType>
+ <spdx:ReferenceType rdf:about="http://spdx.org/rdf/references/cpe23Type"/>
+ </spdx:referenceType>
+ <spdx:referenceCategory rdf:resource="http://spdx.org/rdf/terms#referenceCategory_security"/>
+ </spdx:ExternalRef>
+ </spdx:externalRef>
+ <spdx:hasFile rdf:resource="http://spdx.org/documents/spdx-toolsv2.1.7-SNAPSHOT#SPDXRef-129" />
+ <spdx:relationship>
+ <spdx:Relationship>
+ <spdx:relationshipType rdf:resource="http://spdx.org/rdf/terms#relationshipType_describes" />
+ <spdx:relatedSpdxElement rdf:resource="http://anupam-VirtualBox/repo/SPDX2_time-1.9#SPDXRef-upload2" />
+ </spdx:Relationship>
+ </spdx:relationship>
+ <spdx:attributionText>attribution text</spdx:attributionText>
+ <spdx:annotation>
+ <spdx:Annotation>
+ <spdx:annotationDate>2011-01-29T18:30:22Z</spdx:annotationDate>
+ <rdfs:comment>Package level annotation</rdfs:comment>
+ <spdx:annotator>Person: Package Commenter</spdx:annotator>
+ <spdx:annotationType rdf:resource="http://spdx.org/rdf/terms#annotationType_other"/>
+ </spdx:Annotation>
+ </spdx:annotation>
+ </spdx:Package>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getPackageFromNode(node)
+ if err != nil {
+ t.Errorf("error parsing a valid package: %v", err)
+ }
+}
+
+func Test_rdfParser2_2_setFileToPackage(t *testing.T) {
+ var pkg *spdx.Package2_2
+ var file *spdx.File2_2
+ var parser *rdfParser2_2
+
+ // TestCase 1: setting to a nil files attribute shouldn't panic.
+ parser, _ = parserFromBodyContent(``)
+ pkg = &spdx.Package2_2{}
+ file = &spdx.File2_2{}
+ parser.setFileToPackage(pkg, file)
+ if len(pkg.Files) != 1 {
+ t.Errorf("expected given package to have one file after setting, got %d", len(pkg.Files))
+ }
+ if parser.assocWithPackage[file.FileSPDXIdentifier] != true {
+ t.Errorf("given file should've been associated with a package, assocWithPackage is false")
+ }
+}
+
+func Test_rdfParser2_2_setPackageChecksum(t *testing.T) {
+ var parser *rdfParser2_2
+ var node *gordfParser.Node
+ var pkg *spdx.Package2_2
+ var gotChecksumValue, expectedChecksumValue string
+ var err error
+
+ // TestCase 1: invalid checksum algorithm
+ parser, _ = parserFromBodyContent(`
+ <spdx:Checksum>
+ <spdx:checksumValue>2fd4e1c67a2d28fced849ee1bb76e7391b93eb12</spdx:checksumValue>
+ <spdx:algorithm rdf:resource="http://spdx.org/rdf/terms#checksumAlgorithm_sha999"/>
+ </spdx:Checksum>
+ `)
+ pkg = &spdx.Package2_2{}
+ node = parser.gordfParserObj.Triples[0].Subject
+ err = parser.setPackageChecksum(pkg, node)
+ if err == nil {
+ t.Error("expected an error due to invalid checksum node, got <nil>")
+ }
+
+ // TestCase 1: valid checksum algorithm which is invalid for package
+ parser, _ = parserFromBodyContent(`
+ <spdx:Checksum>
+ <spdx:checksumValue>2fd4e1c67a2d28fced849ee1bb76e7391b93eb12</spdx:checksumValue>
+ <spdx:algorithm rdf:resource="http://spdx.org/rdf/terms#checksumAlgorithm_sha384"/>
+ </spdx:Checksum>
+ `)
+ pkg = &spdx.Package2_2{}
+ node = parser.gordfParserObj.Triples[0].Subject
+ err = parser.setPackageChecksum(pkg, node)
+ if err == nil {
+ t.Error("expected an error due to invalid checksum for package, got <nil>")
+ }
+
+ // TestCase 2: valid checksum (sha1)
+ parser, _ = parserFromBodyContent(`
+ <spdx:Checksum>
+ <spdx:checksumValue>2fd4e1c67a2d28fced849ee1bb76e7391b93eb12</spdx:checksumValue>
+ <spdx:algorithm rdf:resource="http://spdx.org/rdf/terms#checksumAlgorithm_sha1"/>
+ </spdx:Checksum>
+ `)
+ pkg = &spdx.Package2_2{}
+ node = parser.gordfParserObj.Triples[0].Subject
+ err = parser.setPackageChecksum(pkg, node)
+ if err != nil {
+ t.Errorf("unexpected error: %v", err)
+ }
+ expectedChecksumValue = "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12"
+ gotChecksumValue = pkg.PackageChecksumSHA1
+ if gotChecksumValue != expectedChecksumValue {
+ t.Errorf("expected: %v, got: %v", expectedChecksumValue, gotChecksumValue)
+ }
+
+ // TestCase 3: valid checksum (sha256)
+ parser, _ = parserFromBodyContent(`
+ <spdx:Checksum>
+ <spdx:checksumValue>2fd4e1c67a2d28fced849ee1bb76e7391b93eb12</spdx:checksumValue>
+ <spdx:algorithm rdf:resource="http://spdx.org/rdf/terms#checksumAlgorithm_sha256"/>
+ </spdx:Checksum>
+ `)
+ pkg = &spdx.Package2_2{}
+ node = parser.gordfParserObj.Triples[0].Subject
+ err = parser.setPackageChecksum(pkg, node)
+ if err != nil {
+ t.Errorf("unexpected error: %v", err)
+ }
+ expectedChecksumValue = "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12"
+ gotChecksumValue = pkg.PackageChecksumSHA256
+ if gotChecksumValue != expectedChecksumValue {
+ t.Errorf("expected: %v, got: %v", expectedChecksumValue, gotChecksumValue)
+ }
+
+ // TestCase 4: valid checksum (md5)
+ parser, _ = parserFromBodyContent(`
+ <spdx:Checksum>
+ <spdx:checksumValue>2fd4e1c67a2d28fced849ee1bb76e7391b93eb12</spdx:checksumValue>
+ <spdx:algorithm rdf:resource="http://spdx.org/rdf/terms#checksumAlgorithm_md5"/>
+ </spdx:Checksum>
+ `)
+ pkg = &spdx.Package2_2{}
+ node = parser.gordfParserObj.Triples[0].Subject
+ err = parser.setPackageChecksum(pkg, node)
+ if err != nil {
+ t.Errorf("unexpected error: %v", err)
+ }
+ expectedChecksumValue = "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12"
+ gotChecksumValue = pkg.PackageChecksumMD5
+ if gotChecksumValue != expectedChecksumValue {
+ t.Errorf("expected: %v, got: %v", expectedChecksumValue, gotChecksumValue)
+ }
+}
+
+func Test_setDocumentLocationFromURI(t *testing.T) {
+ var pkg *spdx.Package2_2
+ var expectedDocumentLocation, gotDocumentLocation string
+ var inputURI string
+ var err error
+
+ // TestCase 1: NOASSERTION
+ inputURI = SPDX_NOASSERTION_SMALL
+ pkg = &spdx.Package2_2{}
+ err = setDocumentLocationFromURI(pkg, inputURI)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ expectedDocumentLocation = "NOASSERTION"
+ gotDocumentLocation = pkg.PackageDownloadLocation
+ if expectedDocumentLocation != gotDocumentLocation {
+ t.Errorf("expected: %v, got: %v", expectedDocumentLocation, gotDocumentLocation)
+ }
+
+ // TestCase 2: NONE
+ inputURI = SPDX_NONE_CAPS
+ pkg = &spdx.Package2_2{}
+ err = setDocumentLocationFromURI(pkg, inputURI)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ expectedDocumentLocation = "NONE"
+ gotDocumentLocation = pkg.PackageDownloadLocation
+ if expectedDocumentLocation != gotDocumentLocation {
+ t.Errorf("expected: %v, got: %v", expectedDocumentLocation, gotDocumentLocation)
+ }
+
+ // TestCase 3: valid uri
+ inputURI = "https://www.gnu.org/software/texinfo/"
+ pkg = &spdx.Package2_2{}
+ err = setDocumentLocationFromURI(pkg, inputURI)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ expectedDocumentLocation = "https://www.gnu.org/software/texinfo/"
+ gotDocumentLocation = pkg.PackageDownloadLocation
+ if expectedDocumentLocation != gotDocumentLocation {
+ t.Errorf("expected: %v, got: %v", expectedDocumentLocation, gotDocumentLocation)
+ }
+
+ // TestCase 3: invalid uri
+ inputURI = " "
+ pkg = &spdx.Package2_2{}
+ err = setDocumentLocationFromURI(pkg, inputURI)
+ if err == nil {
+ t.Fatalf("expected an error due to invalid uri, got %v", err)
+ }
+}
+
+func Test_setFilesAnalyzed(t *testing.T) {
+ var pkg *spdx.Package2_2
+ var err error
+
+ // TestCase 1: not a valid bool value:
+ pkg = &spdx.Package2_2{}
+ err = setFilesAnalyzed(pkg, "no")
+ if err == nil {
+ t.Errorf("expected an error due to invalid bool input, got %v", err)
+ }
+
+ // TestCase 2: valid input
+ pkg = &spdx.Package2_2{}
+ err = setFilesAnalyzed(pkg, "true")
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if !pkg.IsFilesAnalyzedTagPresent {
+ t.Errorf("should've set IsFilesAnalyzedTagPresent, got: %t", pkg.IsFilesAnalyzedTagPresent)
+ }
+ if !pkg.FilesAnalyzed {
+ t.Errorf("expected: %t, got: %t", true, pkg.FilesAnalyzed)
+ }
+}
diff --git a/rdfloader/parser2v2/parse_relationship.go b/rdfloader/parser2v2/parse_relationship.go
index 91f44f8..b2ccf2f 100644
--- a/rdfloader/parser2v2/parse_relationship.go
+++ b/rdfloader/parser2v2/parse_relationship.go
@@ -72,11 +72,11 @@ func (parser *rdfParser2_2) parseRelatedElementFromTriple(reln *spdx.Relationshi
case SPDX_FILE:
file, err := parser.getFileFromNode(triple.Subject)
if err != nil {
- return fmt.Errorf("error setting a package: %v", err)
+ return fmt.Errorf("error setting a file: %v", err)
}
- reln.RefB, err = ExtractDocElementID(getLastPartOfURI(triple.Subject.ID))
- if err != nil {
- return err
+ reln.RefB = spdx.DocElementID{
+ DocumentRefID: "",
+ ElementRefID: file.FileSPDXIdentifier,
}
parser.files[file.FileSPDXIdentifier] = file
@@ -85,11 +85,10 @@ func (parser *rdfParser2_2) parseRelatedElementFromTriple(reln *spdx.Relationshi
if err != nil {
return fmt.Errorf("error setting a package inside a relationship: %v", err)
}
- reln.RefB, err = ExtractDocElementID(getLastPartOfURI(triple.Subject.ID))
- if err != nil {
- return err
+ reln.RefB = spdx.DocElementID{
+ DocumentRefID: "",
+ ElementRefID: pkg.PackageSPDXIdentifier,
}
-
parser.packages[pkg.PackageSPDXIdentifier] = pkg
case SPDX_SPDX_ELEMENT:
diff --git a/rdfloader/parser2v2/parse_relationship_test.go b/rdfloader/parser2v2/parse_relationship_test.go
index 0aa8315..da500e1 100644
--- a/rdfloader/parser2v2/parse_relationship_test.go
+++ b/rdfloader/parser2v2/parse_relationship_test.go
@@ -100,7 +100,22 @@ func Test_rdfParser2_2_parseRelatedElementFromTriple(t *testing.T) {
t.Errorf("expected %+v, found %+v", expectedRefB, reln.RefB)
}
- // TestCase 2: File as a related element
+ // TestCase 3: invalid package as a relatedElement
+ parser, _ = parserFromBodyContent(`
+ <spdx:Relationship>
+ <spdx:relatedSpdxElement>
+ <spdx:Package rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#Saxon"/>
+ </spdx:relatedSpdxElement>
+ </spdx:Relationship>
+ `)
+ reln = &spdx.Relationship2_2{}
+ triple = rdfwriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_PACKAGE)[0]
+ err = parser.parseRelatedElementFromTriple(reln, triple)
+ if err == nil {
+ t.Errorf("expected an error due to invalid Package id, got %v", err)
+ }
+
+ // TestCase 4: valid File as a related element
parser, _ = parserFromBodyContent(`
<spdx:Relationship>
<spdx:relatedSpdxElement>
@@ -129,6 +144,22 @@ func Test_rdfParser2_2_parseRelatedElementFromTriple(t *testing.T) {
t.Errorf("expected %+v, found %+v", expectedRefB, reln.RefB)
}
+ // TestCase 5: invalid File as a relatedElement
+ parser, _ = parserFromBodyContent(`
+ <spdx:Relationship>
+ <spdx:relatedSpdxElement>
+ <spdx:File rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#Saxon"/>
+ </spdx:relatedSpdxElement>
+ </spdx:Relationship>
+ `)
+ reln = &spdx.Relationship2_2{}
+ triple = rdfwriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_FILE)[0]
+ err = parser.parseRelatedElementFromTriple(reln, triple)
+ if err == nil {
+ t.Errorf("expected an error while parsing an invalid File, got %v", err)
+ }
+
+ // TestCase 6: valid SpdxElement as a related element
parser, _ = parserFromBodyContent(`
<spdx:Relationship>
<spdx:relatedSpdxElement>
@@ -156,6 +187,21 @@ func Test_rdfParser2_2_parseRelatedElementFromTriple(t *testing.T) {
if !reflect.DeepEqual(expectedRefB, reln.RefB) {
t.Errorf("expected %+v, found %+v", expectedRefB, reln.RefB)
}
+
+ // TestCase 7: invalid SpdxElement as a related element
+ parser, _ = parserFromBodyContent(`
+ <spdx:Relationship>
+ <spdx:relatedSpdxElement>
+ <spdx:SpdxElement rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-:File"/>
+ </spdx:relatedSpdxElement>
+ </spdx:Relationship>
+ `)
+ reln = &spdx.Relationship2_2{}
+ triple = rdfwriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_SPDX_ELEMENT)[0]
+ err = parser.parseRelatedElementFromTriple(reln, triple)
+ if err == nil {
+ t.Errorf("expected an error due to invalid documentId for SpdxElement, got %v", err)
+ }
}
func Test_rdfParser2_2_parseRelationship(t *testing.T) {
@@ -231,7 +277,26 @@ func Test_rdfParser2_2_parseRelationship(t *testing.T) {
triple = rdfwriter.FilterTriples(parser.gordfParserObj.Triples, nil, &SPDX_RELATIONSHIP, nil)[0]
err = parser.parseRelationship(triple)
if err == nil {
- t.Errorf("should've raised an error due to unknown relatedElement")
+ t.Errorf("should've raised an error due to unknown relatedElement, got %v", err)
+ }
+
+ // TestCase 6: relatedElement associated with more than one type
+ parser, _ = parserFromBodyContent(`
+ <spdx:File rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-File">
+ <spdx:relationship>
+ <spdx:Relationship>
+ <spdx:relatedSpdxElement>
+ <spdx:Package rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-Saxon"/>
+ </spdx:relatedSpdxElement>
+ </spdx:Relationship>
+ </spdx:relationship>
+ </spdx:File>
+ <spdx:File rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-Saxon"/>
+ `)
+ triple = rdfwriter.FilterTriples(parser.gordfParserObj.Triples, nil, &SPDX_RELATIONSHIP, nil)[0]
+ err = parser.parseRelationship(triple)
+ if err == nil {
+ t.Errorf("expected an error due to invalid relatedElement, got %v", err)
}
// TestCase 5: unknown predicate inside a relationship
diff --git a/rdfloader/parser2v2/parse_review.go b/rdfloader/parser2v2/parse_review.go
index fb01a80..a58a683 100644
--- a/rdfloader/parser2v2/parse_review.go
+++ b/rdfloader/parser2v2/parse_review.go
@@ -26,7 +26,7 @@ func (parser *rdfParser2_2) setReviewFromNode(reviewedNode *gordfParser.Node) er
var err error
review.ReviewerType, review.Reviewer, err = ExtractSubs(triple.Object.ID, ":")
if err != nil {
- return fmt.Errorf("error parsing reviewer: err")
+ return fmt.Errorf("error parsing reviewer: %v", err)
}
default:
return fmt.Errorf("unknown predicate %v for review triples", triple.Predicate)
diff --git a/rdfloader/parser2v2/parse_snippet_info.go b/rdfloader/parser2v2/parse_snippet_info.go
index 8db67c1..25096cb 100644
--- a/rdfloader/parser2v2/parse_snippet_info.go
+++ b/rdfloader/parser2v2/parse_snippet_info.go
@@ -5,22 +5,22 @@ package parser2v2
import (
"fmt"
gordfParser "github.com/RishabhBhatnagar/gordf/rdfloader/parser"
+ "github.com/RishabhBhatnagar/gordf/rdfwriter"
"github.com/spdx/tools-golang/spdx"
"strconv"
- "strings"
)
// Snippet Information
// Cardinality: Optional, Many
-func (parser *rdfParser2_2) getSnippetInformationFromTriple2_2(triple *gordfParser.Triple) (si *spdx.Snippet2_2, err error) {
+func (parser *rdfParser2_2) getSnippetInformationFromNode2_2(node *gordfParser.Node) (si *spdx.Snippet2_2, err error) {
si = &spdx.Snippet2_2{}
- err = setSnippetID(triple.Subject.ID, si)
+ err = setSnippetID(node.ID, si)
if err != nil {
return nil, err
}
- for _, siTriple := range parser.nodeToTriples(triple.Subject) {
+ for _, siTriple := range parser.nodeToTriples(node) {
switch siTriple.Predicate.ID {
case RDF_TYPE:
// cardinality: exactly 1
@@ -33,24 +33,37 @@ func (parser *rdfParser2_2) getSnippetInformationFromTriple2_2(triple *gordfPars
}
si.SnippetFromFileSPDXIdentifier, err = ExtractDocElementID(getLastPartOfURI(siTriple.Object.ID))
parser.files[file.FileSPDXIdentifier] = file
+ case SPDX_RANGE:
+ // cardinality: min 1
+ err = parser.setSnippetRangeFromNode(siTriple.Object, si)
+ if err != nil {
+ return nil, err
+ }
+ case SPDX_LICENSE_INFO_IN_SNIPPET:
+ // license info in snippet can be NONE, NOASSERTION or SimpleLicensingInfo
+ // using AnyLicenseInfo because it can redirect the request and
+ // can handle NONE & NOASSERTION
+ var anyLicense AnyLicenseInfo
+ anyLicense, err = parser.getAnyLicenseFromNode(siTriple.Object)
+ if err != nil {
+ return nil, fmt.Errorf("error parsing license info in snippet: %v", err)
+ }
+ si.LicenseInfoInSnippet = append(si.LicenseInfoInSnippet, anyLicense.ToLicenseString())
case SPDX_NAME:
si.SnippetName = siTriple.Object.ID
case SPDX_COPYRIGHT_TEXT:
si.SnippetCopyrightText = siTriple.Object.ID
case SPDX_LICENSE_COMMENTS:
si.SnippetLicenseComments = siTriple.Object.ID
- case SPDX_LICENSE_INFO_IN_SNIPPET:
- si.LicenseInfoInSnippet = append(si.LicenseInfoInSnippet, siTriple.Object.ID)
case RDFS_COMMENT:
si.SnippetComment = siTriple.Object.ID
case SPDX_LICENSE_CONCLUDED:
- si.SnippetLicenseConcluded = siTriple.Object.ID
- case SPDX_RANGE:
- // cardinality: min 1
- err = parser.setSnippetRangeFromNode(siTriple.Object, si)
+ var anyLicense AnyLicenseInfo
+ anyLicense, err = parser.getAnyLicenseFromNode(siTriple.Object)
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("error parsing license info in snippet: %v", err)
}
+ si.SnippetLicenseConcluded = anyLicense.ToLicenseString()
default:
return nil, fmt.Errorf("unknown predicate %v", siTriple.Predicate.ID)
}
@@ -76,117 +89,101 @@ func (parser *rdfParser2_2) setSnippetToFileWithID(snippet *spdx.Snippet2_2, fil
}
func (parser *rdfParser2_2) setSnippetRangeFromNode(node *gordfParser.Node, si *spdx.Snippet2_2) error {
- // todo: apply DRY in this method.
- rangeType := 0 // 0: undefined range, 1: byte, 2: line
- var start, end string
- for _, t := range parser.nodeToTriples(node) {
- switch t.Predicate.ID {
- case RDF_TYPE:
- if t.Object.ID != PTR_START_END_POINTER {
- return fmt.Errorf("expected range to have sub tag of type StartEndPointer, found %v", t.Object.ID)
- }
- case PTR_START_POINTER:
- for _, subTriple := range parser.nodeToTriples(t.Object) {
- switch subTriple.Predicate.ID {
- case RDF_TYPE:
- switch subTriple.Object.ID {
- case PTR_BYTE_OFFSET_POINTER:
- if rangeType == 2 {
- return fmt.Errorf("byte offset pointer merged with line offset pointer")
- }
- rangeType = 1
- case PTR_LINE_CHAR_POINTER:
- if rangeType == 1 {
- return fmt.Errorf("byte offset pointer merged with line offset pointer")
- }
- rangeType = 2
- default:
- return fmt.Errorf("illegal pointer type %v", subTriple.Object.ID)
- }
- case PTR_REFERENCE:
- err := parser.parseRangeReference(subTriple.Object, si)
- if err != nil {
- return nil
- }
- case PTR_OFFSET, PTR_LINE_NUMBER:
- start = subTriple.Object.ID
- default:
- return fmt.Errorf("undefined predicate %v while parsing range", subTriple.Predicate.ID)
- }
- }
- case PTR_END_POINTER:
- subTriples := parser.nodeToTriples(t.Object)
- for _, subTriple := range subTriples {
- switch subTriple.Predicate.ID {
- case RDF_TYPE:
- switch subTriple.Object.ID {
- case PTR_BYTE_OFFSET_POINTER:
- if rangeType == 2 {
- return fmt.Errorf("byte offset pointer merged with line offset pointer")
- }
- rangeType = 1
- case PTR_LINE_CHAR_POINTER:
- if rangeType == 1 {
- return fmt.Errorf("byte offset pointer merged with line offset pointer")
- }
- rangeType = 2
- default:
- return fmt.Errorf("illegal pointer type %v", subTriple.Object.ID)
- }
- case PTR_REFERENCE:
- err := parser.parseRangeReference(subTriple.Object, si)
- if err != nil {
- return nil
- }
- case PTR_OFFSET, PTR_LINE_NUMBER:
- end = subTriple.Object.ID
- }
- }
- default:
- return fmt.Errorf("unknown predicate %v", t.Predicate.ID)
- }
+ // for a range object, we can have only 3 associated triples:
+ // node -> RDF_TYPE -> Object
+ // node -> startPointer -> Object
+ // node -> endPointer -> Object
+ associatedTriples := parser.nodeToTriples(node)
+ if len(associatedTriples) != 3 {
+ return fmt.Errorf("range should be associated with exactly 3 triples, got %d", len(associatedTriples))
}
- if rangeType != 1 && rangeType != 2 {
- return fmt.Errorf("undefined range type")
+
+ // Triple 1: Predicate=RDF_TYPE
+ typeTriple := rdfwriter.FilterTriples(associatedTriples, &node.ID, &RDF_TYPE, nil)
+ if len(typeTriple) != 1 {
+ // we had 3 associated triples. out of which 2 is start and end pointer,
+ // if we do not have the rdf:type triple as the third one,
+ // we have either extra or undefined predicate.
+ return fmt.Errorf("every object node must be associated with exactly one rdf:type triple, found: %d", len(typeTriple))
}
- startNumber, err := strconv.Atoi(strings.TrimSpace(start))
+
+ // getting start pointer
+ startPointerTriples := rdfwriter.FilterTriples(associatedTriples, &node.ID, &PTR_START_POINTER, nil)
+ if len(startPointerTriples) != 1 {
+ return fmt.Errorf("range object must be associated with exactly 1 startPointer, got %d", len(startPointerTriples))
+ }
+ startRangeType, start, err := parser.getPointerFromNode(startPointerTriples[0].Object, si)
if err != nil {
- return fmt.Errorf("invalid number for range start: %v", start)
+ return fmt.Errorf("error parsing startPointer: %v", err)
}
- endNumber, err := strconv.Atoi(strings.TrimSpace(end))
+
+ // getting end pointer
+ endPointerTriples := rdfwriter.FilterTriples(associatedTriples, &node.ID, &PTR_END_POINTER, nil)
+ if len(startPointerTriples) != 1 {
+ return fmt.Errorf("range object must be associated with exactly 1 endPointer, got %d", len(endPointerTriples))
+ }
+ endRangeType, end, err := parser.getPointerFromNode(endPointerTriples[0].Object, si)
if err != nil {
- return fmt.Errorf("invalid number for range end: %v", end)
+ return fmt.Errorf("error parsing endPointer: %v", err)
+ }
+
+ // return error when start and end pointer type is not same.
+ if startRangeType != endRangeType {
+ return fmt.Errorf("start and end range type doesn't match")
}
- if rangeType == 1 {
- // byte range
- si.SnippetByteRangeStart = startNumber
- si.SnippetByteRangeEnd = endNumber
+
+ if startRangeType == LINE_RANGE {
+ si.SnippetLineRangeStart = start
+ si.SnippetLineRangeEnd = end
} else {
- // line range
- si.SnippetLineRangeStart = startNumber
- si.SnippetLineRangeEnd = endNumber
+ si.SnippetByteRangeStart = start
+ si.SnippetByteRangeEnd = end
}
return nil
}
+func (parser *rdfParser2_2) getPointerFromNode(node *gordfParser.Node, si *spdx.Snippet2_2) (rt RangeType, number int, err error) {
+ for _, triple := range parser.nodeToTriples(node) {
+ switch triple.Predicate.ID {
+ case RDF_TYPE:
+ case PTR_REFERENCE:
+ err = parser.parseRangeReference(triple.Object, si)
+ case PTR_OFFSET:
+ number, err = strconv.Atoi(triple.Object.ID)
+ rt = BYTE_RANGE
+ case PTR_LINE_NUMBER:
+ number, err = strconv.Atoi(triple.Object.ID)
+ rt = LINE_RANGE
+ default:
+ err = fmt.Errorf("undefined predicate (%s) for a pointer", triple.Predicate)
+ }
+ if err != nil {
+ return
+ }
+ }
+ if rt == "" {
+ err = fmt.Errorf("range type not defined for a pointer")
+ }
+ return
+}
+
func (parser *rdfParser2_2) parseRangeReference(node *gordfParser.Node, snippet *spdx.Snippet2_2) error {
- // reference is supposed to be either a resource reference to a file or a new file
- // Unfortunately, I didn't find field where this can be set in the tools-golang data model.
+ // reference is supposed to be either a resource reference to an already
+ // defined or a new file. Unfortunately, I didn't find field where this can be set in the tools-golang data model.
// todo: set this reference to the snippet
- switch node.NodeType {
- case gordfParser.RESOURCELITERAL, gordfParser.LITERAL, gordfParser.BLANK:
+ associatedTriples := rdfwriter.FilterTriples(parser.gordfParserObj.Triples, &node.ID, nil, nil)
+ if len(associatedTriples) == 0 {
return nil
}
file, err := parser.getFileFromNode(node)
if err != nil {
- return fmt.Errorf("error parsing a new file in a reference")
+ return fmt.Errorf("error parsing a new file in a reference: %v", err)
}
- // a new file found within the pointer reference is an unpackaged file.
- if parser.doc.UnpackagedFiles == nil {
- parser.doc.UnpackagedFiles = map[spdx.ElementID]*spdx.File2_2{}
- }
- parser.doc.UnpackagedFiles[file.FileSPDXIdentifier] = file
+ // setting the file to the parser. We cannot say if it is unpackaged
+ // because it is quite possible that the range references a file which
+ // belongs to another package.
+ parser.files[file.FileSPDXIdentifier] = file
return nil
}
diff --git a/rdfloader/parser2v2/parse_snippet_info_test.go b/rdfloader/parser2v2/parse_snippet_info_test.go
new file mode 100644
index 0000000..71edd10
--- /dev/null
+++ b/rdfloader/parser2v2/parse_snippet_info_test.go
@@ -0,0 +1,532 @@
+package parser2v2
+
+import (
+ gordfParser "github.com/RishabhBhatnagar/gordf/rdfloader/parser"
+ "github.com/spdx/tools-golang/spdx"
+ "testing"
+)
+
+func Test_rdfParser2_2_getSnippetInformationFromTriple2_2(t *testing.T) {
+ var err error
+ var parser *rdfParser2_2
+ var node *gordfParser.Node
+
+ // TestCase 1: invalid snippet id:
+ parser, _ = parserFromBodyContent(`
+ <spdx:Snippet rdf:about="#Snippet">
+ </spdx:Snippet>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getSnippetInformationFromNode2_2(node)
+ if err == nil {
+ t.Errorf("expected an error due to invalid, got %v", err)
+ }
+
+ // TestCase 2: Invalid LicenseInfoInSnippet
+ parser, _ = parserFromBodyContent(`
+ <spdx:Snippet rdf:about="#SPDXRef-Snippet">
+ <spdx:licenseInfoInSnippet rdf:resource="http://spdx.org/licenses/Unknown"/>
+ </spdx:Snippet>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getSnippetInformationFromNode2_2(node)
+ if err == nil {
+ t.Errorf("expected an error due to invalid licenseInfoInSnippet, got %v", err)
+ }
+
+ // TestCase 3: Invalid range.
+ parser, _ = parserFromBodyContent(`
+ <spdx:Snippet rdf:about="#SPDXRef-Snippet">
+ <spdx:range>
+ <spdx:StartEndPointer>
+ <spdx:unknownTag />
+ </spdx:StartEndPointer>
+ </spdx:range>
+ </spdx:Snippet>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getSnippetInformationFromNode2_2(node)
+ if err == nil {
+ t.Errorf("expected an error due to invalid range, got %v", err)
+ }
+
+ // TestCase 3: invalid file in snippetFromFile
+ parser, _ = parserFromBodyContent(`
+ <spdx:Snippet rdf:about="#SPDXRef-Snippet">
+ <spdx:snippetFromFile>
+ <spdx:File rdf:resource="http://anupam-VirtualBox/spdx.rdf#item8" />
+ </spdx:snippetFromFile>
+ </spdx:Snippet>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getSnippetInformationFromNode2_2(node)
+ if err == nil {
+ t.Errorf("expected an error due to invalid snippetFromFile, got %v", err)
+ }
+
+ // TestCase 4: unknown predicate
+ parser, _ = parserFromBodyContent(`
+ <spdx:Snippet rdf:about="#SPDXRef-Snippet">
+ <spdx:unknownPredicate />
+ </spdx:Snippet>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getSnippetInformationFromNode2_2(node)
+ if err == nil {
+ t.Errorf("expected an error due to invalid predicate, got %v", err)
+ }
+
+ // TestCase 5: invalid license concluded:
+ parser, _ = parserFromBodyContent(`
+ <spdx:Snippet rdf:about="#SPDXRef-Snippet">
+ <spdx:licenseConcluded rdf:resource="http://spdx.org/licenses/Unknown"/>
+ </spdx:Snippet>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getSnippetInformationFromNode2_2(node)
+ if err == nil {
+ t.Errorf("expected an error due to invalid licenseConcluded, got %v", err)
+ }
+
+ // TestCase 6: everything valid:
+ parser, _ = parserFromBodyContent(`
+ <spdx:Snippet rdf:about="#SPDXRef-Snippet">
+ <spdx:snippetFromFile>
+ <spdx:File rdf:about="#SPDXRef-File" />
+ </spdx:snippetFromFile>
+ <spdx:range>
+ <j.0:StartEndPointer>
+ <j.0:startPointer>
+ <j.0:LineCharPointer>
+ <j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
+ <j.0:lineNumber>420</j.0:lineNumber>
+ </j.0:LineCharPointer>
+ </j.0:startPointer>
+ <j.0:endPointer>
+ <j.0:LineCharPointer>
+ <j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
+ <j.0:lineNumber>310</j.0:lineNumber>
+ </j.0:LineCharPointer>
+ </j.0:endPointer>
+ </j.0:StartEndPointer>
+ </spdx:range>
+ <spdx:licenseInfoInSnippet rdf:resource="http://spdx.org/rdf/terms#noassertion"/>
+ <spdx:name>snippet test</spdx:name>
+ <spdx:copyrightText>test</spdx:copyrightText>
+ <spdx:licenseComments>comments</spdx:licenseComments>
+ <rdfs:comment>comments</rdfs:comment>
+ <spdx:licenseConcluded rdf:resource="http://spdx.org/rdf/terms#noassertion"/>
+ </spdx:Snippet>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getSnippetInformationFromNode2_2(node)
+ if err != nil {
+ t.Fatalf("error parsing a valid example: %v", err)
+ }
+}
+
+func Test_setSnippetID(t *testing.T) {
+ // TestCase 1: invalid input (empty)
+ err := setSnippetID("", &spdx.Snippet2_2{})
+ if err == nil {
+ t.Errorf("should've raised an error for empty input")
+ }
+
+ // TestCase 2: valid input
+ si := &spdx.Snippet2_2{}
+ err = setSnippetID("http://spdx.org/spdxdocs/spdx-example#SPDXRef-Snippet", si)
+ if err != nil {
+ t.Errorf("unexpected error: %v", err)
+ }
+ if si.SnippetSPDXIdentifier != "Snippet" {
+ t.Errorf("expected: %s, found: %s", "Snippet", si.SnippetSPDXIdentifier)
+ }
+}
+
+func Test_rdfParser2_2_parseRangeReference(t *testing.T) {
+ var err error
+ var node *gordfParser.Node
+ var parser *rdfParser2_2
+ var si *spdx.Snippet2_2
+
+ // TestCase 1: ResourceLiteral node without a new file shouldn't raise any error.
+ si = &spdx.Snippet2_2{}
+ parser, _ = parserFromBodyContent(``)
+ node = &gordfParser.Node{
+ NodeType: gordfParser.RESOURCELITERAL,
+ ID: "http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource",
+ }
+ err = parser.parseRangeReference(node, si)
+ if err != nil {
+ t.Errorf("error parsing a valid node: %v", err)
+ }
+
+ // TestCase 2: invalid file in the reference should raise an error
+ si = &spdx.Snippet2_2{}
+ parser, _ = parserFromBodyContent(`
+ <spdx:File rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#DoapSource">
+ <spdx:fileName> test file </spdx:fileName>
+ </spdx:File>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ err = parser.parseRangeReference(node, si)
+ if err == nil {
+ t.Errorf("expected an error due to invalid file in the range reference, got %v", err)
+ }
+
+ // TestCase 3: A valid reference must set the file to the files map of the parser.
+ si = &spdx.Snippet2_2{}
+ parser, _ = parserFromBodyContent(`
+ <spdx:File rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource">
+ <spdx:fileName> test file </spdx:fileName>
+ </spdx:File>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ err = parser.parseRangeReference(node, si)
+ if err != nil {
+ t.Errorf("error parsing a valid input: %v", err)
+ }
+ if len(parser.files) != 1 {
+ t.Errorf("expected parser.files to have 1 file, found %d", len(parser.files))
+ }
+}
+
+func Test_rdfParser2_2_getPointerFromNode(t *testing.T) {
+ var parser *rdfParser2_2
+ var node *gordfParser.Node
+ var si *spdx.Snippet2_2
+ var err error
+ var rt RangeType
+ var number int
+
+ // TestCase 1: invalid number in the offset field must raise an error.
+ parser, _ = parserFromBodyContent(`
+ <j.0:startPointer>
+ <j.0:LineCharPointer>
+ <j.0:reference rdf:resource="#SPDXRef-DoapSource"/>
+ <j.0:offset>3-10</j.0:offset>
+ </j.0:LineCharPointer>
+ </j.0:startPointer>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, _, err = parser.getPointerFromNode(node, si)
+ if err == nil {
+ t.Errorf("should've raised an error parsing invalid offset, got %v", err)
+ }
+
+ // TestCase 2: invalid number in the lineNumber field must raise an error.
+ parser, _ = parserFromBodyContent(`
+ <j.0:ByteOffsetPointer>
+ <j.0:reference rdf:resource="#SPDXRef-DoapSource"/>
+ <j.0:offset>3-10</j.0:offset>
+ </j.0:ByteOffsetPointer>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, _, err = parser.getPointerFromNode(node, si)
+ if err == nil {
+ t.Errorf("should've raised an error parsing invalid offset, got %v", err)
+ }
+
+ // TestCase 3: invalid predicate in the pointer field
+ parser, _ = parserFromBodyContent(`
+ <j.0:ByteOffsetPointer>
+ <spdx:invalidTag />
+ <j.0:reference rdf:resource="#SPDXRef-DoapSource"/>
+ <j.0:lineNumber>3-10</j.0:lineNumber>
+ </j.0:ByteOffsetPointer>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, _, err = parser.getPointerFromNode(node, si)
+ if err == nil {
+ t.Errorf("should've raised an error parsing invalid predicate, got %v", err)
+ }
+
+ // TestCase 4: No range type defined must also raise an error
+ parser, _ = parserFromBodyContent(`
+ <j.0:ByteOffsetPointer>
+ <j.0:reference rdf:resource="#SPDXRef-DoapSource"/>
+ </j.0:ByteOffsetPointer>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, _, err = parser.getPointerFromNode(node, si)
+ if err == nil {
+ t.Errorf("should've raised an error parsing invalid rangeType, got %v", err)
+ }
+
+ // TestCase 5: valid example
+ parser, _ = parserFromBodyContent(`
+ <j.0:ByteOffsetPointer>
+ <j.0:reference rdf:resource="#SPDXRef-DoapSource"/>
+ <j.0:offset>310</j.0:offset>
+ </j.0:ByteOffsetPointer>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ rt, number, err = parser.getPointerFromNode(node, si)
+ if err != nil {
+ t.Fatalf("unexpected error parsing a valid node: %v", err)
+ }
+ if rt != BYTE_RANGE {
+ t.Errorf("expected: %s, got: %s", BYTE_RANGE, rt)
+ }
+ if number != 310 {
+ t.Errorf("expected: %d, got: %d", 310, number)
+ }
+}
+
+func Test_rdfParser2_2_setSnippetRangeFromNode(t *testing.T) {
+ var parser *rdfParser2_2
+ var err error
+ var si *spdx.Snippet2_2
+ var node *gordfParser.Node
+
+ // TestCase 1: range with less one pointer less must raise an error
+ // (end-pointer missing in the range)
+ parser, _ = parserFromBodyContent(`
+ <j.0:StartEndPointer>
+ <j.0:startPointer>
+ <j.0:LineCharPointer>
+ <j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
+ <j.0:offset>310</j.0:offset>
+ </j.0:LineCharPointer>
+ </j.0:startPointer>
+ </j.0:StartEndPointer>
+
+ `)
+ si = &spdx.Snippet2_2{}
+ node = parser.gordfParserObj.Triples[0].Subject
+ err = parser.setSnippetRangeFromNode(node, si)
+ if err == nil {
+ t.Errorf("expected an error due to missing end pointer, got %v", err)
+ }
+
+ // TestCase 2: triples with 0 or more than one type-triple
+ parser, _ = parserFromBodyContent(`
+
+ <j.0:StartEndPointer>
+ <j.0:endPointer>
+ <j.0:ByteOffsetPointer>
+ <j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
+ <j.0:offset>420</j.0:offset>
+ </j.0:ByteOffsetPointer>
+ </j.0:endPointer>
+ <j.0:startPointer>
+ <j.0:ByteOffsetPointer>
+ <j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
+ <j.0:offset>310</j.0:offset>
+ </j.0:ByteOffsetPointer>
+ </j.0:startPointer>
+ </j.0:StartEndPointer>
+
+ `)
+ si = &spdx.Snippet2_2{}
+ node = parser.gordfParserObj.Triples[0].Subject
+ dummyTriple := parser.gordfParserObj.Triples[0]
+ // resetting the node to be associated with 3 triples which will have
+ // rdf:type triple either thrice or 0 times.
+ parser.nodeStringToTriples[node.String()] = []*gordfParser.Triple{
+ dummyTriple, dummyTriple, dummyTriple,
+ }
+ err = parser.setSnippetRangeFromNode(node, si)
+ if err == nil {
+ t.Errorf("expected an error due to invalid rdf:type triples, got %v", err)
+ }
+
+ // TestCase 3: triples with 0 startPointer
+ parser, _ = parserFromBodyContent(`
+ <j.0:StartEndPointer>
+ <j.0:endPointer>
+ <j.0:ByteOffsetPointer>
+ <j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
+ <j.0:offset>420</j.0:offset>
+ </j.0:ByteOffsetPointer>
+ </j.0:endPointer>
+ <j.0:endPointer>
+ <j.0:LineCharPointer>
+ <j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
+ <j.0:offset>310</j.0:offset>
+ </j.0:LineCharPointer>
+ </j.0:endPointer>
+ </j.0:StartEndPointer>
+ `)
+ si = &spdx.Snippet2_2{}
+ node = parser.gordfParserObj.Triples[0].Subject
+ err = parser.setSnippetRangeFromNode(node, si)
+ if err == nil {
+ t.Errorf("expected an error due to missing start pointer, got %v", err)
+ }
+
+ // TestCase 4: triples with 0 endPointer
+ parser, _ = parserFromBodyContent(`
+ <j.0:StartEndPointer>
+ <j.0:endPointer>
+ <j.0:ByteOffsetPointer>
+ <j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
+ <j.0:offset>420</j.0:offset>
+ </j.0:ByteOffsetPointer>
+ </j.0:endPointer>
+ <j.0:endPointer>
+ <j.0:LineCharPointer>
+ <j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
+ <j.0:offset>310</j.0:offset>
+ </j.0:LineCharPointer>
+ </j.0:endPointer>
+ </j.0:StartEndPointer>
+ `)
+ si = &spdx.Snippet2_2{}
+ node = parser.gordfParserObj.Triples[0].Subject
+ err = parser.setSnippetRangeFromNode(node, si)
+ if err == nil {
+ t.Errorf("expected an error due to missing end pointer, got %v", err)
+ }
+
+ // TestCase 5: error parsing start pointer must be propagated to the range
+ parser, _ = parserFromBodyContent(`
+ <j.0:StartEndPointer>
+ <j.0:startPointer>
+ <j.0:ByteOffsetPointer>
+ <j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
+ <j.0:offset>42.0</j.0:offset>
+ </j.0:ByteOffsetPointer>
+ </j.0:startPointer>
+ <j.0:endPointer>
+ <j.0:ByteOffsetPointer>
+ <j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
+ <j.0:offset>310</j.0:offset>
+ </j.0:ByteOffsetPointer>
+ </j.0:endPointer>
+ </j.0:StartEndPointer>
+ `)
+ si = &spdx.Snippet2_2{}
+ node = parser.gordfParserObj.Triples[0].Subject
+ err = parser.setSnippetRangeFromNode(node, si)
+ if err == nil {
+ t.Errorf("expected an error due to invalid start pointer, got %v", err)
+ }
+
+ // TestCase 6: error parsing end pointer must be propagated to the range
+ parser, _ = parserFromBodyContent(`
+ <j.0:StartEndPointer>
+ <j.0:startPointer>
+ <j.0:ByteOffsetPointer>
+ <j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
+ <j.0:offset>420</j.0:offset>
+ </j.0:ByteOffsetPointer>
+ </j.0:startPointer>
+ <j.0:endPointer>
+ <j.0:ByteOffsetPointer>
+ <j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
+ <j.0:offset>31+0</j.0:offset>
+ </j.0:ByteOffsetPointer>
+ </j.0:endPointer>
+ </j.0:StartEndPointer>
+ `)
+ si = &spdx.Snippet2_2{}
+ node = parser.gordfParserObj.Triples[0].Subject
+ err = parser.setSnippetRangeFromNode(node, si)
+ if err == nil {
+ t.Errorf("expected an error due to invalid end pointer, got %v", err)
+ }
+
+ // TestCase 7: mismatching start and end pointer must also raise an error.
+ parser, _ = parserFromBodyContent(`
+ <j.0:StartEndPointer>
+ <j.0:startPointer>
+ <j.0:ByteOffsetPointer>
+ <j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
+ <j.0:offset>420</j.0:offset>
+ </j.0:ByteOffsetPointer>
+ </j.0:startPointer>
+ <j.0:endPointer>
+ <j.0:LineCharPointer>
+ <j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
+ <j.0:lineNumber>310</j.0:lineNumber>
+ </j.0:LineCharPointer>
+ </j.0:endPointer>
+ </j.0:StartEndPointer>
+ `)
+ si = &spdx.Snippet2_2{}
+ node = parser.gordfParserObj.Triples[0].Subject
+ err = parser.setSnippetRangeFromNode(node, si)
+ if err == nil {
+ t.Errorf("expected an error due to mismatching start and end pointers, got %v", err)
+ }
+
+ // TestCase 8: everything valid(byte_range):
+ parser, _ = parserFromBodyContent(`
+ <j.0:StartEndPointer>
+ <j.0:startPointer>
+ <j.0:ByteOffsetPointer>
+ <j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
+ <j.0:offset>420</j.0:offset>
+ </j.0:ByteOffsetPointer>
+ </j.0:startPointer>
+ <j.0:endPointer>
+ <j.0:ByteOffsetPointer>
+ <j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
+ <j.0:offset>310</j.0:offset>
+ </j.0:ByteOffsetPointer>
+ </j.0:endPointer>
+ </j.0:StartEndPointer>
+ `)
+ si = &spdx.Snippet2_2{}
+ node = parser.gordfParserObj.Triples[0].Subject
+ err = parser.setSnippetRangeFromNode(node, si)
+ if err != nil {
+ t.Errorf("unexpected error: %v", err)
+ }
+
+ // TestCase 9: everything valid(line_range):
+ parser, _ = parserFromBodyContent(`
+ <j.0:StartEndPointer>
+ <j.0:startPointer>
+ <j.0:LineCharPointer>
+ <j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
+ <j.0:lineNumber>420</j.0:lineNumber>
+ </j.0:LineCharPointer>
+ </j.0:startPointer>
+ <j.0:endPointer>
+ <j.0:LineCharPointer>
+ <j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
+ <j.0:lineNumber>310</j.0:lineNumber>
+ </j.0:LineCharPointer>
+ </j.0:endPointer>
+ </j.0:StartEndPointer>
+ `)
+ si = &spdx.Snippet2_2{}
+ node = parser.gordfParserObj.Triples[0].Subject
+ err = parser.setSnippetRangeFromNode(node, si)
+ if err != nil {
+ t.Errorf("unexpected error: %v", err)
+ }
+}
+
+func Test_rdfParser2_2_setSnippetToFileWithID(t *testing.T) {
+ var parser *rdfParser2_2
+ var fileId spdx.ElementID
+ var si *spdx.Snippet2_2
+ var file *spdx.File2_2
+ var err error
+
+ // TestCase 1: file id which is not associated with any file must raise an error.
+ parser, _ = parserFromBodyContent("")
+ si = &spdx.Snippet2_2{}
+ err = parser.setSnippetToFileWithID(si, fileId)
+ if err == nil {
+ t.Errorf("expected an error saying undefined file")
+ }
+
+ // TestCase 2: file exists, but snippet of the file doesn't ( it mustn't raise any error )
+ fileId = spdx.ElementID("File1")
+ file = &spdx.File2_2{
+ FileSPDXIdentifier: fileId,
+ }
+ parser.files[fileId] = file
+ file.Snippets = nil // nil snippets
+ err = parser.setSnippetToFileWithID(si, fileId)
+ if err != nil {
+ t.Errorf("unexpected error: %v", err)
+ }
+ if len(file.Snippets) != 1 {
+ t.Errorf("expected file to have 1 snippet, got %d", len(file.Snippets))
+ }
+}
diff --git a/rdfloader/parser2v2/parse_spdx_document.go b/rdfloader/parser2v2/parse_spdx_document.go
index 8371b0f..8ce7ded 100644
--- a/rdfloader/parser2v2/parse_spdx_document.go
+++ b/rdfloader/parser2v2/parse_spdx_document.go
@@ -9,7 +9,7 @@ import (
)
func (parser *rdfParser2_2) parseSpdxDocumentNode(spdxDocNode *gordfParser.Node) (err error) {
- // create a new creation info
+ // shorthand for document's creation info.
ci := parser.doc.CreationInfo
// parse the document header information (SPDXID and document namespace)
@@ -25,6 +25,8 @@ func (parser *rdfParser2_2) parseSpdxDocumentNode(spdxDocNode *gordfParser.Node)
for _, subTriple := range parser.nodeToTriples(spdxDocNode) {
objectValue := subTriple.Object.ID
switch subTriple.Predicate.ID {
+ case RDF_TYPE:
+ continue
case SPDX_SPEC_VERSION: // 2.1: specVersion
// cardinality: exactly 1
ci.SPDXVersion = objectValue
@@ -41,7 +43,7 @@ func (parser *rdfParser2_2) parseSpdxDocumentNode(spdxDocNode *gordfParser.Node)
case SPDX_EXTERNAL_DOCUMENT_REF: // 2.6: externalDocumentReferences
// cardinality: min 0
var extRef string
- extRef, err = parser.getExternalDocumentRefFromTriples(parser.nodeToTriples(subTriple.Object))
+ extRef, err = parser.getExternalDocumentRefFromNode(subTriple.Object)
ci.ExternalDocumentReferences = append(ci.ExternalDocumentReferences, extRef)
case SPDX_CREATION_INFO: // 2.7 - 2.10:
// cardinality: exactly 1
@@ -74,22 +76,20 @@ func (parser *rdfParser2_2) parseSpdxDocumentNode(spdxDocNode *gordfParser.Node)
case SPDX_ANNOTATION: // annotations
// cardinality: min 0
err = parser.parseAnnotationFromNode(subTriple.Object)
+ default:
+ return fmt.Errorf("invalid predicate while parsing SpdxDocument: %v", subTriple.Predicate)
}
if err != nil {
return err
}
}
-
- // control reaches here iff no error is encountered
- // set the ci if no error is encountered while parsing triples.
- parser.doc.CreationInfo = ci
return nil
}
-func (parser *rdfParser2_2) getExternalDocumentRefFromTriples(triples []*gordfParser.Triple) (string, error) {
+func (parser *rdfParser2_2) getExternalDocumentRefFromNode(node *gordfParser.Node) (string, error) {
var docID, checksumValue, checksumAlgorithm, spdxDocument string
var err error
- for _, triple := range triples {
+ for _, triple := range parser.nodeToTriples(node) {
switch triple.Predicate.ID {
case SPDX_EXTERNAL_DOCUMENT_ID:
// cardinality: exactly 1
diff --git a/rdfloader/parser2v2/parse_spdx_document_test.go b/rdfloader/parser2v2/parse_spdx_document_test.go
new file mode 100644
index 0000000..7372ef0
--- /dev/null
+++ b/rdfloader/parser2v2/parse_spdx_document_test.go
@@ -0,0 +1,238 @@
+package parser2v2
+
+import (
+ gordfParser "github.com/RishabhBhatnagar/gordf/rdfloader/parser"
+ "testing"
+)
+
+func Test_rdfParser2_2_getExternalDocumentRefFromNode(t *testing.T) {
+ var parser *rdfParser2_2
+ var node *gordfParser.Node
+ var err error
+
+ // TestCase 1: invalid checksum
+ parser, _ = parserFromBodyContent(`
+ <spdx:ExternalDocumentRef>
+ <spdx:externalDocumentId>DocumentRef-spdx-tool-1.2</spdx:externalDocumentId>
+ <spdx:checksum>
+ <spdx:Checksum>
+ <spdx:checksumValue>d6a770ba38583ed4bb4525bd96e50461655d2759</spdx:checksumValue>
+ <spdx:algorithm rdf:resource="http://spdx.org/rdf/terms#checksumAlgorithm_sha999"/>
+ </spdx:Checksum>
+ </spdx:checksum>
+ <spdx:spdxDocument rdf:resource="http://spdx.org/spdxdocs/spdx-tools-v1.2-3F2504E0-4F89-41D3-9A0C-0305E82C3301"/>
+ </spdx:ExternalDocumentRef>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getExternalDocumentRefFromNode(node)
+ if err == nil {
+ t.Errorf("expected an error due to invalid checksum, found %v", err)
+ }
+
+ // TestCase 2: unknown predicate
+ parser, _ = parserFromBodyContent(`
+ <spdx:ExternalDocumentRef>
+ <spdx:unknownTag />
+ </spdx:ExternalDocumentRef>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getExternalDocumentRefFromNode(node)
+ if err == nil {
+ t.Errorf("expected an error due to invalid predicate, found %v", err)
+ }
+
+ // TestCase 3: valid example
+ parser, _ = parserFromBodyContent(`
+ <spdx:ExternalDocumentRef>
+ <spdx:externalDocumentId>DocumentRef-spdx-tool-1.2</spdx:externalDocumentId>
+ <spdx:checksum>
+ <spdx:Checksum>
+ <spdx:checksumValue>d6a770ba38583ed4bb4525bd96e50461655d2759</spdx:checksumValue>
+ <spdx:algorithm rdf:resource="http://spdx.org/rdf/terms#checksumAlgorithm_sha256"/>
+ </spdx:Checksum>
+ </spdx:checksum>
+ <spdx:spdxDocument rdf:resource="http://spdx.org/spdxdocs/spdx-tools-v1.2-3F2504E0-4F89-41D3-9A0C-0305E82C3301"/>
+ </spdx:ExternalDocumentRef>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getExternalDocumentRefFromNode(node)
+ if err != nil {
+ t.Errorf("unexpected error: %v", err)
+ }
+}
+
+func Test_rdfParser2_2_parseSpdxDocumentNode(t *testing.T) {
+ var parser *rdfParser2_2
+ var node *gordfParser.Node
+ var err error
+
+ // TestCase 1: invalid spdx id of the document
+ parser, _ = parserFromBodyContent(`
+ <spdx:SpdxDocument rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301/Document"/>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ err = parser.parseSpdxDocumentNode(node)
+ if err == nil {
+ t.Errorf("expected an error due to invalid document id, got %v", err)
+ }
+
+ // TestCase 2: erroneous dataLicense
+ parser, _ = parserFromBodyContent(`
+ <spdx:SpdxDocument rdf:about="#SPDXRef-Document">
+ <spdx:dataLicense rdf:resource="http://spdx.org/rdf/terms#Unknown" />
+ </spdx:SpdxDocument>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ err = parser.parseSpdxDocumentNode(node)
+ if err == nil {
+ t.Errorf("expected an error due to invalid dataLicense, got %v", err)
+ }
+
+ // TestCase 3: invalid external document ref
+ parser, _ = parserFromBodyContent(`
+ <spdx:SpdxDocument rdf:about="#SPDXRef-Document">
+ <spdx:externalDocumentRef>
+ <spdx:ExternalDocumentRef>
+ <spdx:externalDocumentId>DocumentRef-spdx-tool-1.2</spdx:externalDocumentId>
+ <spdx:checksum>
+ <spdx:Checksum>
+ <spdx:checksumValue>d6a770ba38583ed4bb4525bd96e50461655d2759</spdx:checksumValue>
+ <spdx:algorithm rdf:resource="http://spdx.org/rdf/terms#checksumAlgorithm_sha999"/>
+ </spdx:Checksum>
+ </spdx:checksum>
+ <spdx:spdxDocument rdf:resource="http://spdx.org/spdxdocs/spdx-tools-v1.2-3F2504E0-4F89-41D3-9A0C-0305E82C3301"/>
+ </spdx:ExternalDocumentRef>
+ </spdx:externalDocumentRef>
+ </spdx:SpdxDocument>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ err = parser.parseSpdxDocumentNode(node)
+ if err == nil {
+ t.Errorf("expected an error due to invalid externalDocumentRef, got %v", err)
+ }
+
+ // TestCase 4: invalid package
+ parser, _ = parserFromBodyContent(`
+ <spdx:SpdxDocument rdf:about="#SPDXRef-Document">
+ <spdx:describesPackage>
+ <spdx:Package rdf:about="http://www.spdx.org/spdxdocs/8f141b09-1138-4fc5-aecb-fc10d9ac1eed#SPDX-1"/>
+ </spdx:describesPackage>
+ </spdx:SpdxDocument>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ err = parser.parseSpdxDocumentNode(node)
+ if err == nil {
+ t.Errorf("expected an error due to invalid externalDocumentRef, got %v", err)
+ }
+
+ // TestCase 5: error in extractedLicensingInfo
+ parser, _ = parserFromBodyContent(`
+ <spdx:SpdxDocument rdf:about="#SPDXRef-Document">
+ <spdx:hasExtractedLicensingInfo>
+ <spdx:ExtractedLicensingInfo rdf:about="#LicenseRef-Freeware">
+ <spdx:invalidTag />
+ <spdx:licenseId>LicenseRef-Freeware</spdx:licenseId>
+ <spdx:name>freeware</spdx:name>
+ <spdx:extractedText>
+<![CDATA[Software classified as freeware is licensed at no cost and is either fully functional for an unlimited time; or has only basic functions enabled with a fully functional version available commercially or as shareware.[8] In contrast to free software, the author usually restricts one or more rights of the user, including the rights to use, copy, distribute, modify and make derivative works of the software or extract the source code.[1][2][9][10] The software license may impose various additional restrictions on the type of use, e.g. only for personal use, private use, individual use, non-profit use, non-commercial use, academic use, educational use, use in charity or humanitarian organizations, non-military use, use by public authorities or various other combinations of these type of restrictions.[11] For instance, the license may be "free for private, non-commercial use". The software license may also impose various other restrictions, such as restricted use over a network, restricted use on a server, restricted use in a combination with some types of other software or with some hardware devices, prohibited distribution over the Internet other than linking to author's website, restricted distribution without author's consent, restricted number of copies, etc.]]>
+ </spdx:extractedText>
+ </spdx:ExtractedLicensingInfo>
+ </spdx:hasExtractedLicensingInfo>
+ </spdx:SpdxDocument>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ err = parser.parseSpdxDocumentNode(node)
+ if err == nil {
+ t.Errorf("expected an error due to invalid extractedLicensingInfo, got %v", err)
+ }
+
+ // TestCase 6: error in annotation
+ parser, _ = parserFromBodyContent(`
+ <spdx:SpdxDocument rdf:about="#SPDXRef-Document">
+ <spdx:annotation>
+ <spdx:Annotation>
+ <spdx:unknownAttribute />
+ </spdx:Annotation>
+ </spdx:annotation>
+ </spdx:SpdxDocument>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ err = parser.parseSpdxDocumentNode(node)
+ if err == nil {
+ t.Errorf("expected an error due to invalid extractedLicensingInfo, got %v", err)
+ }
+
+ // TestCase 7: invalid predicate
+ parser, _ = parserFromBodyContent(`
+ <spdx:SpdxDocument rdf:about="#SPDXRef-Document">
+ <spdx:unknownTag />
+ </spdx:SpdxDocument>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ err = parser.parseSpdxDocumentNode(node)
+ if err == nil {
+ t.Errorf("expected an error due to unknown predicate, got %v", err)
+ }
+
+ // TestCase 7: everything valid
+ parser, _ = parserFromBodyContent(`
+ <spdx:SpdxDocument rdf:about="#SPDXRef-Document">
+ <spdx:specVersion>SPDX-2.1</spdx:specVersion>
+ <spdx:dataLicense rdf:resource="http://spdx.org/licenses/CC0-1.0" />
+ <spdx:name>/test/example</spdx:name>
+ <spdx:externalDocumentRef>
+ <spdx:ExternalDocumentRef>
+ <spdx:externalDocumentId>DocumentRef-spdx-tool-1.2</spdx:externalDocumentId>
+ <spdx:checksum>
+ <spdx:Checksum>
+ <spdx:checksumValue>d6a770ba38583ed4bb4525bd96e50461655d2759</spdx:checksumValue>
+ <spdx:algorithm rdf:resource="http://spdx.org/rdf/terms#checksumAlgorithm_sha1"/>
+ </spdx:Checksum>
+ </spdx:checksum>
+ <spdx:spdxDocument rdf:resource="http://spdx.org/spdxdocs/spdx-tools-v1.2-3F2504E0-4F89-41D3-9A0C-0305E82C3301"/>
+ </spdx:ExternalDocumentRef>
+ </spdx:externalDocumentRef>
+ <spdx:creationInfo>
+ <spdx:CreationInfo>
+ <spdx:licenseListVersion>2.6</spdx:licenseListVersion>
+ <spdx:creator>Person: spdx (y)</spdx:creator>
+ <spdx:creator>Organization: </spdx:creator>
+ <spdx:creator>Tool: spdx2</spdx:creator>
+ <spdx:created>2018-08-24T19:55:34Z</spdx:created>
+ </spdx:CreationInfo>
+ </spdx:creationInfo>
+ <rdfs:comment>test</rdfs:comment>
+ <spdx:reviewed>
+ <spdx:Review>
+ <rdfs:comment>Another example reviewer.</rdfs:comment>
+ <spdx:reviewDate>2011-03-13T00:00:00Z</spdx:reviewDate>
+ <spdx:reviewer>Person: Suzanne Reviewer</spdx:reviewer>
+ </spdx:Review>
+ </spdx:reviewed>
+ <spdx:describesPackage>
+ <spdx:Package rdf:about="#SPDXRef-1"/>
+ </spdx:describesPackage>
+ <spdx:hasExtractedLicensingInfo rdf:resource="http://spdx.org/licenses/CC0-1.0"/>
+ <spdx:relationship>
+ <spdx:Relationship>
+ <spdx:relationshipType rdf:resource="http://spdx.org/rdf/terms#relationshipType_containedBy"/>
+ <spdx:relatedSpdxElement rdf:resource="http://spdx.org/documents/spdx-toolsv2.1.7-SNAPSHOT#SPDXRef-1"/>
+ <rdfs:comment></rdfs:comment>
+ </spdx:Relationship>
+ </spdx:relationship>
+ <spdx:annotation>
+ <spdx:Annotation>
+ <spdx:annotationDate>2011-01-29T18:30:22Z</spdx:annotationDate>
+ <rdfs:comment>test annotation</rdfs:comment>
+ <spdx:annotator>Person: Rishabh Bhatnagar</spdx:annotator>
+ <spdx:annotationType rdf:resource="http://spdx.org/rdf/terms#annotationType_other"/>
+ </spdx:Annotation>
+ </spdx:annotation>
+ </spdx:SpdxDocument>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ err = parser.parseSpdxDocumentNode(node)
+ if err != nil {
+ t.Errorf("unexpected error: %v", err)
+ }
+}
diff --git a/rdfloader/parser2v2/parser.go b/rdfloader/parser2v2/parser.go
index dd50f13..34f5b3a 100644
--- a/rdfloader/parser2v2/parser.go
+++ b/rdfloader/parser2v2/parser.go
@@ -3,6 +3,7 @@
package parser2v2
import (
+ "errors"
"fmt"
gordfParser "github.com/RishabhBhatnagar/gordf/rdfloader/parser"
gordfWriter "github.com/RishabhBhatnagar/gordf/rdfwriter"
@@ -59,9 +60,9 @@ func LoadFromGoRDFParser(gordfParserObj *gordfParser.Parser) (*spdx.Document2_2,
case SPDX_SPDX_DOCUMENT_CAPITALIZED:
continue // it is already parsed.
case SPDX_SNIPPET:
- snippet, err := parser.getSnippetInformationFromTriple2_2(typeTriples[0])
+ snippet, err := parser.getSnippetInformationFromNode2_2(typeTriples[0].Subject)
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("error parsing a snippet: %v", err)
}
err = parser.setSnippetToFileWithID(snippet, snippet.SnippetFromFileSPDXIdentifier.ElementRefID)
if err != nil {
@@ -105,12 +106,16 @@ func (parser *rdfParser2_2) getSpdxDocNode() (node *gordfParser.Node, err error)
&RDF_TYPE, // Predicate
nil, // Object
)
- if len(typeTriples) != 1 {
- return nil, fmt.Errorf("rootNode (%v) must be associated with exactly one"+
- " triple of predicate rdf:type, found %d triples", rootNode, len(typeTriples))
- }
+
if typeTriples[0].Object.ID == SPDX_SPDX_DOCUMENT_CAPITALIZED {
// we found a SpdxDocument Node
+
+ // must be associated with exactly one rdf:type.
+ if len(typeTriples) != 1 {
+ return nil, fmt.Errorf("rootNode (%v) must be associated with exactly one"+
+ " triple of predicate rdf:type, found %d triples", rootNode, len(typeTriples))
+ }
+
// checking if we've already found a node and it is not same as the current one.
if spdxDocNode != nil && spdxDocNode.ID != typeTriples[0].Subject.ID {
return nil, fmt.Errorf("found more than one SpdxDocument Node (%v and %v)", spdxDocNode, typeTriples[0].Subject)
@@ -119,7 +124,7 @@ func (parser *rdfParser2_2) getSpdxDocNode() (node *gordfParser.Node, err error)
}
}
if spdxDocNode == nil {
- return nil, fmt.Errorf("RDF files must be associated with a SpdxDocument tag. No tag found")
+ return nil, errors.New("RDF files must be associated with a SpdxDocument tag. No tag found")
}
return spdxDocNode, nil
}
diff --git a/rdfloader/parser2v2/parser_test.go b/rdfloader/parser2v2/parser_test.go
new file mode 100644
index 0000000..cefbe2a
--- /dev/null
+++ b/rdfloader/parser2v2/parser_test.go
@@ -0,0 +1,161 @@
+package parser2v2
+
+import (
+ "testing"
+)
+
+func TestNewParser2_2(t *testing.T) {
+ // testing if the attributes are initialised well and no top-level is left uninitialized.
+ // primarily, checking if all the maps are initialized because
+ // uninitialized slices are by default slices of length 0
+ p, _ := parserFromBodyContent(``)
+ parser := NewParser2_2(p.gordfParserObj, p.nodeStringToTriples)
+ if parser.files == nil {
+ t.Errorf("files should've been initialised, got %v", parser.files)
+ }
+ if parser.packages == nil {
+ t.Errorf("packages should've been initialised, got %v", parser.packages)
+ }
+ if parser.assocWithPackage == nil {
+ t.Errorf("assocWithPackage should've been initialised, got %v", parser.assocWithPackage)
+ }
+ if parser.doc.CreationInfo == nil {
+ t.Errorf("doc.CreationInfo should've been initialised, got %v", parser.doc.CreationInfo)
+ }
+ if parser.doc.Packages == nil {
+ t.Errorf("doc.Packages should've been initialised, got %v", parser.doc.Packages)
+ }
+ if parser.doc.UnpackagedFiles == nil {
+ t.Errorf("doc.UnpackagedFiles should've been initialised, got %v", parser.doc.UnpackagedFiles)
+ }
+}
+
+func TestLoadFromGoRDFParser(t *testing.T) {
+ var parser *rdfParser2_2
+ var err error
+
+ // TestCase 1: gordfparser without a SpdxDocument node triple:
+ parser, _ = parserFromBodyContent("")
+ _, err = LoadFromGoRDFParser(parser.gordfParserObj)
+ if err == nil {
+ t.Errorf("expected an error because of absence of SpdxDocument node, got %v", err)
+ }
+
+ // TestCase 2: invalid SpdxDocumentNode
+ parser, _ = parserFromBodyContent(`
+ <spdx:SpdxDocument rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301/Document">
+ <spdx:invalidTag />
+ </spdx:SpdxDocument>
+ `)
+ _, err = LoadFromGoRDFParser(parser.gordfParserObj)
+ if err == nil {
+ t.Errorf("expected an error because of absence of SpdxDocument node, got %v", err)
+ }
+
+ // TestCase 3: >1 type triples for subnode of a SpdxDocument:
+ parser, _ = parserFromBodyContent(`
+ <spdx:SpdxDocument rdf:about="#SPDXRef-Document"/>
+ <spdx:Snippet rdf:about="#Snippet"/>
+ <spdx:CreationInfo rdf:about="#Snippet"/>
+ `)
+ _, err = LoadFromGoRDFParser(parser.gordfParserObj)
+ if err == nil {
+ t.Errorf("expected an error due to more than one type triples, got %v", err)
+ }
+
+ // TestCase 4: invalid snippet must raise an error.
+ parser, _ = parserFromBodyContent(`
+ <spdx:SpdxDocument rdf:about="#SPDXRef-Document"/>
+ <spdx:Snippet rdf:about="#Snippet"/>
+ `)
+ _, err = LoadFromGoRDFParser(parser.gordfParserObj)
+ if err == nil {
+ t.Errorf("expected an error due to invalid Snippet, got %v", err)
+ }
+
+ // TestCase 5: invalid snippet not associated with any File must raise an error.
+ parser, _ = parserFromBodyContent(`
+ <spdx:SpdxDocument rdf:about="#SPDXRef-Document"/>
+ <spdx:Snippet rdf:about="#SPDXRef-Snippet"/>
+ `)
+ _, err = LoadFromGoRDFParser(parser.gordfParserObj)
+ if err == nil {
+ t.Errorf("expected an error due to invalid Snippet File, got %v", err)
+ }
+
+ // TestCase 6: other Tag alongwith the SpdxDocument node mustn't raise any error.
+ parser, _ = parserFromBodyContent(`
+ <spdx:SpdxDocument rdf:about="#SPDXRef-Document"/>
+ <spdx:review/>
+ `)
+ _, err = LoadFromGoRDFParser(parser.gordfParserObj)
+ if err != nil {
+ t.Errorf("unexpected error: %v", err)
+ }
+
+ // TestCase 5: everything valid:
+ parser, _ = parserFromBodyContent(`
+ <spdx:SpdxDocument rdf:about="#SPDXRef-Document"/>
+ <spdx:Snippet rdf:about="#SPDXRef-Snippet">
+ <spdx:name>from linux kernel</spdx:name>
+ <spdx:copyrightText>Copyright 2008-2010 John Smith</spdx:copyrightText>
+ <spdx:licenseComments>The concluded license was taken from package xyz, from which the snippet was copied into the current file. The concluded license information was found in the COPYING.txt file in package xyz.</spdx:licenseComments>
+ <spdx:snippetFromFile>
+ <spdx:File rdf:about="#SPDXRef-DoapSource">
+ <spdx:copyrightText>Copyright 2010, 2011 Source Auditor Inc.</spdx:copyrightText>
+ <spdx:fileContributor>Open Logic Inc.</spdx:fileContributor>
+ <spdx:fileName>./src/org/spdx/parser/DOAPProject.java</spdx:fileName>
+ <spdx:fileContributor>Black Duck Software In.c</spdx:fileContributor>
+ <spdx:fileType rdf:resource="http://spdx.org/rdf/terms#fileType_source"/>
+ <spdx:licenseInfoInFile rdf:resource="http://spdx.org/licenses/Apache-2.0"/>
+ </spdx:File>
+ </spdx:snippetFromFile>
+ </spdx:Snippet>
+ `)
+ _, err = LoadFromGoRDFParser(parser.gordfParserObj)
+ if err != nil {
+ t.Errorf("error parsing a valid example: %v", err)
+ }
+}
+
+func Test_rdfParser2_2_getSpdxDocNode(t *testing.T) {
+ var parser *rdfParser2_2
+ var err error
+
+ // TestCase 1: more than one association type for a single node.
+ parser, _ = parserFromBodyContent(`
+ <spdx:SpdxDocument rdf:about="#SPDXRef-Document"/>
+ <spdx:Snippet rdf:about="#SPDXRef-Document"/>
+ `)
+ _, err = parser.getSpdxDocNode()
+ t.Log(err)
+ if err == nil {
+ t.Errorf("expected and error due to more than one type triples for the SpdxDocument Node, got %v", err)
+ }
+
+ // TestCase 2: two different spdx nodes found in a single document.
+ parser, _ = parserFromBodyContent(`
+ <spdx:SpdxDocument rdf:about="#SPDXRef-Document-1"/>
+ <spdx:SpdxDocument rdf:about="#SPDXRef-Document-2"/>
+ `)
+ _, err = parser.getSpdxDocNode()
+ if err == nil {
+ t.Errorf("expected and error due to more than one type SpdxDocument Node, got %v", err)
+ }
+
+ // TestCase 3: no spdx document
+ parser, _ = parserFromBodyContent(``)
+ _, err = parser.getSpdxDocNode()
+ if err == nil {
+ t.Errorf("expected and error due to no SpdxDocument Node, got %v", err)
+ }
+
+ // TestCase 4: valid spdxDocument node
+ parser, _ = parserFromBodyContent(`
+ <spdx:SpdxDocument rdf:about="#SPDXRef-Document-1"/>
+ `)
+ _, err = parser.getSpdxDocNode()
+ if err != nil {
+ t.Errorf("unexpected error: %v", err)
+ }
+}
diff --git a/rdfloader/parser2v2/types.go b/rdfloader/parser2v2/types.go
index aade7a7..eb3b31d 100644
--- a/rdfloader/parser2v2/types.go
+++ b/rdfloader/parser2v2/types.go
@@ -103,3 +103,10 @@ const (
NONE SpecialLicenseValue = "NONE"
NOASSERTION SpecialLicenseValue = "NOASSERTION"
)
+
+type RangeType string
+
+const (
+ BYTE_RANGE RangeType = "byteRange"
+ LINE_RANGE RangeType = "lineRange"
+)
diff --git a/rdfloader/parser2v2/utils.go b/rdfloader/parser2v2/utils.go
index fd9ab77..4ec8426 100644
--- a/rdfloader/parser2v2/utils.go
+++ b/rdfloader/parser2v2/utils.go
@@ -7,10 +7,11 @@ import (
"github.com/RishabhBhatnagar/gordf/rdfwriter"
urilib "github.com/RishabhBhatnagar/gordf/uri"
"github.com/spdx/tools-golang/spdx"
- "regexp"
"strings"
)
+// a uri is of type baseURI#fragment or baseFragment/subFragment
+// returns fragment or subFragment when given as an input.
func getLastPartOfURI(uri string) string {
if strings.Contains(uri, "#") {
parts := strings.Split(uri, "#")
@@ -20,43 +21,12 @@ func getLastPartOfURI(uri string) string {
return parts[len(parts)-1]
}
-func (parser *rdfParser2_2) filterAllTriplesByString(subject, predicate, object string) (retTriples []*gordfParser.Triple) {
- for _, triple := range parser.gordfParserObj.Triples {
- if triple.Subject.ID == subject && triple.Predicate.ID == predicate && triple.Object.ID == object {
- retTriples = append(retTriples, triple)
- }
- }
- return retTriples
-}
-
-func (parser *rdfParser2_2) filterTriplesByRegex(triples []*gordfParser.Triple, subject, predicate, object string) (retTriples []*gordfParser.Triple, err error) {
- var subjectCompiled, objectCompiled, predicateCompiled *regexp.Regexp
- subjectCompiled, err = regexp.Compile(subject)
- if err != nil {
- return
- }
- predicateCompiled, err = regexp.Compile(predicate)
- if err != nil {
- return
- }
- objectCompiled, err = regexp.Compile(object)
- if err != nil {
- return
- }
- for _, triple := range triples {
- if subjectCompiled.MatchString(triple.Subject.ID) && predicateCompiled.MatchString(triple.Predicate.ID) && objectCompiled.MatchString(triple.Object.ID) {
- retTriples = append(retTriples, triple)
- }
- }
- return
-}
-
func isUriValid(uri string) bool {
_, err := urilib.NewURIRef(uri)
return err == nil
}
-func (parser *rdfParser2_2) getNodeTypeFromTriples(triples []*gordfParser.Triple, node *gordfParser.Node) (string, error) {
+func getNodeTypeFromTriples(triples []*gordfParser.Triple, node *gordfParser.Node) (string, error) {
if node == nil {
return "", errors.New("empty node passed to find node type")
}
@@ -71,10 +41,6 @@ func (parser *rdfParser2_2) getNodeTypeFromTriples(triples []*gordfParser.Triple
}
}
-func (parser *rdfParser2_2) getNodeType(node *gordfParser.Node) (string, error) {
- return parser.getNodeTypeFromTriples(parser.gordfParserObj.Triples, node)
-}
-
func (parser *rdfParser2_2) nodeToTriples(node *gordfParser.Node) []*gordfParser.Triple {
if node == nil {
return []*gordfParser.Triple{}
@@ -82,6 +48,8 @@ func (parser *rdfParser2_2) nodeToTriples(node *gordfParser.Node) []*gordfParser
return parser.nodeStringToTriples[node.String()]
}
+// returns which boolean was given as an input
+// string(bool) is the only possible input for which it will not raise any error.
func boolFromString(boolString string) (bool, error) {
switch strings.ToLower(boolString) {
case "true":
diff --git a/rdfloader/parser2v2/utils_test.go b/rdfloader/parser2v2/utils_test.go
new file mode 100644
index 0000000..1012060
--- /dev/null
+++ b/rdfloader/parser2v2/utils_test.go
@@ -0,0 +1,287 @@
+package parser2v2
+
+import (
+ gordfParser "github.com/RishabhBhatnagar/gordf/rdfloader/parser"
+ "github.com/spdx/tools-golang/spdx"
+ "reflect"
+ "testing"
+)
+
+func Test_getLastPartOfURI(t *testing.T) {
+ // uri of type baseFragment#fragment
+ input := "baseFragment#fragment"
+ expectedOutput := "fragment"
+ output := getLastPartOfURI(input)
+ if output != expectedOutput {
+ t.Errorf("expected %s, found %s", expectedOutput, output)
+ }
+
+ // uri of type baseFragment/subFragment
+ input = "baseFragment/subFragment"
+ expectedOutput = "subFragment"
+ output = getLastPartOfURI(input)
+ if output != expectedOutput {
+ t.Errorf("expected %s, found %s", expectedOutput, output)
+ }
+
+ // neither of the case mustn't raise any error.
+ input = "www.github.com"
+ expectedOutput = input
+ output = getLastPartOfURI(input)
+ if output != expectedOutput {
+ t.Errorf("expected %s, found %s", expectedOutput, output)
+ }
+}
+
+func Test_isUriValid(t *testing.T) {
+ // TestCase 1: Valid Input URI
+ input := "https://www.github.com"
+ isValid := isUriValid(input)
+ if !isValid {
+ t.Errorf("valid input(%s) detected as invalid.", input)
+ }
+
+ // TestCase 2: Invalid Input URI
+ input = `http\:www.github.com`
+ isValid = isUriValid(input)
+ if isValid {
+ t.Errorf("invalid input(%s) detected as valid", input)
+ }
+}
+
+func Test_rdfParser2_2_nodeToTriples(t *testing.T) {
+ var parser *rdfParser2_2
+ var output, expectedOutput []*gordfParser.Triple
+
+ // TestCase 1: a nil node shouldn't raise any error or panic.
+ parser, _ = parserFromBodyContent(``)
+ output = parser.nodeToTriples(nil)
+ if output == nil {
+ t.Errorf("nil input should return an empty slice and not nil")
+ }
+ expectedOutput = []*gordfParser.Triple{}
+ if !reflect.DeepEqual(output, expectedOutput) {
+ t.Errorf("expected %+v, got %+v", expectedOutput, output)
+ }
+
+ // TestCase 2: node should be addressable based on the node content and not the pointer.
+ // It should allow new nodes same as the older ones to retrieve the associated triples.
+ parser, _ = parserFromBodyContent(`
+ <spdx:Checksum rdf:about="#checksum">
+ <spdx:algorithm rdf:resource="http://spdx.org/rdf/terms#checksumAlgorithm_sha1" />
+ <spdx:checksumValue>75068c26abbed3ad3980685bae21d7202d288317</spdx:checksumValue>
+ </spdx:Checksum>
+ `)
+ newNode := &gordfParser.Node{
+ NodeType: gordfParser.IRI,
+ ID: "http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#checksum",
+ }
+ output = parser.nodeToTriples(newNode)
+
+ // The output must have 3 triples:
+ // 1. newNode rdf:type Checksum
+ // 2. newNode spdx:algorithm http://spdx.org/rdf/terms#checksumAlgorithm_sha1
+ // 3. newNode spdx:checksumValue 75068c26abbed3ad3980685bae21d7202d288317
+ if len(output) != 3 {
+ t.Errorf("expected output to have 3 triples, got %d", len(output))
+ }
+}
+
+func Test_boolFromString(t *testing.T) {
+ // TestCase 1: Valid Input: "true"
+ // mustn't raise any error
+ input := "true"
+ val, err := boolFromString(input)
+ if err != nil {
+ t.Errorf("function raised an error for a valid input(%s): %s", input, err)
+ }
+ if val != true {
+ t.Errorf("invalid output. Expected %v, found %v", true, val)
+ }
+
+ // TestCase 2: Valid Input: "true"
+ // mustn't raise any error
+ input = "false"
+ val, err = boolFromString(input)
+ if err != nil {
+ t.Errorf("function raised an error for a valid input(%s): %s", input, err)
+ }
+ if val != false {
+ t.Errorf("invalid output. Expected %v, found %v", false, val)
+ }
+
+ // TestCase 3: invalid input: ""
+ // it must raise an error
+ input = ""
+ val, err = boolFromString(input)
+ if err == nil {
+ t.Errorf("invalid input should've raised an error")
+ }
+}
+
+func Test_getNodeTypeFromTriples(t *testing.T) {
+ var err error
+ var node *gordfParser.Node
+ var triples []*gordfParser.Triple
+ var nodeType, expectedNodeType string
+
+ // TestCase 1: nil node must raise an error because,
+ // nil nodes cannot be associated with any rdf:type attribute.
+ _, err = getNodeTypeFromTriples(triples, nil)
+ if err == nil {
+ t.Errorf("expected an error due to nil node, got %v", err)
+ }
+
+ // TestCase 2: none of the triples give information about the rdf:type of a node.
+ node = &gordfParser.Node{
+ NodeType: gordfParser.IRI,
+ ID: "N0",
+ }
+ _, err = getNodeTypeFromTriples(triples, node)
+ if err == nil {
+ t.Errorf("expected an error saying no rdf:type found, got %v", err)
+ }
+
+ // TestCase 3: node is associated with exactly one rdf:type triples
+ typeTriple := &gordfParser.Triple{
+ Subject: node,
+ Predicate: &gordfParser.Node{
+ NodeType: gordfParser.IRI,
+ ID: RDF_TYPE,
+ },
+ Object: &gordfParser.Node{
+ NodeType: gordfParser.IRI,
+ ID: "http://spdx.org/rdf/terms#Checksum",
+ },
+ }
+ triples = append(triples, typeTriple)
+ expectedNodeType = "http://spdx.org/rdf/terms#Checksum"
+ nodeType, err = getNodeTypeFromTriples(triples, node)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if nodeType != expectedNodeType {
+ t.Errorf("expected: %v, got: %v", nodeType, expectedNodeType)
+ }
+
+ // TestCase 4: node associated with more than one rdf:type triples must raise an error.
+ typeTriple = &gordfParser.Triple{
+ Subject: node,
+ Predicate: &gordfParser.Node{
+ NodeType: gordfParser.IRI,
+ ID: RDF_TYPE,
+ },
+ Object: &gordfParser.Node{
+ NodeType: gordfParser.IRI,
+ ID: "http://spdx.org/rdf/terms#Snippet",
+ },
+ }
+ triples = append(triples, typeTriple)
+ _, err = getNodeTypeFromTriples(triples, node)
+ if err == nil {
+ t.Errorf("expected an error saying more than one rdf:type found, got %v", err)
+ }
+}
+
+// following tests are copy pasted from tvloader/parser2v2/util_test.go
+
+func TestCanExtractDocumentAndElementRefsFromID(t *testing.T) {
+ // test with valid ID in this document
+ helperForExtractDocElementID(t, "SPDXRef-file1", false, "", "file1")
+ // test with valid ID in another document
+ helperForExtractDocElementID(t, "DocumentRef-doc2:SPDXRef-file2", false, "doc2", "file2")
+ // test with invalid ID in this document
+ helperForExtractDocElementID(t, "a:SPDXRef-file1", true, "", "")
+ helperForExtractDocElementID(t, "file1", true, "", "")
+ helperForExtractDocElementID(t, "SPDXRef-", true, "", "")
+ helperForExtractDocElementID(t, "SPDXRef-file1:", true, "", "")
+ // test with invalid ID in another document
+ helperForExtractDocElementID(t, "DocumentRef-doc2", true, "", "")
+ helperForExtractDocElementID(t, "DocumentRef-doc2:", true, "", "")
+ helperForExtractDocElementID(t, "DocumentRef-doc2:SPDXRef-", true, "", "")
+ helperForExtractDocElementID(t, "DocumentRef-doc2:a", true, "", "")
+ helperForExtractDocElementID(t, "DocumentRef-:", true, "", "")
+ helperForExtractDocElementID(t, "DocumentRef-:SPDXRef-file1", true, "", "")
+ // test with invalid formats
+ helperForExtractDocElementID(t, "DocumentRef-doc2:SPDXRef-file1:file2", true, "", "")
+}
+
+func helperForExtractDocElementID(t *testing.T, tst string, wantErr bool, wantDoc string, wantElt string) {
+ deID, err := ExtractDocElementID(tst)
+ if err != nil && wantErr == false {
+ t.Errorf("testing %v: expected nil error, got %v", tst, err)
+ }
+ if err == nil && wantErr == true {
+ t.Errorf("testing %v: expected non-nil error, got nil", tst)
+ }
+ if deID.DocumentRefID != wantDoc {
+ if wantDoc == "" {
+ t.Errorf("testing %v: want empty string for DocumentRefID, got %v", tst, deID.DocumentRefID)
+ } else {
+ t.Errorf("testing %v: want %v for DocumentRefID, got %v", tst, wantDoc, deID.DocumentRefID)
+ }
+ }
+ if deID.ElementRefID != spdx.ElementID(wantElt) {
+ if wantElt == "" {
+ t.Errorf("testing %v: want emptyString for ElementRefID, got %v", tst, deID.ElementRefID)
+ } else {
+ t.Errorf("testing %v: want %v for ElementRefID, got %v", tst, wantElt, deID.ElementRefID)
+ }
+ }
+}
+
+func TestCanExtractElementRefsOnlyFromID(t *testing.T) {
+ // test with valid ID in this document
+ helperForExtractElementID(t, "SPDXRef-file1", false, "file1")
+ // test with valid ID in another document
+ helperForExtractElementID(t, "DocumentRef-doc2:SPDXRef-file2", true, "")
+ // test with invalid ID in this document
+ helperForExtractElementID(t, "a:SPDXRef-file1", true, "")
+ helperForExtractElementID(t, "file1", true, "")
+ helperForExtractElementID(t, "SPDXRef-", true, "")
+ helperForExtractElementID(t, "SPDXRef-file1:", true, "")
+ // test with invalid ID in another document
+ helperForExtractElementID(t, "DocumentRef-doc2", true, "")
+ helperForExtractElementID(t, "DocumentRef-doc2:", true, "")
+ helperForExtractElementID(t, "DocumentRef-doc2:SPDXRef-", true, "")
+ helperForExtractElementID(t, "DocumentRef-doc2:a", true, "")
+ helperForExtractElementID(t, "DocumentRef-:", true, "")
+ helperForExtractElementID(t, "DocumentRef-:SPDXRef-file1", true, "")
+}
+
+func helperForExtractElementID(t *testing.T, tst string, wantErr bool, wantElt string) {
+ eID, err := ExtractElementID(tst)
+ if err != nil && wantErr == false {
+ t.Errorf("testing %v: expected nil error, got %v", tst, err)
+ }
+ if err == nil && wantErr == true {
+ t.Errorf("testing %v: expected non-nil error, got nil", tst)
+ }
+ if eID != spdx.ElementID(wantElt) {
+ if wantElt == "" {
+ t.Errorf("testing %v: want emptyString for ElementRefID, got %v", tst, eID)
+ } else {
+ t.Errorf("testing %v: want %v for ElementRefID, got %v", tst, wantElt, eID)
+ }
+ }
+}
+
+func TestCanExtractSubvalues(t *testing.T) {
+ subkey, subvalue, err := ExtractSubs("SHA1: abc123", ":")
+ if err != nil {
+ t.Errorf("got error when calling extractSubs: %v", err)
+ }
+ if subkey != "SHA1" {
+ t.Errorf("got %v for subkey", subkey)
+ }
+ if subvalue != "abc123" {
+ t.Errorf("got %v for subvalue", subvalue)
+ }
+}
+
+func TestReturnsErrorForInvalidSubvalueFormat(t *testing.T) {
+ _, _, err := ExtractSubs("blah", ":")
+ if err == nil {
+ t.Errorf("expected error when calling extractSubs for invalid format (0 colons), got nil")
+ }
+}
diff --git a/rdfloader/rdfloader_test.go b/rdfloader/rdfloader_test.go
new file mode 100644
index 0000000..ed044a8
--- /dev/null
+++ b/rdfloader/rdfloader_test.go
@@ -0,0 +1,32 @@
+package rdfloader
+
+import (
+ "io"
+ "strings"
+ "testing"
+)
+
+func TestLoad2_2(t *testing.T) {
+ var reader io.Reader
+ var err error
+
+ // TestCase 1: invalid rdf/xml must raise an error
+ reader = strings.NewReader("")
+ _, err = Load2_2(reader)
+ if err == nil {
+ t.Errorf("expected an EOF error reading an empty file, got %v", err)
+ }
+
+ // TestCase 2: Valid rdf/xml but invalid spdx document must raise an error
+ reader = strings.NewReader(`
+ <rdf:RDF
+ xmlns:spdx="http://spdx.org/rdf/terms#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#">
+ </rdf:RDF>
+ `)
+ _, err = Load2_2(reader)
+ if err == nil {
+ t.Errorf("expected an error due to no SpdxDocument Node in the document")
+ }
+}