xref: /aosp_15_r20/external/spdx-tools/rdfloader/parser2v3/utils_test.go (revision ba677afa8f67bb56cbc794f4d0e378e0da058e16)
1*ba677afaSXin Li// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
2*ba677afaSXin Li
3*ba677afaSXin Lipackage parser2v3
4*ba677afaSXin Li
5*ba677afaSXin Liimport (
6*ba677afaSXin Li	"reflect"
7*ba677afaSXin Li	"testing"
8*ba677afaSXin Li
9*ba677afaSXin Li	gordfParser "github.com/spdx/gordf/rdfloader/parser"
10*ba677afaSXin Li	"github.com/spdx/tools-golang/spdx/common"
11*ba677afaSXin Li)
12*ba677afaSXin Li
13*ba677afaSXin Lifunc Test_getLastPartOfURI(t *testing.T) {
14*ba677afaSXin Li	// uri of type baseFragment#fragment
15*ba677afaSXin Li	input := "baseFragment#fragment"
16*ba677afaSXin Li	expectedOutput := "fragment"
17*ba677afaSXin Li	output := getLastPartOfURI(input)
18*ba677afaSXin Li	if output != expectedOutput {
19*ba677afaSXin Li		t.Errorf("expected %s, found %s", expectedOutput, output)
20*ba677afaSXin Li	}
21*ba677afaSXin Li
22*ba677afaSXin Li	// uri of type baseFragment/subFragment
23*ba677afaSXin Li	input = "baseFragment/subFragment"
24*ba677afaSXin Li	expectedOutput = "subFragment"
25*ba677afaSXin Li	output = getLastPartOfURI(input)
26*ba677afaSXin Li	if output != expectedOutput {
27*ba677afaSXin Li		t.Errorf("expected %s, found %s", expectedOutput, output)
28*ba677afaSXin Li	}
29*ba677afaSXin Li
30*ba677afaSXin Li	// neither of the case mustn't raise any error.
31*ba677afaSXin Li	input = "www.github.com"
32*ba677afaSXin Li	expectedOutput = input
33*ba677afaSXin Li	output = getLastPartOfURI(input)
34*ba677afaSXin Li	if output != expectedOutput {
35*ba677afaSXin Li		t.Errorf("expected %s, found %s", expectedOutput, output)
36*ba677afaSXin Li	}
37*ba677afaSXin Li}
38*ba677afaSXin Li
39*ba677afaSXin Lifunc Test_isUriValid(t *testing.T) {
40*ba677afaSXin Li	// TestCase 1: Valid Input URI
41*ba677afaSXin Li	input := "https://www.github.com"
42*ba677afaSXin Li	isValid := isUriValid(input)
43*ba677afaSXin Li	if !isValid {
44*ba677afaSXin Li		t.Errorf("valid input(%s) detected as invalid.", input)
45*ba677afaSXin Li	}
46*ba677afaSXin Li
47*ba677afaSXin Li	// TestCase 2: Invalid Input URI
48*ba677afaSXin Li	input = `http\:www.github.com`
49*ba677afaSXin Li	isValid = isUriValid(input)
50*ba677afaSXin Li	if isValid {
51*ba677afaSXin Li		t.Errorf("invalid input(%s) detected as valid", input)
52*ba677afaSXin Li	}
53*ba677afaSXin Li}
54*ba677afaSXin Li
55*ba677afaSXin Lifunc Test_rdfParser2_3_nodeToTriples(t *testing.T) {
56*ba677afaSXin Li	var parser *rdfParser2_3
57*ba677afaSXin Li	var output, expectedOutput []*gordfParser.Triple
58*ba677afaSXin Li
59*ba677afaSXin Li	// TestCase 1: a nil node shouldn't raise any error or panic.
60*ba677afaSXin Li	parser, _ = parserFromBodyContent(``)
61*ba677afaSXin Li	output = parser.nodeToTriples(nil)
62*ba677afaSXin Li	if output == nil {
63*ba677afaSXin Li		t.Errorf("nil input should return an empty slice and not nil")
64*ba677afaSXin Li	}
65*ba677afaSXin Li	expectedOutput = []*gordfParser.Triple{}
66*ba677afaSXin Li	if !reflect.DeepEqual(output, expectedOutput) {
67*ba677afaSXin Li		t.Errorf("expected %+v, got %+v", expectedOutput, output)
68*ba677afaSXin Li	}
69*ba677afaSXin Li
70*ba677afaSXin Li	// TestCase 2: node should be addressable based on the node content and not the pointer.
71*ba677afaSXin Li	// It should allow new nodes same as the older ones to retrieve the associated triples.
72*ba677afaSXin Li	parser, _ = parserFromBodyContent(`
73*ba677afaSXin Li		  <spdx:Checksum rdf:about="#checksum">
74*ba677afaSXin Li			<spdx:algorithm rdf:resource="http://spdx.org/rdf/terms#checksumAlgorithm_sha1" />
75*ba677afaSXin Li			<spdx:checksumValue>75068c26abbed3ad3980685bae21d7202d288317</spdx:checksumValue>
76*ba677afaSXin Li		  </spdx:Checksum>
77*ba677afaSXin Li	`)
78*ba677afaSXin Li	newNode := &gordfParser.Node{
79*ba677afaSXin Li		NodeType: gordfParser.IRI,
80*ba677afaSXin Li		ID:       "http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#checksum",
81*ba677afaSXin Li	}
82*ba677afaSXin Li	output = parser.nodeToTriples(newNode)
83*ba677afaSXin Li
84*ba677afaSXin Li	// The output must have 3 triples:
85*ba677afaSXin Li	// 1. newNode rdf:type Checksum
86*ba677afaSXin Li	// 2. newNode spdx:algorithm http://spdx.org/rdf/terms#checksumAlgorithm_sha1
87*ba677afaSXin Li	// 3. newNode spdx:checksumValue 75068c26abbed3ad3980685bae21d7202d288317
88*ba677afaSXin Li	if len(output) != 3 {
89*ba677afaSXin Li		t.Errorf("expected output to have 3 triples, got %d", len(output))
90*ba677afaSXin Li	}
91*ba677afaSXin Li}
92*ba677afaSXin Li
93*ba677afaSXin Lifunc Test_boolFromString(t *testing.T) {
94*ba677afaSXin Li	// TestCase 1: Valid Input: "true"
95*ba677afaSXin Li	// mustn't raise any error
96*ba677afaSXin Li	input := "true"
97*ba677afaSXin Li	val, err := boolFromString(input)
98*ba677afaSXin Li	if err != nil {
99*ba677afaSXin Li		t.Errorf("function raised an error for a valid input(%s): %s", input, err)
100*ba677afaSXin Li	}
101*ba677afaSXin Li	if val != true {
102*ba677afaSXin Li		t.Errorf("invalid output. Expected %v, found %v", true, val)
103*ba677afaSXin Li	}
104*ba677afaSXin Li
105*ba677afaSXin Li	// TestCase 2: Valid Input: "true"
106*ba677afaSXin Li	// mustn't raise any error
107*ba677afaSXin Li	input = "false"
108*ba677afaSXin Li	val, err = boolFromString(input)
109*ba677afaSXin Li	if err != nil {
110*ba677afaSXin Li		t.Errorf("function raised an error for a valid input(%s): %s", input, err)
111*ba677afaSXin Li	}
112*ba677afaSXin Li	if val != false {
113*ba677afaSXin Li		t.Errorf("invalid output. Expected %v, found %v", false, val)
114*ba677afaSXin Li	}
115*ba677afaSXin Li
116*ba677afaSXin Li	// TestCase 3: invalid input: ""
117*ba677afaSXin Li	// it must raise an error
118*ba677afaSXin Li	input = ""
119*ba677afaSXin Li	val, err = boolFromString(input)
120*ba677afaSXin Li	if err == nil {
121*ba677afaSXin Li		t.Errorf("invalid input should've raised an error")
122*ba677afaSXin Li	}
123*ba677afaSXin Li}
124*ba677afaSXin Li
125*ba677afaSXin Lifunc Test_getNodeTypeFromTriples(t *testing.T) {
126*ba677afaSXin Li	var err error
127*ba677afaSXin Li	var node *gordfParser.Node
128*ba677afaSXin Li	var triples []*gordfParser.Triple
129*ba677afaSXin Li	var nodeType, expectedNodeType string
130*ba677afaSXin Li
131*ba677afaSXin Li	// TestCase 1: nil node must raise an error because,
132*ba677afaSXin Li	// nil nodes cannot be associated with any rdf:type attribute.
133*ba677afaSXin Li	_, err = getNodeTypeFromTriples(triples, nil)
134*ba677afaSXin Li	if err == nil {
135*ba677afaSXin Li		t.Errorf("expected an error due to nil node, got %v", err)
136*ba677afaSXin Li	}
137*ba677afaSXin Li
138*ba677afaSXin Li	// TestCase 2: none of the triples give information about the rdf:type of a node.
139*ba677afaSXin Li	node = &gordfParser.Node{
140*ba677afaSXin Li		NodeType: gordfParser.IRI,
141*ba677afaSXin Li		ID:       "N0",
142*ba677afaSXin Li	}
143*ba677afaSXin Li	_, err = getNodeTypeFromTriples(triples, node)
144*ba677afaSXin Li	if err == nil {
145*ba677afaSXin Li		t.Errorf("expected an error saying no rdf:type found, got %v", err)
146*ba677afaSXin Li	}
147*ba677afaSXin Li
148*ba677afaSXin Li	// TestCase 3: node is associated with exactly one rdf:type triples
149*ba677afaSXin Li	typeTriple := &gordfParser.Triple{
150*ba677afaSXin Li		Subject: node,
151*ba677afaSXin Li		Predicate: &gordfParser.Node{
152*ba677afaSXin Li			NodeType: gordfParser.IRI,
153*ba677afaSXin Li			ID:       RDF_TYPE,
154*ba677afaSXin Li		},
155*ba677afaSXin Li		Object: &gordfParser.Node{
156*ba677afaSXin Li			NodeType: gordfParser.IRI,
157*ba677afaSXin Li			ID:       "http://spdx.org/rdf/terms#Checksum",
158*ba677afaSXin Li		},
159*ba677afaSXin Li	}
160*ba677afaSXin Li	triples = append(triples, typeTriple)
161*ba677afaSXin Li	expectedNodeType = "http://spdx.org/rdf/terms#Checksum"
162*ba677afaSXin Li	nodeType, err = getNodeTypeFromTriples(triples, node)
163*ba677afaSXin Li	if err != nil {
164*ba677afaSXin Li		t.Fatalf("unexpected error: %v", err)
165*ba677afaSXin Li	}
166*ba677afaSXin Li	if nodeType != expectedNodeType {
167*ba677afaSXin Li		t.Errorf("expected: %v, got: %v", nodeType, expectedNodeType)
168*ba677afaSXin Li	}
169*ba677afaSXin Li
170*ba677afaSXin Li	// TestCase 4: node associated with more than one rdf:type triples must raise an error.
171*ba677afaSXin Li	typeTriple = &gordfParser.Triple{
172*ba677afaSXin Li		Subject: node,
173*ba677afaSXin Li		Predicate: &gordfParser.Node{
174*ba677afaSXin Li			NodeType: gordfParser.IRI,
175*ba677afaSXin Li			ID:       RDF_TYPE,
176*ba677afaSXin Li		},
177*ba677afaSXin Li		Object: &gordfParser.Node{
178*ba677afaSXin Li			NodeType: gordfParser.IRI,
179*ba677afaSXin Li			ID:       "http://spdx.org/rdf/terms#Snippet",
180*ba677afaSXin Li		},
181*ba677afaSXin Li	}
182*ba677afaSXin Li	triples = append(triples, typeTriple)
183*ba677afaSXin Li	_, err = getNodeTypeFromTriples(triples, node)
184*ba677afaSXin Li	if err == nil {
185*ba677afaSXin Li		t.Errorf("expected an error saying more than one rdf:type found, got %v", err)
186*ba677afaSXin Li	}
187*ba677afaSXin Li}
188*ba677afaSXin Li
189*ba677afaSXin Li// following tests are copy pasted from tvloader/parser2v3/util_test.go
190*ba677afaSXin Li
191*ba677afaSXin Lifunc TestCanExtractDocumentAndElementRefsFromID(t *testing.T) {
192*ba677afaSXin Li	// test with valid ID in this document
193*ba677afaSXin Li	helperForExtractDocElementID(t, "SPDXRef-file1", false, "", "file1")
194*ba677afaSXin Li	// test with valid ID in another document
195*ba677afaSXin Li	helperForExtractDocElementID(t, "DocumentRef-doc2:SPDXRef-file2", false, "doc2", "file2")
196*ba677afaSXin Li	// test with invalid ID in this document
197*ba677afaSXin Li	helperForExtractDocElementID(t, "a:SPDXRef-file1", true, "", "")
198*ba677afaSXin Li	helperForExtractDocElementID(t, "file1", true, "", "")
199*ba677afaSXin Li	helperForExtractDocElementID(t, "SPDXRef-", true, "", "")
200*ba677afaSXin Li	helperForExtractDocElementID(t, "SPDXRef-file1:", true, "", "")
201*ba677afaSXin Li	// test with invalid ID in another document
202*ba677afaSXin Li	helperForExtractDocElementID(t, "DocumentRef-doc2", true, "", "")
203*ba677afaSXin Li	helperForExtractDocElementID(t, "DocumentRef-doc2:", true, "", "")
204*ba677afaSXin Li	helperForExtractDocElementID(t, "DocumentRef-doc2:SPDXRef-", true, "", "")
205*ba677afaSXin Li	helperForExtractDocElementID(t, "DocumentRef-doc2:a", true, "", "")
206*ba677afaSXin Li	helperForExtractDocElementID(t, "DocumentRef-:", true, "", "")
207*ba677afaSXin Li	helperForExtractDocElementID(t, "DocumentRef-:SPDXRef-file1", true, "", "")
208*ba677afaSXin Li	// test with invalid formats
209*ba677afaSXin Li	helperForExtractDocElementID(t, "DocumentRef-doc2:SPDXRef-file1:file2", true, "", "")
210*ba677afaSXin Li}
211*ba677afaSXin Li
212*ba677afaSXin Lifunc helperForExtractDocElementID(t *testing.T, tst string, wantErr bool, wantDoc string, wantElt string) {
213*ba677afaSXin Li	deID, err := ExtractDocElementID(tst)
214*ba677afaSXin Li	if err != nil && wantErr == false {
215*ba677afaSXin Li		t.Errorf("testing %v: expected nil error, got %v", tst, err)
216*ba677afaSXin Li	}
217*ba677afaSXin Li	if err == nil && wantErr == true {
218*ba677afaSXin Li		t.Errorf("testing %v: expected non-nil error, got nil", tst)
219*ba677afaSXin Li	}
220*ba677afaSXin Li	if deID.DocumentRefID != wantDoc {
221*ba677afaSXin Li		if wantDoc == "" {
222*ba677afaSXin Li			t.Errorf("testing %v: want empty string for DocumentRefID, got %v", tst, deID.DocumentRefID)
223*ba677afaSXin Li		} else {
224*ba677afaSXin Li			t.Errorf("testing %v: want %v for DocumentRefID, got %v", tst, wantDoc, deID.DocumentRefID)
225*ba677afaSXin Li		}
226*ba677afaSXin Li	}
227*ba677afaSXin Li	if deID.ElementRefID != common.ElementID(wantElt) {
228*ba677afaSXin Li		if wantElt == "" {
229*ba677afaSXin Li			t.Errorf("testing %v: want emptyString for ElementRefID, got %v", tst, deID.ElementRefID)
230*ba677afaSXin Li		} else {
231*ba677afaSXin Li			t.Errorf("testing %v: want %v for ElementRefID, got %v", tst, wantElt, deID.ElementRefID)
232*ba677afaSXin Li		}
233*ba677afaSXin Li	}
234*ba677afaSXin Li}
235*ba677afaSXin Li
236*ba677afaSXin Lifunc TestCanExtractElementRefsOnlyFromID(t *testing.T) {
237*ba677afaSXin Li	// test with valid ID in this document
238*ba677afaSXin Li	helperForExtractElementID(t, "SPDXRef-file1", false, "file1")
239*ba677afaSXin Li	// test with valid ID in another document
240*ba677afaSXin Li	helperForExtractElementID(t, "DocumentRef-doc2:SPDXRef-file2", true, "")
241*ba677afaSXin Li	// test with invalid ID in this document
242*ba677afaSXin Li	helperForExtractElementID(t, "a:SPDXRef-file1", true, "")
243*ba677afaSXin Li	helperForExtractElementID(t, "file1", true, "")
244*ba677afaSXin Li	helperForExtractElementID(t, "SPDXRef-", true, "")
245*ba677afaSXin Li	helperForExtractElementID(t, "SPDXRef-file1:", true, "")
246*ba677afaSXin Li	// test with invalid ID in another document
247*ba677afaSXin Li	helperForExtractElementID(t, "DocumentRef-doc2", true, "")
248*ba677afaSXin Li	helperForExtractElementID(t, "DocumentRef-doc2:", true, "")
249*ba677afaSXin Li	helperForExtractElementID(t, "DocumentRef-doc2:SPDXRef-", true, "")
250*ba677afaSXin Li	helperForExtractElementID(t, "DocumentRef-doc2:a", true, "")
251*ba677afaSXin Li	helperForExtractElementID(t, "DocumentRef-:", true, "")
252*ba677afaSXin Li	helperForExtractElementID(t, "DocumentRef-:SPDXRef-file1", true, "")
253*ba677afaSXin Li}
254*ba677afaSXin Li
255*ba677afaSXin Lifunc helperForExtractElementID(t *testing.T, tst string, wantErr bool, wantElt string) {
256*ba677afaSXin Li	eID, err := ExtractElementID(tst)
257*ba677afaSXin Li	if err != nil && wantErr == false {
258*ba677afaSXin Li		t.Errorf("testing %v: expected nil error, got %v", tst, err)
259*ba677afaSXin Li	}
260*ba677afaSXin Li	if err == nil && wantErr == true {
261*ba677afaSXin Li		t.Errorf("testing %v: expected non-nil error, got nil", tst)
262*ba677afaSXin Li	}
263*ba677afaSXin Li	if eID != common.ElementID(wantElt) {
264*ba677afaSXin Li		if wantElt == "" {
265*ba677afaSXin Li			t.Errorf("testing %v: want emptyString for ElementRefID, got %v", tst, eID)
266*ba677afaSXin Li		} else {
267*ba677afaSXin Li			t.Errorf("testing %v: want %v for ElementRefID, got %v", tst, wantElt, eID)
268*ba677afaSXin Li		}
269*ba677afaSXin Li	}
270*ba677afaSXin Li}
271*ba677afaSXin Li
272*ba677afaSXin Lifunc TestCanExtractSubvalues(t *testing.T) {
273*ba677afaSXin Li	subkey, subvalue, err := ExtractSubs("SHA1: abc123", ":")
274*ba677afaSXin Li	if err != nil {
275*ba677afaSXin Li		t.Errorf("got error when calling extractSubs: %v", err)
276*ba677afaSXin Li	}
277*ba677afaSXin Li	if subkey != "SHA1" {
278*ba677afaSXin Li		t.Errorf("got %v for subkey", subkey)
279*ba677afaSXin Li	}
280*ba677afaSXin Li	if subvalue != "abc123" {
281*ba677afaSXin Li		t.Errorf("got %v for subvalue", subvalue)
282*ba677afaSXin Li	}
283*ba677afaSXin Li}
284*ba677afaSXin Li
285*ba677afaSXin Lifunc TestReturnsErrorForInvalidSubvalueFormat(t *testing.T) {
286*ba677afaSXin Li	_, _, err := ExtractSubs("blah", ":")
287*ba677afaSXin Li	if err == nil {
288*ba677afaSXin Li		t.Errorf("expected error when calling extractSubs for invalid format (0 colons), got nil")
289*ba677afaSXin Li	}
290*ba677afaSXin Li}
291