• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
2
3package parser2v2
4
5import (
6	"testing"
7
8	gordfParser "github.com/spdx/gordf/rdfloader/parser"
9	"github.com/spdx/tools-golang/spdx/common"
10	"github.com/spdx/tools-golang/spdx/v2_2"
11)
12
13func Test_rdfParser2_2_getSnippetInformationFromTriple2_2(t *testing.T) {
14	var err error
15	var parser *rdfParser2_2
16	var node *gordfParser.Node
17
18	// TestCase 1: invalid snippet id:
19	parser, _ = parserFromBodyContent(`
20		<spdx:Snippet rdf:about="#Snippet">
21		</spdx:Snippet>
22	`)
23	node = parser.gordfParserObj.Triples[0].Subject
24	_, err = parser.getSnippetInformationFromNode2_2(node)
25	if err == nil {
26		t.Errorf("expected an error due to invalid, got %v", err)
27	}
28
29	// TestCase 2: Invalid LicenseInfoInSnippet
30	parser, _ = parserFromBodyContent(`
31		<spdx:Snippet rdf:about="#SPDXRef-Snippet">
32			<spdx:licenseInfoInSnippet rdf:resource="http://spdx.org/licenses/Unknown"/>
33		</spdx:Snippet>
34	`)
35	node = parser.gordfParserObj.Triples[0].Subject
36	_, err = parser.getSnippetInformationFromNode2_2(node)
37	if err == nil {
38		t.Errorf("expected an error due to invalid licenseInfoInSnippet, got %v", err)
39	}
40
41	// TestCase 3: Invalid range.
42	parser, _ = parserFromBodyContent(`
43		<spdx:Snippet rdf:about="#SPDXRef-Snippet">
44			<spdx:range>
45				<spdx:StartEndPointer>
46					<spdx:unknownTag />
47				</spdx:StartEndPointer>
48			</spdx:range>
49		</spdx:Snippet>
50	`)
51	node = parser.gordfParserObj.Triples[0].Subject
52	_, err = parser.getSnippetInformationFromNode2_2(node)
53	if err == nil {
54		t.Errorf("expected an error due to invalid range, got %v", err)
55	}
56
57	// TestCase 3: invalid file in snippetFromFile
58	parser, _ = parserFromBodyContent(`
59		<spdx:Snippet rdf:about="#SPDXRef-Snippet">
60			<spdx:snippetFromFile>
61				<spdx:File rdf:resource="http://anupam-VirtualBox/spdx.rdf#item8" />
62			</spdx:snippetFromFile>
63		</spdx:Snippet>
64	`)
65	node = parser.gordfParserObj.Triples[0].Subject
66	_, err = parser.getSnippetInformationFromNode2_2(node)
67	if err == nil {
68		t.Errorf("expected an error due to invalid snippetFromFile, got %v", err)
69	}
70
71	// TestCase 4: unknown predicate
72	parser, _ = parserFromBodyContent(`
73		<spdx:Snippet rdf:about="#SPDXRef-Snippet">
74			<spdx:unknownPredicate />
75		</spdx:Snippet>
76	`)
77	node = parser.gordfParserObj.Triples[0].Subject
78	_, err = parser.getSnippetInformationFromNode2_2(node)
79	if err == nil {
80		t.Errorf("expected an error due to invalid predicate, got %v", err)
81	}
82
83	// TestCase 5: invalid license concluded:
84	parser, _ = parserFromBodyContent(`
85		<spdx:Snippet rdf:about="#SPDXRef-Snippet">
86			<spdx:licenseConcluded rdf:resource="http://spdx.org/licenses/Unknown"/>
87		</spdx:Snippet>
88	`)
89	node = parser.gordfParserObj.Triples[0].Subject
90	_, err = parser.getSnippetInformationFromNode2_2(node)
91	if err == nil {
92		t.Errorf("expected an error due to invalid licenseConcluded, got %v", err)
93	}
94
95	// TestCase 6: everything valid:
96	parser, _ = parserFromBodyContent(`
97		<spdx:Snippet rdf:about="#SPDXRef-Snippet">
98			<spdx:snippetFromFile>
99				<spdx:File rdf:about="#SPDXRef-File" />
100			</spdx:snippetFromFile>
101			<spdx:range>
102				<j.0:StartEndPointer>
103					<j.0:startPointer>
104						<j.0:LineCharPointer>
105							<j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
106							<j.0:lineNumber>420</j.0:lineNumber>
107						</j.0:LineCharPointer>
108					</j.0:startPointer>
109					<j.0:endPointer>
110						<j.0:LineCharPointer>
111							<j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
112							<j.0:lineNumber>310</j.0:lineNumber>
113						</j.0:LineCharPointer>
114					</j.0:endPointer>
115				</j.0:StartEndPointer>
116			</spdx:range>
117			<spdx:licenseInfoInSnippet rdf:resource="http://spdx.org/rdf/terms#noassertion"/>
118			<spdx:name>snippet test</spdx:name>
119			<spdx:copyrightText>test</spdx:copyrightText>
120			<spdx:licenseComments>comments</spdx:licenseComments>
121			<rdfs:comment>comments</rdfs:comment>
122			<spdx:licenseConcluded rdf:resource="http://spdx.org/rdf/terms#noassertion"/>
123		</spdx:Snippet>
124	`)
125	node = parser.gordfParserObj.Triples[0].Subject
126	_, err = parser.getSnippetInformationFromNode2_2(node)
127	if err != nil {
128		t.Fatalf("error parsing a valid example: %v", err)
129	}
130}
131
132func Test_setSnippetID(t *testing.T) {
133	// TestCase 1: invalid input (empty)
134	err := setSnippetID("", &v2_2.Snippet{})
135	if err == nil {
136		t.Errorf("should've raised an error for empty input")
137	}
138
139	// TestCase 2: valid input
140	si := &v2_2.Snippet{}
141	err = setSnippetID("http://spdx.org/spdxdocs/spdx-example#SPDXRef-Snippet", si)
142	if err != nil {
143		t.Errorf("unexpected error: %v", err)
144	}
145	if si.SnippetSPDXIdentifier != "Snippet" {
146		t.Errorf("expected: %s, found: %s", "Snippet", si.SnippetSPDXIdentifier)
147	}
148}
149
150func Test_rdfParser2_2_parseRangeReference(t *testing.T) {
151	var err error
152	var node *gordfParser.Node
153	var parser *rdfParser2_2
154	var si *v2_2.Snippet
155
156	// TestCase 1: ResourceLiteral node without a new file shouldn't raise any error.
157	si = &v2_2.Snippet{}
158	parser, _ = parserFromBodyContent(``)
159	node = &gordfParser.Node{
160		NodeType: gordfParser.RESOURCELITERAL,
161		ID:       "http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource",
162	}
163	err = parser.parseRangeReference(node, si)
164	if err != nil {
165		t.Errorf("error parsing a valid node: %v", err)
166	}
167
168	// TestCase 2: invalid file in the reference should raise an error
169	si = &v2_2.Snippet{}
170	parser, _ = parserFromBodyContent(`
171		<spdx:File rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#DoapSource">
172			<spdx:fileName> test file </spdx:fileName>
173		</spdx:File>
174	`)
175	node = parser.gordfParserObj.Triples[0].Subject
176	err = parser.parseRangeReference(node, si)
177	if err == nil {
178		t.Errorf("expected an error due to invalid file in the range reference, got %v", err)
179	}
180
181	// TestCase 3: A valid reference must set the file to the files map of the parser.
182	si = &v2_2.Snippet{}
183	parser, _ = parserFromBodyContent(`
184		<spdx:File rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource">
185			<spdx:fileName> test file </spdx:fileName>
186		</spdx:File>
187	`)
188	node = parser.gordfParserObj.Triples[0].Subject
189	err = parser.parseRangeReference(node, si)
190	if err != nil {
191		t.Errorf("error parsing a valid input: %v", err)
192	}
193	if len(parser.files) != 1 {
194		t.Errorf("expected parser.files to have 1 file, found %d", len(parser.files))
195	}
196}
197
198func Test_rdfParser2_2_getPointerFromNode(t *testing.T) {
199	var parser *rdfParser2_2
200	var node *gordfParser.Node
201	var si *v2_2.Snippet
202	var err error
203	var rt RangeType
204	var number int
205
206	// TestCase 1: invalid number in the offset field must raise an error.
207	parser, _ = parserFromBodyContent(`
208		<j.0:startPointer>
209			<j.0:LineCharPointer>
210				<j.0:reference rdf:resource="#SPDXRef-DoapSource"/>
211				<j.0:offset>3-10</j.0:offset>
212			</j.0:LineCharPointer>
213		</j.0:startPointer>
214	`)
215	node = parser.gordfParserObj.Triples[0].Subject
216	_, _, err = parser.getPointerFromNode(node, si)
217	if err == nil {
218		t.Errorf("should've raised an error parsing invalid offset, got %v", err)
219	}
220
221	// TestCase 2: invalid number in the lineNumber field must raise an error.
222	parser, _ = parserFromBodyContent(`
223		<j.0:ByteOffsetPointer>
224			<j.0:reference rdf:resource="#SPDXRef-DoapSource"/>
225			<j.0:offset>3-10</j.0:offset>
226		</j.0:ByteOffsetPointer>
227	`)
228	node = parser.gordfParserObj.Triples[0].Subject
229	_, _, err = parser.getPointerFromNode(node, si)
230	if err == nil {
231		t.Errorf("should've raised an error parsing invalid offset, got %v", err)
232	}
233
234	// TestCase 3: invalid predicate in the pointer field
235	parser, _ = parserFromBodyContent(`
236		<j.0:ByteOffsetPointer>
237			<spdx:invalidTag />
238			<j.0:reference rdf:resource="#SPDXRef-DoapSource"/>
239			<j.0:lineNumber>3-10</j.0:lineNumber>
240		</j.0:ByteOffsetPointer>
241	`)
242	node = parser.gordfParserObj.Triples[0].Subject
243	_, _, err = parser.getPointerFromNode(node, si)
244	if err == nil {
245		t.Errorf("should've raised an error parsing invalid predicate, got %v", err)
246	}
247
248	// TestCase 4: No range type defined must also raise an error
249	parser, _ = parserFromBodyContent(`
250		<j.0:ByteOffsetPointer>
251			<j.0:reference rdf:resource="#SPDXRef-DoapSource"/>
252		</j.0:ByteOffsetPointer>
253	`)
254	node = parser.gordfParserObj.Triples[0].Subject
255	_, _, err = parser.getPointerFromNode(node, si)
256	if err == nil {
257		t.Errorf("should've raised an error parsing invalid rangeType, got %v", err)
258	}
259
260	// TestCase 5: valid example
261	parser, _ = parserFromBodyContent(`
262		<j.0:ByteOffsetPointer>
263			<j.0:reference rdf:resource="#SPDXRef-DoapSource"/>
264			<j.0:offset>310</j.0:offset>
265		</j.0:ByteOffsetPointer>
266	`)
267	node = parser.gordfParserObj.Triples[0].Subject
268	rt, number, err = parser.getPointerFromNode(node, si)
269	if err != nil {
270		t.Fatalf("unexpected error parsing a valid node: %v", err)
271	}
272	if rt != BYTE_RANGE {
273		t.Errorf("expected: %s, got: %s", BYTE_RANGE, rt)
274	}
275	if number != 310 {
276		t.Errorf("expected: %d, got: %d", 310, number)
277	}
278}
279
280func Test_rdfParser2_2_setSnippetRangeFromNode(t *testing.T) {
281	var parser *rdfParser2_2
282	var err error
283	var si *v2_2.Snippet
284	var node *gordfParser.Node
285
286	// TestCase 1: range with less one pointer less must raise an error
287	//			   (end-pointer missing in the range)
288	parser, _ = parserFromBodyContent(`
289            <j.0:StartEndPointer>
290                <j.0:startPointer>
291                    <j.0:LineCharPointer>
292                        <j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
293                        <j.0:offset>310</j.0:offset>
294                    </j.0:LineCharPointer>
295                </j.0:startPointer>
296            </j.0:StartEndPointer>
297
298	`)
299	si = &v2_2.Snippet{}
300	node = parser.gordfParserObj.Triples[0].Subject
301	err = parser.setSnippetRangeFromNode(node, si)
302	if err == nil {
303		t.Errorf("expected an error due to missing end pointer, got %v", err)
304	}
305
306	// TestCase 2: triples with 0 or more than one type-triple
307	parser, _ = parserFromBodyContent(`
308
309            <j.0:StartEndPointer>
310                <j.0:endPointer>
311                    <j.0:ByteOffsetPointer>
312                        <j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
313                        <j.0:offset>420</j.0:offset>
314                    </j.0:ByteOffsetPointer>
315                </j.0:endPointer>
316                <j.0:startPointer>
317                    <j.0:ByteOffsetPointer>
318                        <j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
319                        <j.0:offset>310</j.0:offset>
320                    </j.0:ByteOffsetPointer>
321                </j.0:startPointer>
322            </j.0:StartEndPointer>
323
324	`)
325	si = &v2_2.Snippet{}
326	node = parser.gordfParserObj.Triples[0].Subject
327	dummyTriple := parser.gordfParserObj.Triples[0]
328	// resetting the node to be associated with 3 triples which will have
329	// rdf:type triple either thrice or 0 times.
330	parser.nodeStringToTriples[node.String()] = []*gordfParser.Triple{
331		dummyTriple, dummyTriple, dummyTriple,
332	}
333	err = parser.setSnippetRangeFromNode(node, si)
334	if err == nil {
335		t.Errorf("expected an error due to invalid rdf:type triples, got %v", err)
336	}
337
338	// TestCase 3: triples with 0 startPointer
339	parser, _ = parserFromBodyContent(`
340		<j.0:StartEndPointer>
341			<j.0:endPointer>
342				<j.0:ByteOffsetPointer>
343					<j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
344					<j.0:offset>420</j.0:offset>
345				</j.0:ByteOffsetPointer>
346			</j.0:endPointer>
347			<j.0:endPointer>
348				<j.0:LineCharPointer>
349					<j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
350					<j.0:offset>310</j.0:offset>
351				</j.0:LineCharPointer>
352			</j.0:endPointer>
353		</j.0:StartEndPointer>
354	`)
355	si = &v2_2.Snippet{}
356	node = parser.gordfParserObj.Triples[0].Subject
357	err = parser.setSnippetRangeFromNode(node, si)
358	if err == nil {
359		t.Errorf("expected an error due to missing start pointer, got %v", err)
360	}
361
362	// TestCase 4: triples with 0 endPointer
363	parser, _ = parserFromBodyContent(`
364		<j.0:StartEndPointer>
365			<j.0:endPointer>
366				<j.0:ByteOffsetPointer>
367					<j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
368					<j.0:offset>420</j.0:offset>
369				</j.0:ByteOffsetPointer>
370			</j.0:endPointer>
371			<j.0:endPointer>
372				<j.0:LineCharPointer>
373					<j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
374					<j.0:offset>310</j.0:offset>
375				</j.0:LineCharPointer>
376			</j.0:endPointer>
377		</j.0:StartEndPointer>
378	`)
379	si = &v2_2.Snippet{}
380	node = parser.gordfParserObj.Triples[0].Subject
381	err = parser.setSnippetRangeFromNode(node, si)
382	if err == nil {
383		t.Errorf("expected an error due to missing end pointer, got %v", err)
384	}
385
386	// TestCase 5: error parsing start pointer must be propagated to the range
387	parser, _ = parserFromBodyContent(`
388		<j.0:StartEndPointer>
389			<j.0:startPointer>
390				<j.0:ByteOffsetPointer>
391					<j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
392					<j.0:offset>42.0</j.0:offset>
393				</j.0:ByteOffsetPointer>
394			</j.0:startPointer>
395			<j.0:endPointer>
396				<j.0:ByteOffsetPointer>
397					<j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
398					<j.0:offset>310</j.0:offset>
399				</j.0:ByteOffsetPointer>
400			</j.0:endPointer>
401		</j.0:StartEndPointer>
402	`)
403	si = &v2_2.Snippet{}
404	node = parser.gordfParserObj.Triples[0].Subject
405	err = parser.setSnippetRangeFromNode(node, si)
406	if err == nil {
407		t.Errorf("expected an error due to invalid start pointer, got %v", err)
408	}
409
410	// TestCase 6: error parsing end pointer must be propagated to the range
411	parser, _ = parserFromBodyContent(`
412		<j.0:StartEndPointer>
413			<j.0:startPointer>
414				<j.0:ByteOffsetPointer>
415					<j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
416					<j.0:offset>420</j.0:offset>
417				</j.0:ByteOffsetPointer>
418			</j.0:startPointer>
419			<j.0:endPointer>
420				<j.0:ByteOffsetPointer>
421					<j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
422					<j.0:offset>31+0</j.0:offset>
423				</j.0:ByteOffsetPointer>
424			</j.0:endPointer>
425		</j.0:StartEndPointer>
426	`)
427	si = &v2_2.Snippet{}
428	node = parser.gordfParserObj.Triples[0].Subject
429	err = parser.setSnippetRangeFromNode(node, si)
430	if err == nil {
431		t.Errorf("expected an error due to invalid end pointer, got %v", err)
432	}
433
434	// TestCase 7: mismatching start and end pointer must also raise an error.
435	parser, _ = parserFromBodyContent(`
436		<j.0:StartEndPointer>
437			<j.0:startPointer>
438				<j.0:ByteOffsetPointer>
439					<j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
440					<j.0:offset>420</j.0:offset>
441				</j.0:ByteOffsetPointer>
442			</j.0:startPointer>
443			<j.0:endPointer>
444				<j.0:LineCharPointer>
445					<j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
446					<j.0:lineNumber>310</j.0:lineNumber>
447				</j.0:LineCharPointer>
448			</j.0:endPointer>
449		</j.0:StartEndPointer>
450	`)
451	si = &v2_2.Snippet{}
452	node = parser.gordfParserObj.Triples[0].Subject
453	err = parser.setSnippetRangeFromNode(node, si)
454	if err == nil {
455		t.Errorf("expected an error due to mismatching start and end pointers, got %v", err)
456	}
457
458	// TestCase 8: everything valid(byte_range):
459	parser, _ = parserFromBodyContent(`
460		<j.0:StartEndPointer>
461			<j.0:startPointer>
462				<j.0:ByteOffsetPointer>
463					<j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
464					<j.0:offset>420</j.0:offset>
465				</j.0:ByteOffsetPointer>
466			</j.0:startPointer>
467			<j.0:endPointer>
468				<j.0:ByteOffsetPointer>
469					<j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
470					<j.0:offset>310</j.0:offset>
471				</j.0:ByteOffsetPointer>
472			</j.0:endPointer>
473		</j.0:StartEndPointer>
474	`)
475	si = &v2_2.Snippet{}
476	node = parser.gordfParserObj.Triples[0].Subject
477	err = parser.setSnippetRangeFromNode(node, si)
478	if err != nil {
479		t.Errorf("unexpected error: %v", err)
480	}
481
482	// TestCase 9: everything valid(line_range):
483	parser, _ = parserFromBodyContent(`
484		<j.0:StartEndPointer>
485			<j.0:startPointer>
486				<j.0:LineCharPointer>
487					<j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
488					<j.0:lineNumber>420</j.0:lineNumber>
489				</j.0:LineCharPointer>
490			</j.0:startPointer>
491			<j.0:endPointer>
492				<j.0:LineCharPointer>
493					<j.0:reference rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DoapSource"/>
494					<j.0:lineNumber>310</j.0:lineNumber>
495				</j.0:LineCharPointer>
496			</j.0:endPointer>
497		</j.0:StartEndPointer>
498	`)
499	si = &v2_2.Snippet{}
500	node = parser.gordfParserObj.Triples[0].Subject
501	err = parser.setSnippetRangeFromNode(node, si)
502	if err != nil {
503		t.Errorf("unexpected error: %v", err)
504	}
505}
506
507func Test_rdfParser2_2_setSnippetToFileWithID(t *testing.T) {
508	var parser *rdfParser2_2
509	var fileId common.ElementID
510	var si *v2_2.Snippet
511	var file *v2_2.File
512	var err error
513
514	// TestCase 1: file id which is not associated with any file must raise an error.
515	parser, _ = parserFromBodyContent("")
516	si = &v2_2.Snippet{}
517	err = parser.setSnippetToFileWithID(si, fileId)
518	if err == nil {
519		t.Errorf("expected an error saying undefined file")
520	}
521
522	// TestCase 2: file exists, but snippet of the file doesn't ( it mustn't raise any error )
523	fileId = common.ElementID("File1")
524	file = &v2_2.File{
525		FileSPDXIdentifier: fileId,
526	}
527	parser.files[fileId] = file
528	file.Snippets = nil // nil snippets
529	err = parser.setSnippetToFileWithID(si, fileId)
530	if err != nil {
531		t.Errorf("unexpected error: %v", err)
532	}
533	if len(file.Snippets) != 1 {
534		t.Errorf("expected file to have 1 snippet, got %d", len(file.Snippets))
535	}
536}
537