aboutsummaryrefslogtreecommitdiff
path: root/rdfloader
diff options
context:
space:
mode:
authorRishabh Bhatnagar <bhatnagarrishabh4@gmail.com>2020-08-30 23:01:21 +0530
committerRishabh Bhatnagar <bhatnagarrishabh4@gmail.com>2020-08-30 23:01:21 +0530
commit84fab30a66a136c293769b182265c62e6665b302 (patch)
treea907b98dd2d7b277f0fce5808f4e1acb6009720f /rdfloader
parent054eb919a1867a7b0c171a8c6fcdc3140a7e2903 (diff)
downloadspdx-tools-84fab30a66a136c293769b182265c62e6665b302.tar.gz
Add Tests and Bug Fixes for Relationships and Licenses
- licenseTypes: renamed license of WithExceptionOperator to member - ignore rdf:type triple in Licenses - add comment to LicenseException Signed-off-by: Rishabh Bhatnagar <bhatnagarrishabh4@gmail.com>
Diffstat (limited to 'rdfloader')
-rw-r--r--rdfloader/parser2v2/license_utils.go115
-rw-r--r--rdfloader/parser2v2/license_utils_test.go343
-rw-r--r--rdfloader/parser2v2/parse_license.go146
-rw-r--r--rdfloader/parser2v2/parse_license_test.go811
-rw-r--r--rdfloader/parser2v2/parse_other_license_info.go2
-rw-r--r--rdfloader/parser2v2/parse_other_license_info_test.go71
-rw-r--r--rdfloader/parser2v2/parse_review.go6
-rw-r--r--rdfloader/parser2v2/parse_review_test.go71
-rw-r--r--rdfloader/parser2v2/types.go6
9 files changed, 1460 insertions, 111 deletions
diff --git a/rdfloader/parser2v2/license_utils.go b/rdfloader/parser2v2/license_utils.go
new file mode 100644
index 0000000..2641b27
--- /dev/null
+++ b/rdfloader/parser2v2/license_utils.go
@@ -0,0 +1,115 @@
+package parser2v2
+
+import (
+ "fmt"
+ gordfParser "github.com/RishabhBhatnagar/gordf/rdfloader/parser"
+ "strings"
+)
+
+/* util methods for licenses and checksums below:*/
+
+// Given the license URI, returns the name of the license defined
+// in the last part of the uri.
+// This function is susceptible to false-positives.
+func getLicenseStringFromURI(uri string) string {
+ licenseEnd := strings.TrimSpace(getLastPartOfURI(uri))
+ lower := strings.ToLower(licenseEnd)
+ if lower == "none" || lower == "noassertion" {
+ return strings.ToUpper(licenseEnd)
+ }
+ return licenseEnd
+}
+
+// returns the checksum algorithm and it's value
+// In the newer versions, these two strings will be bound to a single checksum struct
+// whose pointer will be returned.
+func (parser *rdfParser2_2) getChecksumFromNode(checksumNode *gordfParser.Node) (algorithm string, value string, err error) {
+ var checksumValue, checksumAlgorithm string
+ for _, checksumTriple := range parser.nodeToTriples(checksumNode) {
+ switch checksumTriple.Predicate.ID {
+ case RDF_TYPE:
+ continue
+ case SPDX_CHECKSUM_VALUE:
+ // cardinality: exactly 1
+ checksumValue = strings.TrimSpace(checksumTriple.Object.ID)
+ case SPDX_ALGORITHM:
+ // cardinality: exactly 1
+ checksumAlgorithm, err = getAlgorithmFromURI(checksumTriple.Object.ID)
+ if err != nil {
+ return
+ }
+ default:
+ err = fmt.Errorf("unknown predicate '%s' while parsing checksum node", checksumTriple.Predicate.ID)
+ return
+ }
+ }
+ return checksumAlgorithm, checksumValue, nil
+}
+
+func getAlgorithmFromURI(algorithmURI string) (checksumAlgorithm string, err error) {
+ fragment := getLastPartOfURI(algorithmURI)
+ if !strings.HasPrefix(fragment, "checksumAlgorithm_") {
+ return "", fmt.Errorf("checksum algorithm uri must begin with checksumAlgorithm_. found %s", fragment)
+ }
+ algorithm := strings.TrimPrefix(fragment, "checksumAlgorithm_")
+ algorithm = strings.ToLower(strings.TrimSpace(algorithm))
+ switch algorithm {
+ case "md2", "md4", "md5", "md6":
+ checksumAlgorithm = strings.ToUpper(algorithm)
+ case "sha1", "sha224", "sha256", "sha384", "sha512":
+ checksumAlgorithm = strings.ToUpper(algorithm)
+ default:
+ return "", fmt.Errorf("unknown checksum algorithm %s", algorithm)
+ }
+ return
+}
+
+// from a list of licenses, it returns a
+// list of string representation of those licenses.
+func mapLicensesToStrings(licences []AnyLicenseInfo) []string {
+ res := make([]string, len(licences), len(licences))
+ for i, lic := range licences {
+ res[i] = lic.ToLicenseString()
+ }
+ return res
+}
+
+/****** Type Functions ******/
+
+// TODO: should probably add brackets while linearizing a nested license.
+func (lic ConjunctiveLicenseSet) ToLicenseString() string {
+ return strings.Join(mapLicensesToStrings(lic.members), " AND ")
+}
+
+// TODO: should probably add brackets while linearizing a nested license.
+func (lic DisjunctiveLicenseSet) ToLicenseString() string {
+ return strings.Join(mapLicensesToStrings(lic.members), " OR ")
+}
+
+func (lic ExtractedLicensingInfo) ToLicenseString() string {
+ return lic.licenseID
+}
+
+func (operator OrLaterOperator) ToLicenseString() string {
+ return operator.member.ToLicenseString()
+}
+
+func (lic License) ToLicenseString() string {
+ return lic.licenseID
+}
+
+func (lic ListedLicense) ToLicenseString() string {
+ return lic.licenseID
+}
+
+func (lic WithExceptionOperator) ToLicenseString() string {
+ return lic.member.ToLicenseString()
+}
+
+func (lic SpecialLicense) ToLicenseString() string {
+ return string(lic.value)
+}
+
+func (lic SimpleLicensingInfo) ToLicenseString() string {
+ return lic.licenseID
+}
diff --git a/rdfloader/parser2v2/license_utils_test.go b/rdfloader/parser2v2/license_utils_test.go
new file mode 100644
index 0000000..f4c9377
--- /dev/null
+++ b/rdfloader/parser2v2/license_utils_test.go
@@ -0,0 +1,343 @@
+package parser2v2
+
+import (
+ "reflect"
+ "testing"
+)
+
+func Test_getLicenseStringFromURI(t *testing.T) {
+ // TestCase 1: NONE license
+ input := SPDX_NONE_CAPS
+ output := getLicenseStringFromURI(input)
+ expectedOutput := "NONE"
+ if output != expectedOutput {
+ t.Errorf("expected: %s, found %s", expectedOutput, output)
+ }
+
+ // TestCase 2: NOASSERTION license
+ input = SPDX_NOASSERTION_SMALL
+ output = getLicenseStringFromURI(input)
+ expectedOutput = "NOASSERTION"
+ if output != expectedOutput {
+ t.Errorf("expected: %s, found %s", expectedOutput, output)
+ }
+
+ // TestCase 3: Other license
+ input = NS_SPDX + "LicenseRef-1"
+ output = getLicenseStringFromURI(input)
+ expectedOutput = "LicenseRef-1"
+ if output != expectedOutput {
+ t.Errorf("expected: %s, found %s", expectedOutput, output)
+ }
+}
+
+func Test_rdfParser2_2_getChecksumFromNode(t *testing.T) {
+ var parser *rdfParser2_2
+ 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>
+ `)
+ checksumNode := parser.gordfParserObj.Triples[0].Subject
+ _, _, err = parser.getChecksumFromNode(checksumNode)
+ if err == nil {
+ t.Errorf("expected an error saying invalid checksum algorithm")
+ }
+
+ // TestCase 2: invalid predicate
+ parser, _ = parserFromBodyContent(`
+ <spdx:Checksum>
+ <spdx:checksumValue>2fd4e1c67a2d28fced849ee1bb76e7391b93eb12</spdx:checksumValue>
+ <spdx:algorithm rdf:resource="http://spdx.org/rdf/terms#checksumAlgorithm_sha1"/>
+ <spdx:invalidPredicate />
+ </spdx:Checksum>
+ `)
+ checksumNode = parser.gordfParserObj.Triples[0].Subject
+ _, _, err = parser.getChecksumFromNode(checksumNode)
+ if err == nil {
+ t.Errorf("expected an error saying invalid predicate")
+ }
+
+ // TestCase 3: valid input
+ parser, _ = parserFromBodyContent(`
+ <spdx:Checksum>
+ <spdx:checksumValue>2fd4e1c67a2d28fced849ee1bb76e7391b93eb12</spdx:checksumValue>
+ <spdx:algorithm rdf:resource="http://spdx.org/rdf/terms#checksumAlgorithm_sha1"/>
+ </spdx:Checksum>
+ `)
+ checksumNode = parser.gordfParserObj.Triples[0].Subject
+ algorithm, value, err := parser.getChecksumFromNode(checksumNode)
+ if err != nil {
+ t.Errorf("unexpected error: %v", err)
+ }
+ if algorithm != "SHA1" {
+ t.Errorf("expected checksum algorithm to be sha1, found %s", algorithm)
+ }
+ expectedValue := "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12"
+ if value != expectedValue {
+ t.Errorf("expected checksumValue to be %s, found %s", expectedValue, value)
+ }
+}
+
+func Test_rdfParser2_2_getAlgorithmFromURI(t *testing.T) {
+ var algorithmURI string
+ var err error
+
+ // TestCase 1: checksumAlgorithm uri doesn't start with checksumAlgorithm_
+ algorithmURI = NS_SPDX + "sha1"
+ _, err = getAlgorithmFromURI(algorithmURI)
+ if err == nil {
+ t.Errorf("should've raised an error for algorithmURI that doesn't start with checksumAlgorithm_")
+ }
+
+ // TestCase 2: unknown checksum algorithm
+ algorithmURI = NS_SPDX + "checksumAlgorithm_sha999"
+ _, err = getAlgorithmFromURI(algorithmURI)
+ if err == nil {
+ t.Errorf("should've raised an error for invalid algorithm")
+ }
+
+ // TestCase 3: valid input
+ algorithmURI = NS_SPDX + "checksumAlgorithm_sha256"
+ algorithm, err := getAlgorithmFromURI(algorithmURI)
+ if err != nil {
+ t.Errorf("unexpected error: %v", err)
+ }
+ if algorithm != "SHA256" {
+ t.Errorf("expected: SHA256, found: %s", algorithm)
+ }
+}
+
+func Test_mapLicensesToStrings(t *testing.T) {
+ // nothing much to test here.
+ // just a dummy dry run.
+ licenses := []AnyLicenseInfo{
+ SpecialLicense{
+ value: NONE,
+ },
+ SpecialLicense{
+ value: NOASSERTION,
+ },
+ }
+ licenseStrings := mapLicensesToStrings(licenses)
+ expectedLicenseStrings := []string{"NONE", "NOASSERTION"}
+ if !reflect.DeepEqual(licenseStrings, expectedLicenseStrings) {
+ t.Errorf("expected: %+v\nfound %+v", expectedLicenseStrings, licenseStrings)
+ }
+}
+
+func TestConjunctiveLicenseSet_ToLicenseString(t *testing.T) {
+ var lic ConjunctiveLicenseSet
+ var output, expectedOutput string
+
+ // TestCase 1: no license in the set
+ lic = ConjunctiveLicenseSet{
+ members: nil,
+ }
+ output = lic.ToLicenseString()
+ expectedOutput = ""
+ if output != expectedOutput {
+ t.Errorf("expected: %s, found %s", output, expectedOutput)
+ }
+
+ // TestCase 2: single license in the set
+ lic = ConjunctiveLicenseSet{
+ members: []AnyLicenseInfo{
+ SpecialLicense{value: NOASSERTION},
+ },
+ }
+ output = lic.ToLicenseString()
+ expectedOutput = "NOASSERTION"
+ if output != expectedOutput {
+ t.Errorf("expected: %s, found %s", output, expectedOutput)
+ }
+
+ // TestCase 3: more than one license in the set.
+ lic = ConjunctiveLicenseSet{
+ members: []AnyLicenseInfo{
+ SpecialLicense{value: NOASSERTION},
+ SpecialLicense{value: NONE},
+ },
+ }
+ output = lic.ToLicenseString()
+ expectedOutput = "NOASSERTION AND NONE"
+ if output != expectedOutput {
+ t.Errorf("expected: %s, found %s", output, expectedOutput)
+ }
+
+ // TestCase 4: nested conjunctive license.
+ lic = ConjunctiveLicenseSet{
+ members: []AnyLicenseInfo{
+ SpecialLicense{value: NOASSERTION},
+ ConjunctiveLicenseSet{
+ members: []AnyLicenseInfo{
+ SpecialLicense{value: "LicenseRef-1"},
+ SpecialLicense{value: NONE},
+ },
+ },
+ },
+ }
+ output = lic.ToLicenseString()
+ expectedOutput = "NOASSERTION AND LicenseRef-1 AND NONE"
+ if output != expectedOutput {
+ t.Errorf("expected: %s, found %s", output, expectedOutput)
+ }
+}
+
+func TestDisjunctiveLicenseSet_ToLicenseString(t *testing.T) {
+ var lic DisjunctiveLicenseSet
+ var output, expectedOutput string
+
+ // TestCase 1: no license in the set
+ lic = DisjunctiveLicenseSet{
+ members: nil,
+ }
+ output = lic.ToLicenseString()
+ expectedOutput = ""
+ if output != expectedOutput {
+ t.Errorf("expected: %s, found %s", output, expectedOutput)
+ }
+
+ // TestCase 2: single license in the set
+ lic = DisjunctiveLicenseSet{
+ members: []AnyLicenseInfo{
+ SpecialLicense{value: NOASSERTION},
+ },
+ }
+ output = lic.ToLicenseString()
+ expectedOutput = "NOASSERTION"
+ if output != expectedOutput {
+ t.Errorf("expected: %s, found %s", output, expectedOutput)
+ }
+
+ // TestCase 3: more than one license in the set.
+ lic = DisjunctiveLicenseSet{
+ members: []AnyLicenseInfo{
+ SpecialLicense{value: NOASSERTION},
+ SpecialLicense{value: NONE},
+ },
+ }
+ output = lic.ToLicenseString()
+ expectedOutput = "NOASSERTION OR NONE"
+ if output != expectedOutput {
+ t.Errorf("expected: %s, found %s", output, expectedOutput)
+ }
+
+ // TestCase 4: nested conjunctive license.
+ lic = DisjunctiveLicenseSet{
+ members: []AnyLicenseInfo{
+ SpecialLicense{value: NOASSERTION},
+ DisjunctiveLicenseSet{
+ members: []AnyLicenseInfo{
+ SpecialLicense{value: "LicenseRef-1"},
+ SpecialLicense{value: NONE},
+ },
+ },
+ },
+ }
+ output = lic.ToLicenseString()
+ expectedOutput = "NOASSERTION OR LicenseRef-1 OR NONE"
+ if output != expectedOutput {
+ t.Errorf("expected: %s, found %s", output, expectedOutput)
+ }
+}
+
+func TestExtractedLicensingInfo_ToLicenseString(t *testing.T) {
+ // nothing to test (just a dry run)
+ extractedLicense := ExtractedLicensingInfo{
+ SimpleLicensingInfo: SimpleLicensingInfo{
+ licenseID: "license",
+ },
+ extractedText: "extracted Text",
+ }
+ expectedOutput := "license"
+ output := extractedLicense.ToLicenseString()
+ if output != expectedOutput {
+ t.Errorf("expected: %s, found: %s", expectedOutput, output)
+ }
+}
+
+func TestOrLaterOperator_ToLicenseString(t *testing.T) {
+ // nothing to test (just a dry run)
+ orLater := OrLaterOperator{
+ member: SimpleLicensingInfo{
+ licenseID: "license",
+ },
+ }
+ expectedOutput := "license"
+ output := orLater.ToLicenseString()
+ if output != expectedOutput {
+ t.Errorf("expected: %s, found: %s", expectedOutput, output)
+ }
+}
+
+func TestLicense_ToLicenseString(t *testing.T) {
+ // nothing to test (just a dry run)
+ license := License{
+ SimpleLicensingInfo: SimpleLicensingInfo{
+ licenseID: "license",
+ },
+ }
+ expectedOutput := "license"
+ output := license.ToLicenseString()
+ if output != expectedOutput {
+ t.Errorf("expected: %s, found: %s", expectedOutput, output)
+ }
+}
+
+func TestListedLicense_ToLicenseString(t *testing.T) {
+ // nothing to test (just a dry run)
+ ll := ListedLicense{License{
+ SimpleLicensingInfo: SimpleLicensingInfo{
+ licenseID: "license",
+ },
+ },
+ }
+ expectedOutput := "license"
+ output := ll.ToLicenseString()
+ if output != expectedOutput {
+ t.Errorf("expected: %s, found: %s", expectedOutput, output)
+ }
+}
+
+func TestWithExceptionOperator_ToLicenseString(t *testing.T) {
+ // nothing to test (just a dry run)
+ withException := WithExceptionOperator{
+ member: SimpleLicensingInfo{
+ licenseID: "license",
+ },
+ licenseException: LicenseException{},
+ }
+ expectedOutput := "license"
+ output := withException.ToLicenseString()
+ if output != expectedOutput {
+ t.Errorf("expected: %s, found: %s", expectedOutput, output)
+ }
+}
+
+func TestSpecialLicense_ToLicenseString(t *testing.T) {
+ // nothing to test (just a dry run)
+ specialLicense := SpecialLicense{
+ value: "license",
+ }
+ expectedOutput := "license"
+ output := specialLicense.ToLicenseString()
+ if output != expectedOutput {
+ t.Errorf("expected: %s, found: %s", expectedOutput, output)
+ }
+}
+
+func TestSimpleLicensingInfo_ToLicenseString(t *testing.T) {
+ // nothing to test (just a dry run)
+ sli := SimpleLicensingInfo{
+ licenseID: "license",
+ }
+ expectedOutput := "license"
+ output := sli.ToLicenseString()
+ if output != expectedOutput {
+ t.Errorf("expected: %s, found: %s", expectedOutput, output)
+ }
+}
diff --git a/rdfloader/parser2v2/parse_license.go b/rdfloader/parser2v2/parse_license.go
index 6bab096..4ebdccf 100644
--- a/rdfloader/parser2v2/parse_license.go
+++ b/rdfloader/parser2v2/parse_license.go
@@ -9,6 +9,12 @@ import (
"strings"
)
+// AnyLicense is a baseClass for all the licenses
+// All the types of licenses is a sub-type of AnyLicense,
+// either directly or indirectly.
+// This function acts as a mux for all the licenses. Based on the input, it
+// decides which type of license it is and passes control to that type of
+// license parser to parse the given input.
func (parser *rdfParser2_2) getAnyLicenseFromNode(node *gordfParser.Node) (AnyLicenseInfo, error) {
associatedTriples := rdfwriter.FilterTriples(parser.gordfParserObj.Triples, &node.ID, nil, nil)
if len(associatedTriples) == 0 {
@@ -43,6 +49,8 @@ func (parser *rdfParser2_2) getLicenseExceptionFromNode(node *gordfParser.Node)
for _, triple := range associatedTriples {
value := triple.Object.ID
switch triple.Predicate.ID {
+ case RDF_TYPE:
+ continue
case SPDX_LICENSE_EXCEPTION_ID:
exception.licenseExceptionId = value
case SPDX_LICENSE_EXCEPTION_TEXT:
@@ -56,6 +64,8 @@ func (parser *rdfParser2_2) getLicenseExceptionFromNode(node *gordfParser.Node)
exception.name = value
case SPDX_EXAMPLE:
exception.example = value
+ case RDFS_COMMENT:
+ exception.comment = value
default:
return exception, fmt.Errorf("invalid predicate(%s) for LicenseException", triple.Predicate)
}
@@ -70,16 +80,27 @@ func (parser *rdfParser2_2) getSimpleLicensingInfoFromNode(node *gordfParser.Nod
func (parser *rdfParser2_2) getWithExceptionOperatorFromNode(node *gordfParser.Node) (operator WithExceptionOperator, err error) {
associatedTriples := rdfwriter.FilterTriples(parser.gordfParserObj.Triples, &node.ID, nil, nil)
+ var memberFound bool
for _, triple := range associatedTriples {
switch triple.Predicate.ID {
+ case RDF_TYPE:
+ continue
case SPDX_MEMBER:
+ if memberFound {
+ return operator,
+ fmt.Errorf("more than one member found in the WithExceptionOperator (expected only 1)")
+ }
+ memberFound = true
member, err := parser.getSimpleLicensingInfoFromNode(triple.Object)
if err != nil {
return operator, fmt.Errorf("error parsing member of a WithExceptionOperator: %v", err)
}
- operator.license = member
+ operator.member = member
case SPDX_LICENSE_EXCEPTION:
operator.licenseException, err = parser.getLicenseExceptionFromNode(triple.Object)
+ if err != nil {
+ return operator, fmt.Errorf("error parsing licenseException of WithExceptionOperator: %v", err)
+ }
default:
return operator, fmt.Errorf("unknown predicate (%s) for a WithExceptionOperator", triple.Predicate.ID)
}
@@ -94,14 +115,24 @@ func (parser *rdfParser2_2) getOrLaterOperatorFromNode(node *gordfParser.Node) (
return operator, fmt.Errorf("orLaterOperator must be associated with exactly one tag. found %v triples", n-1)
}
for _, triple := range associatedTriples {
- operator.license, err = parser.getSimpleLicensingInfoFromNode(triple.Object)
- if err != nil {
- return operator, fmt.Errorf("error parsing simpleLicensingInfo of OrLaterOperator: %v", err)
+ switch triple.Predicate.ID {
+ case RDF_TYPE:
+ continue
+ case SPDX_MEMBER:
+ operator.member, err = parser.getSimpleLicensingInfoFromNode(triple.Object)
+ if err != nil {
+ return operator, fmt.Errorf("error parsing simpleLicensingInfo of OrLaterOperator: %v", err)
+ }
+ default:
+ return operator, fmt.Errorf("unknown predicate %s", triple.Predicate.ID)
}
}
return operator, nil
}
+// SpecialLicense is a type of license which is not defined in any of the
+// spdx documents, it is a type of license defined for the sake of brevity.
+// It can be [NONE|NOASSERTION|LicenseRef-<string>]
func (parser *rdfParser2_2) getSpecialLicenseFromNode(node *gordfParser.Node) (lic SpecialLicense, err error) {
uri := strings.TrimSpace(node.ID)
switch uri {
@@ -161,6 +192,8 @@ func (parser *rdfParser2_2) getConjunctiveLicenseSetFromNode(node *gordfParser.N
return licenseSet, fmt.Errorf("error parsing conjunctive license set: %v", err)
}
licenseSet.members = append(licenseSet.members, member)
+ default:
+ return licenseSet, fmt.Errorf("unknown subTag for ConjunctiveLicenseSet: %s", triple.Predicate.ID)
}
}
return licenseSet, nil
@@ -176,6 +209,9 @@ func (parser *rdfParser2_2) getSimpleLicensingInfoFromTriples(triples []*gordfPa
case SPDX_NAME:
lic.name = triple.Object.ID
case RDFS_SEE_ALSO:
+ if !isUriValid(triple.Object.ID) {
+ return lic, fmt.Errorf("%s is not a valid uri for seeAlso attribute of a License", triple.Object.ID)
+ }
lic.seeAlso = append(lic.seeAlso, triple.Object.ID)
case SPDX_EXAMPLE:
lic.example = triple.Object.ID
@@ -207,12 +243,6 @@ func (parser *rdfParser2_2) getLicenseFromNode(node *gordfParser.Node) (lic Lice
lic.standardLicenseTemplate = value
case SPDX_STANDARD_LICENSE_HEADER_TEMPLATE:
lic.standardLicenseHeaderTemplate = value
- case RDFS_SEE_ALSO:
- if !isUriValid(value) {
- return lic, fmt.Errorf("%s is not a valid uri for seeAlso attribute of a License", value)
- }
- lic.seeAlso = value
-
case SPDX_IS_DEPRECATED_LICENSE_ID:
lic.isDeprecatedLicenseID, err = boolFromString(value)
if err != nil {
@@ -233,99 +263,3 @@ func (parser *rdfParser2_2) getLicenseFromNode(node *gordfParser.Node) (lic Lice
}
return lic, nil
}
-
-/* util methods for licenses and checksums below:*/
-
-// Given the license URI, returns the name of the license defined
-// in the last part of the uri.
-// This function is susceptible to false-positives.
-func getLicenseStringFromURI(uri string) string {
- licenseEnd := strings.TrimSpace(getLastPartOfURI(uri))
- lower := strings.ToLower(licenseEnd)
- if lower == "none" || lower == "noassertion" {
- return strings.ToUpper(licenseEnd)
- }
- return licenseEnd
-}
-
-// returns the checksum algorithm and it's value
-// In the newer versions, these two strings will be bound to a single checksum struct
-// whose pointer will be returned.
-func (parser *rdfParser2_2) getChecksumFromNode(checksumNode *gordfParser.Node) (algorithm string, value string, err error) {
- var checksumValue, checksumAlgorithm string
- for _, checksumTriple := range parser.nodeToTriples(checksumNode) {
- switch checksumTriple.Predicate.ID {
- case RDF_TYPE:
- continue
- case SPDX_CHECKSUM_VALUE:
- // cardinality: exactly 1
- checksumValue = strings.TrimSpace(checksumTriple.Object.ID)
- case SPDX_ALGORITHM:
- // cardinality: exactly 1
- checksumAlgorithm, err = parser.getAlgorithmFromURI(checksumTriple.Object.ID)
- if err != nil {
- return
- }
- }
- }
- return checksumAlgorithm, checksumValue, nil
-}
-
-func (parser *rdfParser2_2) getAlgorithmFromURI(algorithmURI string) (checksumAlgorithm string, err error) {
- fragment := getLastPartOfURI(algorithmURI)
- if !strings.HasPrefix(fragment, "checksumAlgorithm") {
- return "", fmt.Errorf("checksum algorithm uri must begin with checksumAlgorithm. found %s", fragment)
- }
- algorithm := strings.TrimPrefix(fragment, "checksumAlgorithm_")
- algorithm = strings.ToLower(strings.TrimSpace(algorithm))
- switch algorithm {
- case "md2", "md4", "md5", "md6":
- checksumAlgorithm = strings.ToUpper(algorithm)
- case "sha1", "sha224", "sha256", "sha384", "sha512":
- checksumAlgorithm = strings.ToUpper(algorithm)
- default:
- return "", fmt.Errorf("unknown checksum algorithm %s", algorithm)
- }
- return
-}
-
-func mapLicensesToStrings(licences []AnyLicenseInfo) []string {
- res := make([]string, len(licences), len(licences))
- for i, lic := range licences {
- res[i] = lic.ToLicenseString()
- }
- return res
-}
-
-func (lic ConjunctiveLicenseSet) ToLicenseString() string {
- return strings.Join(mapLicensesToStrings(lic.members), " AND ")
-}
-
-func (lic DisjunctiveLicenseSet) ToLicenseString() string {
- return strings.Join(mapLicensesToStrings(lic.members), " OR ")
-}
-
-/****** Type Functions ******/
-func (lic ExtractedLicensingInfo) ToLicenseString() string {
- return lic.licenseID
-}
-
-func (operator OrLaterOperator) ToLicenseString() string {
- return operator.license.ToLicenseString()
-}
-
-func (lic License) ToLicenseString() string {
- return lic.licenseID
-}
-
-func (lic ListedLicense) ToLicenseString() string {
- return lic.licenseID
-}
-
-func (lic WithExceptionOperator) ToLicenseString() string {
- return lic.license.ToLicenseString()
-}
-
-func (lic SpecialLicense) ToLicenseString() string {
- return string(lic.value)
-}
diff --git a/rdfloader/parser2v2/parse_license_test.go b/rdfloader/parser2v2/parse_license_test.go
new file mode 100644
index 0000000..942ed4f
--- /dev/null
+++ b/rdfloader/parser2v2/parse_license_test.go
@@ -0,0 +1,811 @@
+package parser2v2
+
+import (
+ gordfParser "github.com/RishabhBhatnagar/gordf/rdfloader/parser"
+ "reflect"
+ "sort"
+ "testing"
+)
+
+func Test_rdfParser2_2_getAnyLicenseFromNode(t *testing.T) {
+ // since this function is a mux, we just have to make sure that with each
+ // type of input, it is able to redirect the request to an appropriate
+ // license getter.
+
+ // TestCase 1: input node is just a node string without any associated
+ // triple (either a NONE|NOASSERTION) because for other case,
+ // the license should've been associated with other triples
+ parser, _ := parserFromBodyContent(``)
+ inputNode := &gordfParser.Node{
+ NodeType: gordfParser.IRI,
+ ID: NS_SPDX + "NONE",
+ }
+ lic, err := parser.getAnyLicenseFromNode(inputNode)
+ if err != nil {
+ t.Errorf("error parsing a valid license input: %v", err)
+ }
+ // checking if the return type is a SpecialLicense
+ switch lic.(type) {
+ case SpecialLicense:
+ default:
+ t.Errorf("expected license to be of type SpecialLicense, found %v", reflect.TypeOf(lic))
+ }
+
+ // TestCase 2: DisjunctiveLicenseSet:
+ parser, _ = parserFromBodyContent(`
+ <spdx:DisjunctiveLicenseSet>
+ <spdx:member rdf:resource="http://spdx.org/licenses/Nokia"/>
+ <spdx:member rdf:resource="http://spdx.org/licenses/LGPL-2.0"/>
+ </spdx:DisjunctiveLicenseSet>
+ `)
+ inputNode = parser.gordfParserObj.Triples[0].Subject
+ lic, err = parser.getAnyLicenseFromNode(inputNode)
+ if err != nil {
+ t.Errorf("error parsing a valid license input: %v", err)
+ }
+ // checking if the return type is a DisjunctiveLicenseSet
+ switch lic.(type) {
+ case DisjunctiveLicenseSet:
+ default:
+ t.Errorf("expected license to be of type DisjunctiveLicenseSet, found %v", reflect.TypeOf(lic))
+ }
+
+ // TestCase 3: ConjunctiveLicenseSet:
+ parser, _ = parserFromBodyContent(`
+ <spdx:ConjunctiveLicenseSet>
+ <spdx:member rdf:resource="http://spdx.org/licenses/Nokia"/>
+ <spdx:member rdf:resource="http://spdx.org/licenses/LGPL-2.0"/>
+ </spdx:ConjunctiveLicenseSet>
+ `)
+ inputNode = parser.gordfParserObj.Triples[0].Subject
+ lic, err = parser.getAnyLicenseFromNode(inputNode)
+ if err != nil {
+ t.Errorf("error parsing a valid license input: %v", err)
+ }
+ // checking if the return type is a ConjunctiveLicenseSet
+ switch lic.(type) {
+ case ConjunctiveLicenseSet:
+ default:
+ t.Errorf("expected license to be of type ConjunctiveLicenseSet, found %v", reflect.TypeOf(lic))
+ }
+
+ // TestCase 4: ExtractedLicensingInfo
+ parser, _ = parserFromBodyContent(`
+ <spdx:ExtractedLicensingInfo rdf:about="http://spdx.dev/spdx.rdf#LicenseRef-Freeware">
+ <spdx:licenseId>LicenseRef-Freeware</spdx:licenseId>
+ <spdx:name>freeware</spdx:name>
+ <spdx:extractedText><![CDATA[...]]></spdx:extractedText>
+ </spdx:ExtractedLicensingInfo>
+ `)
+ inputNode = parser.gordfParserObj.Triples[0].Subject
+ lic, err = parser.getAnyLicenseFromNode(inputNode)
+ if err != nil {
+ t.Errorf("error parsing a valid license input: %v", err)
+ }
+ // checking if the return type is a ExtractedLicensingInfo
+ switch lic.(type) {
+ case ExtractedLicensingInfo:
+ default:
+ t.Errorf("expected license to be of type ExtractedLicensingInfo, found %v", reflect.TypeOf(lic))
+ }
+
+ // TestCase 4: ExtractedLicensingInfo
+ parser, _ = parserFromBodyContent(`
+ <spdx:ExtractedLicensingInfo rdf:about="http://spdx.dev/spdx.rdf#LicenseRef-Freeware">
+ <spdx:licenseId>LicenseRef-Freeware</spdx:licenseId>
+ <spdx:name>freeware</spdx:name>
+ <spdx:extractedText><![CDATA[...]]></spdx:extractedText>
+ </spdx:ExtractedLicensingInfo>
+ `)
+ inputNode = parser.gordfParserObj.Triples[0].Subject
+ lic, err = parser.getAnyLicenseFromNode(inputNode)
+ if err != nil {
+ t.Errorf("error parsing a valid license input: %v", err)
+ }
+ // checking if the return type is a ExtractedLicensingInfo
+ switch lic.(type) {
+ case ExtractedLicensingInfo:
+ default:
+ t.Errorf("expected license to be of type ExtractedLicensingInfo, found %v", reflect.TypeOf(lic))
+ }
+
+ // TestCase 5: License
+ parser, _ = parserFromBodyContent(`
+ <spdx:License rdf:about="http://spdx.org/licenses/Apache-2.0">
+ <spdx:standardLicenseTemplate>&lt;&gt; Apache License Version 2.0, January 2004 http://www.apache.org/licenses/&lt;&gt;&lt;&gt; TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION&lt;&gt; &lt;&gt; Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. &lt;&gt; Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. &lt;&gt; Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. &lt;&gt; Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: &lt;&gt; You must give any other recipients of the Work or Derivative Works a copy of this License; and &lt;&gt; You must cause any modified files to carry prominent notices stating that You changed the files; and &lt;&gt; You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and &lt;&gt; If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. &lt;&gt; Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. &lt;&gt; Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. &lt;&gt; Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. &lt;&gt; Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. &lt;&gt; Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.&lt;&gt; END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright &lt;&gt; Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.&lt;&gt;</spdx:standardLicenseTemplate>
+ <rdfs:seeAlso>http://www.apache.org/licenses/LICENSE-2.0</rdfs:seeAlso>
+ <spdx:name>Apache License 2.0</spdx:name>
+ <spdx:licenseId>Apache-2.0</spdx:licenseId>
+ <spdx:isOsiApproved>true</spdx:isOsiApproved>
+ <rdfs:seeAlso>http://www.opensource.org/licenses/Apache-2.0</rdfs:seeAlso>
+ <spdx:licenseText>...</spdx:licenseText>
+ <spdx:standardLicenseHeader>...</spdx:standardLicenseHeader>
+ </spdx:License>
+ `)
+ inputNode = parser.gordfParserObj.Triples[0].Subject
+ lic, err = parser.getAnyLicenseFromNode(inputNode)
+ if err != nil {
+ t.Errorf("error parsing a valid license input: %v", err)
+ }
+ // checking if the return type is a License
+ switch lic.(type) {
+ case License:
+ default:
+ t.Errorf("expected license to be of type License, found %v", reflect.TypeOf(lic))
+ }
+
+ // TestCase 5: WithExceptionOperator
+ parser, _ = parserFromBodyContent(`
+ <spdx:WithExceptionOperator>
+ <spdx:licenseException>
+ <spdx:LicenseException rdf:nodeID="A1">
+ <spdx:example></spdx:example>
+ <spdx:licenseExceptionId>Libtool-exception</spdx:licenseExceptionId>
+ <rdfs:comment></rdfs:comment>
+ </spdx:LicenseException>
+ </spdx:licenseException>
+ <spdx:member rdf:resource="http://spdx.org/licenses/GPL-2.0-or-later"/>
+ </spdx:WithExceptionOperator>
+ `)
+ inputNode = parser.gordfParserObj.Triples[0].Subject
+ lic, err = parser.getAnyLicenseFromNode(inputNode)
+ if err != nil {
+ t.Errorf("error parsing a valid license input: %v", err)
+ }
+ // checking if the return type is a WithExceptionOperator
+ switch lic.(type) {
+ case WithExceptionOperator:
+ default:
+ t.Errorf("expected license to be of type WithExceptionOperator, found %v", reflect.TypeOf(lic))
+ }
+
+ // TestCase 6: OrLaterOperator
+ parser, _ = parserFromBodyContent(`
+ <spdx:OrLaterOperator>
+ <spdx:member>
+ <spdx:SimpleLicensingInfo>
+ <spdx:licenseId>LicenseRef-Freeware</spdx:licenseId>
+ <spdx:name>freeware</spdx:name>
+ </spdx:SimpleLicensingInfo>
+ </spdx:member>
+ </spdx:OrLaterOperator>
+ `)
+ inputNode = parser.gordfParserObj.Triples[0].Subject
+ lic, err = parser.getAnyLicenseFromNode(inputNode)
+ if err != nil {
+ t.Errorf("error parsing a valid license input: %v", err)
+ }
+ // checking if the return type is a OrLaterOperator
+ switch lic.(type) {
+ case OrLaterOperator:
+ default:
+ 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)
+ if err == nil {
+ t.Errorf("should've raised an error for invalid input")
+ }
+}
+
+func Test_rdfParser2_2_getConjunctiveLicenseSetFromNode(t *testing.T) {
+ var parser *rdfParser2_2
+ var err error
+ var licenseNode *gordfParser.Node
+ var license ConjunctiveLicenseSet
+
+ // TestCase 1: invalid license member
+ parser, _ = parserFromBodyContent(`
+ <spdx:ConjunctiveLicenseSet>
+ <spdx:member rdf:resource="http://spdx.org/licenses/Unknown"/>
+ <spdx:member rdf:resource="http://spdx.org/licenses/LGPL-2.0"/>
+ </spdx:ConjunctiveLicenseSet>
+ `)
+ licenseNode = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getConjunctiveLicenseSetFromNode(licenseNode)
+ if err == nil {
+ t.Errorf("expected an error saying invalid license member, found <nil>")
+ }
+
+ // 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/LGPL-2.0"/>
+ <spdx:unknownTag />
+ </spdx:ConjunctiveLicenseSet>
+ `)
+ licenseNode = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getConjunctiveLicenseSetFromNode(licenseNode)
+ if err == nil {
+ t.Errorf("expected an error saying invalid predicate found")
+ }
+
+ // TestCase 3: valid example.
+ parser, _ = parserFromBodyContent(`
+ <spdx:ConjunctiveLicenseSet>
+ <spdx:member rdf:resource="http://spdx.org/licenses/Nokia"/>
+ <spdx:member rdf:resource="http://spdx.org/licenses/LGPL-2.0"/>
+ </spdx:ConjunctiveLicenseSet>
+ `)
+ licenseNode = parser.gordfParserObj.Triples[0].Subject
+ license, err = parser.getConjunctiveLicenseSetFromNode(licenseNode)
+ if err != nil {
+ t.Errorf("unexpected error parsing licenseSet: %v", err)
+ }
+ nMembers := len(license.members)
+ if nMembers != 2 {
+ t.Errorf("expected licenseSet to have 2 members, found %d", nMembers)
+ }
+ licenseMembers := mapLicensesToStrings(license.members)
+ expectedLicenseMembers := []string{"LGPL-2.0", "Nokia"}
+ sort.Strings(licenseMembers)
+ if !reflect.DeepEqual(licenseMembers, expectedLicenseMembers) {
+ t.Errorf("expected %v, found %v", expectedLicenseMembers, licenseMembers)
+ }
+}
+
+func Test_rdfParser2_2_getDisjunctiveLicenseSetFromNode(t *testing.T) {
+ var parser *rdfParser2_2
+ var err error
+ var licenseNode *gordfParser.Node
+ var license DisjunctiveLicenseSet
+
+ // TestCase 1: invalid license member
+ parser, _ = parserFromBodyContent(`
+ <spdx:DisjunctiveLicenseSet>
+ <spdx:member rdf:resource="http://spdx.org/licenses/Unknown"/>
+ <spdx:member rdf:resource="http://spdx.org/licenses/LGPL-2.0"/>
+ </spdx:DisjunctiveLicenseSet>
+ `)
+ licenseNode = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getDisjunctiveLicenseSetFromNode(licenseNode)
+ if err == nil {
+ t.Errorf("expected an error saying invalid license member, found <nil>")
+ }
+
+ // TestCase 2: invalid predicate in the licenseSet.
+ parser, _ = parserFromBodyContent(`
+ <spdx:DisjunctiveLicenseSet>
+ <spdx:member rdf:resource="http://spdx.org/licenses/Unknown"/>
+ <spdx:member rdf:resource="http://spdx.org/licenses/LGPL-2.0"/>
+ <spdx:unknownTag />
+ </spdx:DisjunctiveLicenseSet>
+ `)
+ licenseNode = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getDisjunctiveLicenseSetFromNode(licenseNode)
+ if err == nil {
+ t.Errorf("expected an error saying invalid predicate found")
+ }
+
+ // TestCase 3: valid example.
+ parser, _ = parserFromBodyContent(`
+ <spdx:DisjunctiveLicenseSet>
+ <spdx:member rdf:resource="http://spdx.org/licenses/Nokia"/>
+ <spdx:member rdf:resource="http://spdx.org/licenses/LGPL-2.0"/>
+ </spdx:DisjunctiveLicenseSet>
+ `)
+ licenseNode = parser.gordfParserObj.Triples[0].Subject
+ license, err = parser.getDisjunctiveLicenseSetFromNode(licenseNode)
+ if err != nil {
+ t.Errorf("unexpected error parsing licenseSet: %v", err)
+ }
+ nMembers := len(license.members)
+ if nMembers != 2 {
+ t.Errorf("expected licenseSet to have 2 members, found %d", nMembers)
+ }
+ licenseMembers := mapLicensesToStrings(license.members)
+ expectedLicenseMembers := []string{"LGPL-2.0", "Nokia"}
+ sort.Strings(licenseMembers)
+ if !reflect.DeepEqual(licenseMembers, expectedLicenseMembers) {
+ t.Errorf("expected %v, found %v", expectedLicenseMembers, licenseMembers)
+ }
+}
+
+func Test_rdfParser2_2_getLicenseExceptionFromNode(t *testing.T) {
+ var licenseException LicenseException
+ var err error
+ var node *gordfParser.Node
+ var parser *rdfParser2_2
+
+ // TestCase 1: invalid value for rdf:seeAlso
+ parser, _ = parserFromBodyContent(`
+ <spdx:LicenseException>
+ <rdfs:seeAlso>see-also</rdfs:seeAlso>
+ <spdx:example></spdx:example>
+ <spdx:licenseExceptionId>Libtool-exception</spdx:licenseExceptionId>
+ <rdfs:comment></rdfs:comment>
+ </spdx:LicenseException>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getLicenseExceptionFromNode(node)
+ if err == nil {
+ t.Errorf("should've raised an error due to invalid uri for rdfs:seeAlso")
+ }
+
+ // TestCase 2: invalid predicate for licenseException
+ // TestCase 1: invalid value for rdf:seeAlso
+ parser, _ = parserFromBodyContent(`
+ <spdx:LicenseException>
+ <spdx:example></spdx:example>
+ <spdx:licenseExceptionId>Libtool-exception</spdx:licenseExceptionId>
+ <rdfs:unknown></rdfs:unknown>
+ </spdx:LicenseException>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getLicenseExceptionFromNode(node)
+ if err == nil {
+ t.Errorf("should've raised an error due to invalid predicate")
+ }
+
+ // TestCase 3: everything valid
+ // TestCase 1: invalid value for rdf:seeAlso
+ parser, _ = parserFromBodyContent(`
+ <spdx:LicenseException>
+ <rdfs:seeAlso rdf:resource="http://www.opensource.org/licenses/GPL-3.0"/>
+ <spdx:example>no example</spdx:example>
+ <spdx:licenseExceptionId>Libtool-exception</spdx:licenseExceptionId>
+ <rdfs:comment>no comments</rdfs:comment>
+ <spdx:licenseExceptionText>text</spdx:licenseExceptionText>
+ <spdx:name>name</spdx:name>
+ </spdx:LicenseException>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ licenseException, err = parser.getLicenseExceptionFromNode(node)
+ if err != nil {
+ t.Fatalf("unexpected error while parsing a valid licenseException")
+ }
+ expectedCrossReference := "http://www.opensource.org/licenses/GPL-3.0"
+ if licenseException.seeAlso != expectedCrossReference {
+ t.Errorf("expected: %s, found: %s", expectedCrossReference, licenseException.seeAlso)
+ }
+ expectedExample := "no example"
+ if licenseException.example != expectedExample {
+ t.Errorf("expected: %s, got: %s", expectedExample, licenseException.example)
+ }
+ if licenseException.licenseExceptionId != "Libtool-exception" {
+ t.Errorf("expected: %s, got: %s", "Libtool-exception", licenseException.licenseExceptionId)
+ }
+ if licenseException.comment != "no comments" {
+ t.Errorf("expected: %s, got: %s", "no comments", licenseException.comment)
+ }
+ if licenseException.licenseExceptionText != "text" {
+ t.Errorf("expected: '%s', got: '%s'", "text", licenseException.licenseExceptionText)
+ }
+ if licenseException.name != "name" {
+ t.Errorf("expected: '%s', got: '%s'", "name", licenseException.name)
+ }
+}
+
+func Test_rdfParser2_2_getLicenseFromNode(t *testing.T) {
+ var parser *rdfParser2_2
+ var node *gordfParser.Node
+ var license License
+ var err error
+
+ // TestCase 1: isOsiApproved is not a valid boolean
+ parser, _ = parserFromBodyContent(`
+ <spdx:License>
+ <spdx:isOsiApproved>no</spdx:isOsiApproved>
+ </spdx:License>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ license, err = parser.getLicenseFromNode(node)
+ if err == nil {
+ t.Errorf("expected function to raise an error stating isOsiApproved should be a valid boolean type")
+ }
+
+ // TestCase 2: rdf:seeAlso not a valid uri must raise an error
+ parser, _ = parserFromBodyContent(`
+ <spdx:License>
+ <rdfs:seeAlso>uri</rdfs:seeAlso>
+ </spdx:License>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ license, err = parser.getLicenseFromNode(node)
+ if err == nil {
+ t.Errorf("expected function to raise an error stating invalid uri for rdfs:seeAlso")
+ }
+
+ // TestCase 3: isDeprecatedLicenseId is not a valid boolean
+ parser, _ = parserFromBodyContent(`
+ <spdx:License>
+ <spdx:isDeprecatedLicenseId>yes</spdx:isDeprecatedLicenseId>
+ </spdx:License>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ license, err = parser.getLicenseFromNode(node)
+ if err == nil {
+ t.Errorf("expected function to raise an error stating isDeprecatedLicenseId should be a valid boolean type")
+ }
+
+ // TestCase 4: isFsfLibre is not a valid boolean
+ parser, _ = parserFromBodyContent(`
+ <spdx:License>
+ <spdx:isFsfLibre>no</spdx:isFsfLibre>
+ </spdx:License>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ license, err = parser.getLicenseFromNode(node)
+ if err == nil {
+ t.Errorf("expected function to raise an error stating isFsfLibre should be a valid boolean type")
+ }
+
+ // TestCase 5: invalid triple for License:
+ parser, _ = parserFromBodyContent(`
+ <spdx:License>
+ <spdx:unknown />
+ </spdx:License>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ license, err = parser.getLicenseFromNode(node)
+ if err == nil {
+ t.Errorf("invalid predicate should've raised an error, got <nil>")
+ }
+
+ // TestCase 5: everything valid:
+ parser, _ = parserFromBodyContent(`
+ <spdx:License rdf:about="http://spdx.org/licenses/GPL-3.0-or-later">
+ <rdfs:seeAlso>http://www.opensource.org/licenses/GPL-3.0</rdfs:seeAlso>
+ <spdx:isOsiApproved>true</spdx:isOsiApproved>
+ <spdx:licenseText>GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007</spdx:licenseText>
+ <spdx:name>GNU General Public License v3.0 or later</spdx:name>
+ <spdx:standardLicenseHeaderTemplate>...</spdx:standardLicenseHeaderTemplate>
+ <spdx:licenseId>GPL-3.0-or-later</spdx:licenseId>
+ <rdfs:comment>This license was released: 29 June 2007</rdfs:comment>
+ <spdx:isFsfLibre>true</spdx:isFsfLibre>
+ <spdx:standardLicenseHeader>...</spdx:standardLicenseHeader>
+ <spdx:standardLicenseTemplate>....</spdx:standardLicenseTemplate>
+ </spdx:License>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ license, err = parser.getLicenseFromNode(node)
+ if err != nil {
+ t.Errorf("error parsing a valid input: %v", err)
+ }
+ expectedSeeAlso := "http://www.opensource.org/licenses/GPL-3.0"
+ if len(license.seeAlso) != 1 {
+ t.Fatalf("expected seeAlso to have 1 element, got %d", len(license.seeAlso))
+ }
+ if license.seeAlso[len(license.seeAlso)-1] != expectedSeeAlso {
+ t.Errorf("expected %s, got %s", expectedSeeAlso, license.seeAlso)
+ }
+ if license.isOsiApproved != true {
+ t.Errorf("expected %t, got %t", true, license.isOsiApproved)
+ }
+ expectedLicenseText := "GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007"
+ if license.licenseText != expectedLicenseText {
+ t.Errorf("expected %s, got %s", expectedSeeAlso, license.licenseText)
+ }
+ expectedName := "GNU General Public License v3.0 or later"
+ if license.name != expectedName {
+ t.Errorf("expected %s, got %s", expectedName, license.name)
+ }
+ expectedstdLicHeader := "..."
+ if license.standardLicenseHeader != expectedstdLicHeader {
+ t.Errorf("expected %s, got %s", expectedstdLicHeader, license.standardLicenseHeader)
+ }
+ expectedLicenseId := "GPL-3.0-or-later"
+ if expectedLicenseId != license.licenseID {
+ t.Errorf("expected %s, got %s", expectedLicenseId, license.licenseID)
+ }
+ expectedLicenseComment := "This license was released: 29 June 2007"
+ if expectedLicenseComment != license.comment {
+ t.Errorf("expected %s, got %s", expectedLicenseComment, license.comment)
+ }
+ expectedstdLicTemplate := "..."
+ if license.standardLicenseHeader != expectedstdLicTemplate {
+ t.Errorf("expected %s, got %s", expectedstdLicTemplate, license.standardLicenseTemplate)
+ }
+ expectedstdLicHeaderTemplate := "..."
+ if license.standardLicenseHeaderTemplate != expectedstdLicHeaderTemplate {
+ t.Errorf("expected %s, got %s", expectedstdLicHeaderTemplate, license.standardLicenseHeaderTemplate)
+ }
+ if license.isFsfLibre != true {
+ t.Errorf("expected %t, got %t", true, license.isFsfLibre)
+ }
+}
+
+func Test_rdfParser2_2_getOrLaterOperatorFromNode(t *testing.T) {
+ var parser *rdfParser2_2
+ var node *gordfParser.Node
+ var err error
+
+ // TestCase 1: more than one member in the OrLaterOperator tag must raise an error
+ parser, _ = parserFromBodyContent(`
+ <spdx:OrLaterOperator>
+ <spdx:member>
+ <spdx:SimpleLicensingInfo>
+ <spdx:licenseId>LicenseRef-Freeware</spdx:licenseId>
+ <spdx:name>freeware</spdx:name>
+ </spdx:SimpleLicensingInfo>
+ </spdx:member>
+ <spdx:member rdf:resource="http://spdx.org/licenses/Nokia"/>
+ </spdx:OrLaterOperator>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getOrLaterOperatorFromNode(node)
+ if err == nil {
+ t.Error("expected an error due to more than one members, got <nil>")
+ }
+
+ // TestCase 2: Invalid predicate must raise an error
+ parser, _ = parserFromBodyContent(`
+ <spdx:OrLaterOperator>
+ <spdx:members>
+ <spdx:SimpleLicensingInfo>
+ <spdx:licenseId>LicenseRef-Freeware</spdx:licenseId>
+ <spdx:name>freeware</spdx:name>
+ </spdx:SimpleLicensingInfo>
+ </spdx:members>
+ </spdx:OrLaterOperator>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getOrLaterOperatorFromNode(node)
+ if err == nil {
+ t.Error("expected an error due to invalid predicate, got <nil>")
+ }
+
+ // TestCase 3: valid input
+ parser, _ = parserFromBodyContent(`
+ <spdx:OrLaterOperator>
+ <spdx:member>
+ <spdx:SimpleLicensingInfo>
+ <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("unexpected error parsing a valid input: %v", err)
+ }
+}
+
+func Test_rdfParser2_2_getSimpleLicensingInfoFromNode(t *testing.T) {
+ // nothing to test. The just provides an interface to call function that
+ // uses triples to render a SimpleLicensingInfo.
+ parser, _ := parserFromBodyContent(`
+ <spdx:SimpleLicensingInfo>
+ <spdx:licenseId>LicenseRef-Freeware</spdx:licenseId>
+ <spdx:name>freeware</spdx:name>
+ </spdx:SimpleLicensingInfo>
+ `)
+ node := parser.gordfParserObj.Triples[0].Subject
+ _, err := parser.getSimpleLicensingInfoFromNode(node)
+ if err != nil {
+ t.Errorf("error parsing a valid input: %v", err)
+ }
+}
+
+func Test_rdfParser2_2_getSimpleLicensingInfoFromTriples(t *testing.T) {
+ var parser *rdfParser2_2
+ var err error
+ var license SimpleLicensingInfo
+
+ // TestCase 1: invalid rdf:seeAlso attribute
+ parser, _ = parserFromBodyContent(`
+ <spdx:SimpleLicensingInfo>
+ <rdfs:seeAlso>an invalid uri</rdfs:seeAlso>
+ </spdx:SimpleLicensingInfo>
+ `)
+ _, err = parser.getSimpleLicensingInfoFromTriples(parser.gordfParserObj.Triples)
+ if err == nil {
+ t.Error("expected an error reporting invalid uri for rdf:seeAlso, got <nil>")
+ }
+
+ // TestCase 2: invalid predicate must raise an error
+ parser, _ = parserFromBodyContent(`
+ <spdx:SimpleLicensingInfo>
+ <rdfs:invalidPredicate />
+ </spdx:SimpleLicensingInfo>
+ `)
+ _, err = parser.getSimpleLicensingInfoFromTriples(parser.gordfParserObj.Triples)
+ if err == nil {
+ t.Error("expected an error reporting invalid predicate, got <nil>")
+ }
+
+ // TestCase 3: valid example
+ parser, _ = parserFromBodyContent(`
+ <spdx:SimpleLicensingInfo>
+ <rdfs:comment>comment</rdfs:comment>
+ <spdx:licenseId>lid</spdx:licenseId>
+ <spdx:name>name</spdx:name>
+ <rdfs:seeAlso>https://opensource.org/licenses/MPL-1.0</rdfs:seeAlso>
+ <spdx:example>example</spdx:example>
+ </spdx:SimpleLicensingInfo>
+ `)
+ license, err = parser.getSimpleLicensingInfoFromTriples(parser.gordfParserObj.Triples)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ expectedComment := "comment"
+ expectedLicenseId := "lid"
+ expectedName := "name"
+ expectedSeeAlso := "https://opensource.org/licenses/MPL-1.0"
+ expectedExample := "example"
+ if expectedComment != license.comment {
+ t.Errorf("expected %v, got %v", expectedComment, license.comment)
+ }
+ if expectedLicenseId != license.licenseID {
+ t.Errorf("expected %v, got %v", expectedLicenseId, license.licenseID)
+ }
+ if expectedName != license.name {
+ t.Errorf("expected %v, got %v", expectedName, license.name)
+ }
+ if len(license.seeAlso) != 1 {
+ t.Fatalf("expected seeAlso to have 1 element, found %d", len(license.seeAlso))
+ }
+ if license.seeAlso[0] != expectedSeeAlso {
+ t.Errorf("expected %v, got %v", expectedSeeAlso, license.seeAlso[0])
+ }
+ if license.example != expectedExample {
+ t.Errorf("expected %v, got %v", expectedExample, license.example)
+ }
+}
+
+func Test_rdfParser2_2_getSpecialLicenseFromNode(t *testing.T) {
+ var parser *rdfParser2_2
+ var node *gordfParser.Node
+ var license SpecialLicense
+
+ // TestCase 1: NONE
+ parser, _ = parserFromBodyContent(``)
+ node = &gordfParser.Node{
+ NodeType: gordfParser.IRI,
+ ID: NS_SPDX + "NONE",
+ }
+ license, err := parser.getSpecialLicenseFromNode(node)
+ if err != nil {
+ t.Errorf("error parsing a valid node: %v", err)
+ }
+ if license.value != "NONE" {
+ t.Errorf("expected %s, got %s", "NONE", license.value)
+ }
+
+ // TestCase 2: NOASSERTION
+ parser, _ = parserFromBodyContent(``)
+ node = &gordfParser.Node{
+ NodeType: gordfParser.IRI,
+ ID: NS_SPDX + "NOASSERTION",
+ }
+ license, err = parser.getSpecialLicenseFromNode(node)
+ if err != nil {
+ t.Errorf("error parsing a valid node: %v", err)
+ }
+ if license.value != "NOASSERTION" {
+ t.Errorf("expected %s, got %s", "NOASSERTION", license.value)
+ }
+
+ // TestCase 4: undefined standard license
+ parser, _ = parserFromBodyContent(``)
+ node = &gordfParser.Node{
+ NodeType: gordfParser.IRI,
+ ID: "https://opensource.org/licenses/unknown",
+ }
+ _, err = parser.getSpecialLicenseFromNode(node)
+ if err == nil {
+ t.Errorf("expected an error saying invalid license")
+ }
+
+ // TestCase 4: valid standard license
+ parser, _ = parserFromBodyContent(``)
+ node = &gordfParser.Node{
+ NodeType: gordfParser.IRI,
+ ID: "https://opensource.org/licenses/MPL-1.0",
+ }
+ license, err = parser.getSpecialLicenseFromNode(node)
+ if err != nil {
+ t.Errorf("error parsing a valid node: %v", err)
+ }
+ if license.value != "MPL-1.0" {
+ t.Errorf("expected %s, got %s", "MPL-1.0", license.value)
+ }
+}
+
+func Test_rdfParser2_2_getWithExceptionOperatorFromNode(t *testing.T) {
+ var parser *rdfParser2_2
+ var node *gordfParser.Node
+ var err error
+
+ // TestCase 1: more than one member in the OrLaterOperator tag must raise an error
+ parser, _ = parserFromBodyContent(`
+ <spdx:WithExceptionOperator>
+ <spdx:member>
+ <spdx:SimpleLicensingInfo>
+ <spdx:licenseId>LicenseRef-Freeware</spdx:licenseId>
+ <spdx:name>freeware</spdx:name>
+ </spdx:SimpleLicensingInfo>
+ </spdx:member>
+ <spdx:member rdf:resource="http://spdx.org/licenses/Nokia"/>
+ </spdx:WithExceptionOperator>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getWithExceptionOperatorFromNode(node)
+ if err == nil {
+ t.Error("expected an error due to more than one members, got <nil>")
+ }
+
+ // TestCase 2: Invalid predicate must raise an error
+ parser, _ = parserFromBodyContent(`
+ <spdx:WithExceptionOperator>
+ <spdx:members>
+ <spdx:SimpleLicensingInfo>
+ <spdx:licenseId>LicenseRef-Freeware</spdx:licenseId>
+ <spdx:name>freeware</spdx:name>
+ </spdx:SimpleLicensingInfo>
+ </spdx:members>
+ </spdx:WithExceptionOperator>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getWithExceptionOperatorFromNode(node)
+ if err == nil {
+ t.Error("expected an error due to invalid predicate, got <nil>")
+ }
+
+ // TestCase 3: Invalid member
+ parser, _ = parserFromBodyContent(`
+ <spdx:WithExceptionOperator>
+ <spdx:member>
+ <spdx:License rdf:about="http://spdx.org/licenses/GPL-2.0-or-later">
+ <spdx:unknownTag />
+ </spdx:License>
+ </spdx:member>
+ </spdx:WithExceptionOperator>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getWithExceptionOperatorFromNode(node)
+ if err == nil {
+ t.Error("expected an error due to error parsing a member, got <nil>")
+ }
+
+ // TestCase 4: Invalid licenseException
+ parser, _ = parserFromBodyContent(`
+ <spdx:WithExceptionOperator>
+ <spdx:member>
+ <spdx:License rdf:about="http://spdx.org/licenses/GPL-2.0-or-later"/>
+ </spdx:member>
+ <spdx:licenseException>
+ <spdx:LicenseException>
+ <spdx:invalidTag />
+ <spdx:example>example</spdx:example>
+ <spdx:licenseExceptionId>Libtool-exception</spdx:licenseExceptionId>
+ <rdfs:comment>comment</rdfs:comment>
+ </spdx:LicenseException>
+ </spdx:licenseException>
+ </spdx:WithExceptionOperator>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getWithExceptionOperatorFromNode(node)
+ if err == nil {
+ t.Error("expected an error due to invalid licenseException, got <nil>")
+ }
+
+ // TestCase 5: valid input
+ parser, _ = parserFromBodyContent(`
+ <spdx:WithExceptionOperator>
+ <spdx:member>
+ <spdx:License rdf:about="http://spdx.org/licenses/GPL-2.0-or-later"/>
+ </spdx:member>
+ <spdx:licenseException>
+ <spdx:LicenseException>
+ <spdx:example>example</spdx:example>
+ <spdx:licenseExceptionId>Libtool-exception</spdx:licenseExceptionId>
+ <rdfs:comment>comment</rdfs:comment>
+ </spdx:LicenseException>
+ </spdx:licenseException>
+ </spdx:WithExceptionOperator>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getWithExceptionOperatorFromNode(node)
+ if err != nil {
+ t.Errorf("error parsing a valid input: %v", err)
+ }
+}
diff --git a/rdfloader/parser2v2/parse_other_license_info.go b/rdfloader/parser2v2/parse_other_license_info.go
index 887ae55..506a6db 100644
--- a/rdfloader/parser2v2/parse_other_license_info.go
+++ b/rdfloader/parser2v2/parse_other_license_info.go
@@ -11,7 +11,7 @@ import (
func (parser *rdfParser2_2) getExtractedLicensingInfoFromNode(node *gordfParser.Node) (lic ExtractedLicensingInfo, err error) {
associatedTriples := rdfwriter.FilterTriples(parser.gordfParserObj.Triples, &node.ID, nil, nil)
- restTriples := []*gordfParser.Triple{}
+ var restTriples []*gordfParser.Triple
for _, triple := range associatedTriples {
switch triple.Predicate.ID {
case SPDX_EXTRACTED_TEXT:
diff --git a/rdfloader/parser2v2/parse_other_license_info_test.go b/rdfloader/parser2v2/parse_other_license_info_test.go
new file mode 100644
index 0000000..286438e
--- /dev/null
+++ b/rdfloader/parser2v2/parse_other_license_info_test.go
@@ -0,0 +1,71 @@
+package parser2v2
+
+import (
+ gordfParser "github.com/RishabhBhatnagar/gordf/rdfloader/parser"
+ "reflect"
+ "testing"
+)
+
+func Test_rdfParser2_2_getExtractedLicensingInfoFromNode(t *testing.T) {
+ var parser *rdfParser2_2
+ var err error
+ var node *gordfParser.Node
+
+ // TestCase 1: invalid predicate must raise an error
+ parser, _ = parserFromBodyContent(`
+ <spdx:ExtractedLicensingInfo rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9.tar.gz_1535120734-spdx.rdf#LicenseRef-Freeware">
+ <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>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getExtractedLicensingInfoFromNode(node)
+ if err == nil {
+ t.Errorf("expected an error saying invalid predicate, got <nil>")
+ }
+
+ // TestCase 2: valid input
+ parser, _ = parserFromBodyContent(`
+ <spdx:ExtractedLicensingInfo rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9.tar.gz_1535120734-spdx.rdf#LicenseRef-Freeware">
+ <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>
+ `)
+ node = parser.gordfParserObj.Triples[0].Subject
+ _, err = parser.getExtractedLicensingInfoFromNode(node)
+ if err != nil {
+ t.Errorf("unexpected error: %v", err)
+ }
+}
+
+func Test_rdfParser2_2_extractedLicenseToOtherLicense(t *testing.T) {
+ // nothing to test for this function.
+ parser, _ := parserFromBodyContent(`
+ <spdx:ExtractedLicensingInfo rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9.tar.gz_1535120734-spdx.rdf#LicenseRef-Freeware">
+ <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>
+ `)
+ node := parser.gordfParserObj.Triples[0].Subject
+ extLicense, _ := parser.getExtractedLicensingInfoFromNode(node)
+ othLic := parser.extractedLicenseToOtherLicense(extLicense)
+
+ if othLic.LicenseIdentifier != extLicense.licenseID {
+ t.Errorf("expected %v, got %v", othLic.LicenseIdentifier, extLicense.licenseID)
+ }
+ if othLic.ExtractedText != extLicense.extractedText {
+ t.Errorf("expected %v, got %v", othLic.ExtractedText, extLicense.extractedText)
+ }
+ if othLic.LicenseComment != extLicense.comment {
+ t.Errorf("expected %v, got %v", othLic.LicenseComment, extLicense.comment)
+ }
+ if !reflect.DeepEqual(othLic.LicenseCrossReferences, extLicense.seeAlso) {
+ t.Errorf("expected %v, got %v", othLic.LicenseCrossReferences, extLicense.seeAlso)
+ }
+ if othLic.LicenseName != extLicense.name {
+ t.Errorf("expected %v, got %v", othLic.LicenseName, extLicense.name)
+ }
+}
diff --git a/rdfloader/parser2v2/parse_review.go b/rdfloader/parser2v2/parse_review.go
index ed89865..fb01a80 100644
--- a/rdfloader/parser2v2/parse_review.go
+++ b/rdfloader/parser2v2/parse_review.go
@@ -23,7 +23,11 @@ func (parser *rdfParser2_2) setReviewFromNode(reviewedNode *gordfParser.Node) er
review.ReviewDate = triple.Object.ID
case SPDX_REVIEWER:
// cardinality: max 1
- review.Reviewer = triple.Object.ID
+ var err error
+ review.ReviewerType, review.Reviewer, err = ExtractSubs(triple.Object.ID, ":")
+ if err != nil {
+ return fmt.Errorf("error parsing reviewer: err")
+ }
default:
return fmt.Errorf("unknown predicate %v for review triples", triple.Predicate)
}
diff --git a/rdfloader/parser2v2/parse_review_test.go b/rdfloader/parser2v2/parse_review_test.go
new file mode 100644
index 0000000..e0e8677
--- /dev/null
+++ b/rdfloader/parser2v2/parse_review_test.go
@@ -0,0 +1,71 @@
+package parser2v2
+
+import (
+ "testing"
+)
+
+func Test_rdfParser2_2_setReviewFromNode(t *testing.T) {
+ // TestCase 1: unknown predicate must raise an error
+ parser, _ := parserFromBodyContent(`
+ <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:unknown />
+ </spdx:Review>
+ `)
+ reviewNode := parser.gordfParserObj.Triples[0].Subject
+ err := parser.setReviewFromNode(reviewNode)
+ if err == nil {
+ t.Errorf("unknown predicate should've elicit an error")
+ }
+
+ // TestCase 2: wrong reviewer format must raise an error
+ parser, _ = parserFromBodyContent(`
+ <spdx:Review>
+ <rdfs:comment>Another example reviewer.</rdfs:comment>
+ <spdx:reviewDate>2011-03-13T00:00:00Z</spdx:reviewDate>
+ <spdx:reviewer>Suzanne Reviewer</spdx:reviewer>
+ </spdx:Review>
+ `)
+ reviewNode = parser.gordfParserObj.Triples[0].Subject
+ err = parser.setReviewFromNode(reviewNode)
+ if err == nil {
+ t.Errorf("incorrect should've elicit an error")
+ }
+
+ // TestCase 3: valid input
+ parser, _ = parserFromBodyContent(`
+ <spdx:Review>
+ <rdfs:comment>Another example reviewer.</rdfs:comment>
+ <spdx:reviewDate>2011-03-13T00:00:00Z</spdx:reviewDate>
+ <spdx:reviewer>Person: Suzanne</spdx:reviewer>
+ </spdx:Review>
+ `)
+ reviewNode = parser.gordfParserObj.Triples[0].Subject
+ err = parser.setReviewFromNode(reviewNode)
+ if err != nil {
+ t.Errorf("error parsing a valid node")
+ }
+ n := len(parser.doc.Reviews)
+ if n != 1 {
+ t.Errorf("expected doc to have 1 review, found %d", n)
+ }
+ review := parser.doc.Reviews[0]
+ expectedComment := "Another example reviewer."
+ if review.ReviewComment != expectedComment {
+ t.Errorf("expected: %v, found: %s", expectedComment, review.ReviewComment)
+ }
+ expectedDate := "2011-03-13T00:00:00Z"
+ if review.ReviewDate != expectedDate {
+ t.Errorf("expected %s, found %s", expectedDate, review.ReviewDate)
+ }
+ expectedReviewer := "Suzanne"
+ if review.Reviewer != expectedReviewer {
+ t.Errorf("expected %s, found %s", expectedReviewer, review.Reviewer)
+ }
+ expectedReviewerType := "Person"
+ if review.ReviewerType != expectedReviewerType {
+ t.Errorf("expected %s, found %s", expectedReviewerType, review.ReviewerType)
+ }
+}
diff --git a/rdfloader/parser2v2/types.go b/rdfloader/parser2v2/types.go
index d37c14b..aade7a7 100644
--- a/rdfloader/parser2v2/types.go
+++ b/rdfloader/parser2v2/types.go
@@ -47,7 +47,7 @@ type ExtractedLicensingInfo struct {
type OrLaterOperator struct {
AnyLicenseInfo
- license SimpleLicensingInfo
+ member SimpleLicensingInfo
}
type ConjunctiveLicenseSet struct {
@@ -67,7 +67,6 @@ type License struct {
standardLicenseHeader string
standardLicenseTemplate string
standardLicenseHeaderTemplate string
- seeAlso string
isDeprecatedLicenseID bool
isFsfLibre bool
}
@@ -82,11 +81,12 @@ type LicenseException struct {
seeAlso string // must be a valid uri
name string
example string
+ comment string
}
type WithExceptionOperator struct {
AnyLicenseInfo
- license SimpleLicensingInfo
+ member SimpleLicensingInfo
licenseException LicenseException
}