1// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 2package parser2v1 3 4import ( 5 "testing" 6 7 "github.com/spdx/tools-golang/spdx/common" 8 "github.com/spdx/tools-golang/spdx/v2_1" 9) 10 11// ===== Parser file section state change tests ===== 12func TestParser2_1FileStartsNewFileAfterParsingFileNameTag(t *testing.T) { 13 // create the first file 14 fileOldName := "f1.txt" 15 16 parser := tvParser2_1{ 17 doc: &v2_1.Document{Packages: []*v2_1.Package{}}, 18 st: psFile2_1, 19 pkg: &v2_1.Package{PackageName: "test", PackageSPDXIdentifier: "test", Files: []*v2_1.File{}}, 20 file: &v2_1.File{FileName: fileOldName, FileSPDXIdentifier: "f1"}, 21 } 22 fileOld := parser.file 23 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 24 parser.pkg.Files = append(parser.pkg.Files, fileOld) 25 // the Package's Files should have this one only 26 if len(parser.pkg.Files) != 1 { 27 t.Fatalf("expected 1 file, got %d", len(parser.pkg.Files)) 28 } 29 if parser.pkg.Files[0] != fileOld { 30 t.Errorf("expected file %v in Files[f1], got %v", fileOld, parser.pkg.Files[0]) 31 } 32 if parser.pkg.Files[0].FileName != fileOldName { 33 t.Errorf("expected file name %s in Files[f1], got %s", fileOldName, parser.pkg.Files[0].FileName) 34 } 35 36 // now add a new file 37 fileName := "f2.txt" 38 err := parser.parsePair2_1("FileName", fileName) 39 if err != nil { 40 t.Errorf("got error when calling parsePair2_1: %v", err) 41 } 42 // state should be correct 43 if parser.st != psFile2_1 { 44 t.Errorf("expected state to be %v, got %v", psFile2_1, parser.st) 45 } 46 // and a file should be created 47 if parser.file == nil { 48 t.Fatalf("parser didn't create new file") 49 } 50 // and the file name should be as expected 51 if parser.file.FileName != fileName { 52 t.Errorf("expected file name %s, got %s", fileName, parser.file.FileName) 53 } 54 // and the Package's Files should still be of size 1 and not have this new 55 // one yet, since it hasn't seen an SPDX identifier 56 if len(parser.pkg.Files) != 1 { 57 t.Fatalf("expected 1 file, got %d", len(parser.pkg.Files)) 58 } 59 if parser.pkg.Files[0] != fileOld { 60 t.Errorf("expected file %v in Files[f1], got %v", fileOld, parser.pkg.Files[0]) 61 } 62 if parser.pkg.Files[0].FileName != fileOldName { 63 t.Errorf("expected file name %s in Files[f1], got %s", fileOldName, parser.pkg.Files[0].FileName) 64 } 65 66 // now parse an SPDX identifier tag 67 err = parser.parsePair2_1("SPDXID", "SPDXRef-f2ID") 68 if err != nil { 69 t.Errorf("got error when calling parsePair2_1: %v", err) 70 } 71 // and the Package's Files should now be of size 2 and have this new one 72 if len(parser.pkg.Files) != 2 { 73 t.Fatalf("expected 2 files, got %d", len(parser.pkg.Files)) 74 } 75 if parser.pkg.Files[0] != fileOld { 76 t.Errorf("expected file %v in Files[f1], got %v", fileOld, parser.pkg.Files[0]) 77 } 78 if parser.pkg.Files[0].FileName != fileOldName { 79 t.Errorf("expected file name %s in Files[f1], got %s", fileOldName, parser.pkg.Files[0].FileName) 80 } 81 if parser.pkg.Files[1] != parser.file { 82 t.Errorf("expected file %v in Files[f2ID], got %v", parser.file, parser.pkg.Files[1]) 83 } 84 if parser.pkg.Files[1].FileName != fileName { 85 t.Errorf("expected file name %s in Files[f2ID], got %s", fileName, parser.pkg.Files[1].FileName) 86 } 87} 88 89func TestParser2_1FileAddsToPackageOrUnpackagedFiles(t *testing.T) { 90 // start with no packages 91 parser := tvParser2_1{ 92 doc: &v2_1.Document{}, 93 st: psCreationInfo2_1, 94 } 95 96 // add a file and SPDX identifier 97 fileName := "f2.txt" 98 err := parser.parsePair2_1("FileName", fileName) 99 if err != nil { 100 t.Errorf("got error when calling parsePair2_1: %v", err) 101 } 102 err = parser.parsePair2_1("SPDXID", "SPDXRef-f2ID") 103 if err != nil { 104 t.Errorf("got error when calling parsePair2_1: %v", err) 105 } 106 fileOld := parser.file 107 // should have been added to Files 108 if len(parser.doc.Files) != 1 { 109 t.Fatalf("expected 1 file in Files, got %d", len(parser.doc.Files)) 110 } 111 if parser.doc.Files[0] != fileOld { 112 t.Errorf("expected file %v in Files[f2ID], got %v", fileOld, parser.doc.Files[0]) 113 } 114 // now create a package and a new file 115 err = parser.parsePair2_1("PackageName", "package1") 116 if err != nil { 117 t.Errorf("got error when calling parsePair2_1: %v", err) 118 } 119 err = parser.parsePair2_1("SPDXID", "SPDXRef-pkg1") 120 if err != nil { 121 t.Errorf("got error when calling parsePair2_1: %v", err) 122 } 123 err = parser.parsePair2_1("FileName", "f3.txt") 124 if err != nil { 125 t.Errorf("got error when calling parsePair2_1: %v", err) 126 } 127 err = parser.parsePair2_1("SPDXID", "SPDXRef-f3ID") 128 if err != nil { 129 t.Errorf("got error when calling parsePair2_1: %v", err) 130 } 131 // Files should still be size 1 and have old file only 132 if len(parser.doc.Files) != 1 { 133 t.Fatalf("expected 1 file in Files, got %d", len(parser.doc.Files)) 134 } 135 if parser.doc.Files[0] != fileOld { 136 t.Errorf("expected file %v in Files[f2ID], got %v", fileOld, parser.doc.Files[0]) 137 } 138 // and new package should have gotten the new file 139 if len(parser.pkg.Files) != 1 { 140 t.Fatalf("expected 1 file in Files, got %d", len(parser.pkg.Files)) 141 } 142 if parser.pkg.Files[0] != parser.file { 143 t.Errorf("expected file %v in Files[f3ID], got %v", parser.file, parser.pkg.Files[0]) 144 } 145} 146 147func TestParser2_1FileStartsNewPackageAfterParsingPackageNameTag(t *testing.T) { 148 // create the first file and package 149 p1Name := "package1" 150 f1Name := "f1.txt" 151 152 parser := tvParser2_1{ 153 doc: &v2_1.Document{Packages: []*v2_1.Package{}}, 154 st: psFile2_1, 155 pkg: &v2_1.Package{PackageName: p1Name, PackageSPDXIdentifier: "package1", Files: []*v2_1.File{}}, 156 file: &v2_1.File{FileName: f1Name, FileSPDXIdentifier: "f1"}, 157 } 158 p1 := parser.pkg 159 f1 := parser.file 160 parser.doc.Packages = append(parser.doc.Packages, p1) 161 parser.pkg.Files = append(parser.pkg.Files, f1) 162 163 // now add a new package 164 p2Name := "package2" 165 err := parser.parsePair2_1("PackageName", p2Name) 166 if err != nil { 167 t.Errorf("got error when calling parsePair2_1: %v", err) 168 } 169 // state should go back to Package 170 if parser.st != psPackage2_1 { 171 t.Errorf("expected state to be %v, got %v", psPackage2_1, parser.st) 172 } 173 // and a package should be created 174 if parser.pkg == nil { 175 t.Fatalf("parser didn't create new pkg") 176 } 177 // and the package name should be as expected 178 if parser.pkg.PackageName != p2Name { 179 t.Errorf("expected package name %s, got %s", p2Name, parser.pkg.PackageName) 180 } 181 // and the package should default to true for FilesAnalyzed 182 if parser.pkg.FilesAnalyzed != true { 183 t.Errorf("expected FilesAnalyzed to default to true, got false") 184 } 185 if parser.pkg.IsFilesAnalyzedTagPresent != false { 186 t.Errorf("expected IsFilesAnalyzedTagPresent to default to false, got true") 187 } 188 // and the new Package should have no files 189 if len(parser.pkg.Files) != 0 { 190 t.Errorf("Expected no files in pkg.Files, got %d", len(parser.pkg.Files)) 191 } 192 // and the Document's Packages should still be of size 1 and not have this 193 // new one, because no SPDX identifier has been seen yet 194 if len(parser.doc.Packages) != 1 { 195 t.Fatalf("expected 1 package, got %d", len(parser.doc.Packages)) 196 } 197 if parser.doc.Packages[0] != p1 { 198 t.Errorf("Expected package %v in Packages[package1], got %v", p1, parser.doc.Packages[0]) 199 } 200 if parser.doc.Packages[0].PackageName != p1Name { 201 t.Errorf("expected package name %s in Packages[package1], got %s", p1Name, parser.doc.Packages[0].PackageName) 202 } 203 // and the first Package's Files should be of size 1 and have f1 only 204 if len(parser.doc.Packages[0].Files) != 1 { 205 t.Errorf("Expected 1 file in Packages[package1].Files, got %d", len(parser.doc.Packages[0].Files)) 206 } 207 if parser.doc.Packages[0].Files[0] != f1 { 208 t.Errorf("Expected file %v in Files[f1], got %v", f1, parser.doc.Packages[0].Files[0]) 209 } 210 if parser.doc.Packages[0].Files[0].FileName != f1Name { 211 t.Errorf("expected file name %s in Files[f1], got %s", f1Name, parser.doc.Packages[0].Files[0].FileName) 212 } 213 // and the current file should be nil 214 if parser.file != nil { 215 t.Errorf("Expected nil for parser.file, got %v", parser.file) 216 } 217} 218 219func TestParser2_1FileMovesToSnippetAfterParsingSnippetSPDXIDTag(t *testing.T) { 220 parser := tvParser2_1{ 221 doc: &v2_1.Document{Packages: []*v2_1.Package{}}, 222 st: psFile2_1, 223 pkg: &v2_1.Package{PackageName: "test", PackageSPDXIdentifier: "test", Files: []*v2_1.File{}}, 224 file: &v2_1.File{FileName: "f1.txt", FileSPDXIdentifier: "f1"}, 225 } 226 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 227 parser.pkg.Files = append(parser.pkg.Files, parser.file) 228 fileCurrent := parser.file 229 230 err := parser.parsePair2_1("SnippetSPDXID", "SPDXRef-Test1") 231 if err != nil { 232 t.Errorf("got error when calling parsePair2_1: %v", err) 233 } 234 // state should be correct 235 if parser.st != psSnippet2_1 { 236 t.Errorf("expected state to be %v, got %v", psSnippet2_1, parser.st) 237 } 238 // and current file should remain what it was 239 if parser.file != fileCurrent { 240 t.Fatalf("expected file to remain %v, got %v", fileCurrent, parser.file) 241 } 242} 243 244func TestParser2_1FileMovesToOtherLicenseAfterParsingLicenseIDTag(t *testing.T) { 245 parser := tvParser2_1{ 246 doc: &v2_1.Document{Packages: []*v2_1.Package{}}, 247 st: psFile2_1, 248 pkg: &v2_1.Package{PackageName: "test", PackageSPDXIdentifier: "test", Files: []*v2_1.File{}}, 249 file: &v2_1.File{FileName: "f1.txt", FileSPDXIdentifier: "f1"}, 250 } 251 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 252 parser.pkg.Files = append(parser.pkg.Files, parser.file) 253 254 err := parser.parsePair2_1("LicenseID", "LicenseRef-TestLic") 255 if err != nil { 256 t.Errorf("got error when calling parsePair2_1: %v", err) 257 } 258 if parser.st != psOtherLicense2_1 { 259 t.Errorf("expected state to be %v, got %v", psOtherLicense2_1, parser.st) 260 } 261} 262 263func TestParser2_1FileMovesToReviewAfterParsingReviewerTag(t *testing.T) { 264 parser := tvParser2_1{ 265 doc: &v2_1.Document{Packages: []*v2_1.Package{}}, 266 st: psFile2_1, 267 pkg: &v2_1.Package{PackageName: "test", PackageSPDXIdentifier: "test", Files: []*v2_1.File{}}, 268 file: &v2_1.File{FileName: "f1.txt", FileSPDXIdentifier: "f1"}, 269 } 270 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 271 parser.pkg.Files = append(parser.pkg.Files, parser.file) 272 273 err := parser.parsePair2_1("Reviewer", "Person: John Doe") 274 if err != nil { 275 t.Errorf("got error when calling parsePair2_1: %v", err) 276 } 277 if parser.st != psReview2_1 { 278 t.Errorf("expected state to be %v, got %v", psReview2_1, parser.st) 279 } 280} 281 282func TestParser2_1FileStaysAfterParsingRelationshipTags(t *testing.T) { 283 parser := tvParser2_1{ 284 doc: &v2_1.Document{Packages: []*v2_1.Package{}}, 285 st: psFile2_1, 286 pkg: &v2_1.Package{PackageName: "test", PackageSPDXIdentifier: "test", Files: []*v2_1.File{}}, 287 file: &v2_1.File{FileName: "f1.txt", FileSPDXIdentifier: "f1"}, 288 } 289 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 290 parser.pkg.Files = append(parser.pkg.Files, parser.file) 291 292 err := parser.parsePair2_1("Relationship", "SPDXRef-blah CONTAINS SPDXRef-blah-else") 293 if err != nil { 294 t.Errorf("got error when calling parsePair2_1: %v", err) 295 } 296 // state should remain unchanged 297 if parser.st != psFile2_1 { 298 t.Errorf("expected state to be %v, got %v", psFile2_1, parser.st) 299 } 300 301 err = parser.parsePair2_1("RelationshipComment", "blah") 302 if err != nil { 303 t.Errorf("got error when calling parsePair2_1: %v", err) 304 } 305 // state should still remain unchanged 306 if parser.st != psFile2_1 { 307 t.Errorf("expected state to be %v, got %v", psFile2_1, parser.st) 308 } 309} 310 311func TestParser2_1FileStaysAfterParsingAnnotationTags(t *testing.T) { 312 parser := tvParser2_1{ 313 doc: &v2_1.Document{Packages: []*v2_1.Package{}}, 314 st: psFile2_1, 315 pkg: &v2_1.Package{PackageName: "test", PackageSPDXIdentifier: "test", Files: []*v2_1.File{}}, 316 file: &v2_1.File{FileName: "f1.txt", FileSPDXIdentifier: "f1"}, 317 } 318 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 319 parser.pkg.Files = append(parser.pkg.Files, parser.file) 320 321 err := parser.parsePair2_1("Annotator", "Person: John Doe ()") 322 if err != nil { 323 t.Errorf("got error when calling parsePair2_1: %v", err) 324 } 325 if parser.st != psFile2_1 { 326 t.Errorf("parser is in state %v, expected %v", parser.st, psFile2_1) 327 } 328 329 err = parser.parsePair2_1("AnnotationDate", "2018-09-15T00:36:00Z") 330 if err != nil { 331 t.Errorf("got error when calling parsePair2_1: %v", err) 332 } 333 if parser.st != psFile2_1 { 334 t.Errorf("parser is in state %v, expected %v", parser.st, psFile2_1) 335 } 336 337 err = parser.parsePair2_1("AnnotationType", "REVIEW") 338 if err != nil { 339 t.Errorf("got error when calling parsePair2_1: %v", err) 340 } 341 if parser.st != psFile2_1 { 342 t.Errorf("parser is in state %v, expected %v", parser.st, psFile2_1) 343 } 344 345 err = parser.parsePair2_1("SPDXREF", "SPDXRef-45") 346 if err != nil { 347 t.Errorf("got error when calling parsePair2_1: %v", err) 348 } 349 if parser.st != psFile2_1 { 350 t.Errorf("parser is in state %v, expected %v", parser.st, psFile2_1) 351 } 352 353 err = parser.parsePair2_1("AnnotationComment", "i guess i had something to say about this particular file") 354 if err != nil { 355 t.Errorf("got error when calling parsePair2_1: %v", err) 356 } 357 if parser.st != psFile2_1 { 358 t.Errorf("parser is in state %v, expected %v", parser.st, psFile2_1) 359 } 360} 361 362// ===== File data section tests ===== 363func TestParser2_1CanParseFileTags(t *testing.T) { 364 parser := tvParser2_1{ 365 doc: &v2_1.Document{Packages: []*v2_1.Package{}}, 366 st: psFile2_1, 367 pkg: &v2_1.Package{PackageName: "test", PackageSPDXIdentifier: "test", Files: []*v2_1.File{}}, 368 } 369 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 370 371 // File Name 372 err := parser.parsePairFromFile2_1("FileName", "f1.txt") 373 if err != nil { 374 t.Errorf("expected nil error, got %v", err) 375 } 376 if parser.file.FileName != "f1.txt" { 377 t.Errorf("got %v for FileName", parser.file.FileName) 378 } 379 // should not yet be added to the Packages file list, because we haven't 380 // seen an SPDX identifier yet 381 if len(parser.pkg.Files) != 0 { 382 t.Errorf("expected 0 files, got %d", len(parser.pkg.Files)) 383 } 384 385 // File SPDX Identifier 386 err = parser.parsePairFromFile2_1("SPDXID", "SPDXRef-f1") 387 if err != nil { 388 t.Errorf("expected nil error, got %v", err) 389 } 390 if parser.file.FileSPDXIdentifier != "f1" { 391 t.Errorf("got %v for FileSPDXIdentifier", parser.file.FileSPDXIdentifier) 392 } 393 // should now be added to the Packages file list 394 if len(parser.pkg.Files) != 1 { 395 t.Errorf("expected 1 file, got %d", len(parser.pkg.Files)) 396 } 397 if parser.pkg.Files[0] != parser.file { 398 t.Errorf("expected Files[f1] to be %v, got %v", parser.file, parser.pkg.Files[0]) 399 } 400 401 // File Type 402 fileTypes := []string{ 403 "TEXT", 404 "DOCUMENTATION", 405 } 406 for _, ty := range fileTypes { 407 err = parser.parsePairFromFile2_1("FileType", ty) 408 if err != nil { 409 t.Errorf("expected nil error, got %v", err) 410 } 411 } 412 for _, typeWant := range fileTypes { 413 flagFound := false 414 for _, typeCheck := range parser.file.FileTypes { 415 if typeWant == typeCheck { 416 flagFound = true 417 } 418 } 419 if flagFound == false { 420 t.Errorf("didn't find %s in FileTypes", typeWant) 421 } 422 } 423 if len(fileTypes) != len(parser.file.FileTypes) { 424 t.Errorf("expected %d types in FileTypes, got %d", len(fileTypes), 425 len(parser.file.FileTypes)) 426 } 427 428 // File Checksums 429 codeSha1 := "85ed0817af83a24ad8da68c2b5094de69833983c" 430 sumSha1 := "SHA1: 85ed0817af83a24ad8da68c2b5094de69833983c" 431 codeSha256 := "11b6d3ee554eedf79299905a98f9b9a04e498210b59f15094c916c91d150efcd" 432 sumSha256 := "SHA256: 11b6d3ee554eedf79299905a98f9b9a04e498210b59f15094c916c91d150efcd" 433 codeMd5 := "624c1abb3664f4b35547e7c73864ad24" 434 sumMd5 := "MD5: 624c1abb3664f4b35547e7c73864ad24" 435 err = parser.parsePairFromFile2_1("FileChecksum", sumSha1) 436 if err != nil { 437 t.Errorf("expected nil error, got %v", err) 438 } 439 err = parser.parsePairFromFile2_1("FileChecksum", sumSha256) 440 if err != nil { 441 t.Errorf("expected nil error, got %v", err) 442 } 443 err = parser.parsePairFromFile2_1("FileChecksum", sumMd5) 444 if err != nil { 445 t.Errorf("expected nil error, got %v", err) 446 } 447 for _, checksum := range parser.file.Checksums { 448 switch checksum.Algorithm { 449 case common.SHA1: 450 if checksum.Value != codeSha1 { 451 t.Errorf("expected %s for FileChecksumSHA1, got %s", codeSha1, checksum.Value) 452 } 453 case common.SHA256: 454 if checksum.Value != codeSha256 { 455 t.Errorf("expected %s for FileChecksumSHA1, got %s", codeSha256, checksum.Value) 456 } 457 case common.MD5: 458 if checksum.Value != codeMd5 { 459 t.Errorf("expected %s for FileChecksumSHA1, got %s", codeMd5, checksum.Value) 460 } 461 } 462 } 463 // Concluded License 464 err = parser.parsePairFromFile2_1("LicenseConcluded", "Apache-2.0 OR GPL-2.0-or-later") 465 if err != nil { 466 t.Errorf("expected nil error, got %v", err) 467 } 468 if parser.file.LicenseConcluded != "Apache-2.0 OR GPL-2.0-or-later" { 469 t.Errorf("got %v for LicenseConcluded", parser.file.LicenseConcluded) 470 } 471 472 // License Information in File 473 lics := []string{ 474 "Apache-2.0", 475 "GPL-2.0-or-later", 476 "CC0-1.0", 477 } 478 for _, lic := range lics { 479 err = parser.parsePairFromFile2_1("LicenseInfoInFile", lic) 480 if err != nil { 481 t.Errorf("expected nil error, got %v", err) 482 } 483 } 484 for _, licWant := range lics { 485 flagFound := false 486 for _, licCheck := range parser.file.LicenseInfoInFiles { 487 if licWant == licCheck { 488 flagFound = true 489 } 490 } 491 if flagFound == false { 492 t.Errorf("didn't find %s in LicenseInfoInFiles", licWant) 493 } 494 } 495 if len(lics) != len(parser.file.LicenseInfoInFiles) { 496 t.Errorf("expected %d licenses in LicenseInfoInFiles, got %d", len(lics), 497 len(parser.file.LicenseInfoInFiles)) 498 } 499 500 // Comments on License 501 err = parser.parsePairFromFile2_1("LicenseComments", "this is a comment") 502 if err != nil { 503 t.Errorf("expected nil error, got %v", err) 504 } 505 if parser.file.LicenseComments != "this is a comment" { 506 t.Errorf("got %v for LicenseComments", parser.file.LicenseComments) 507 } 508 509 // Copyright Text 510 err = parser.parsePairFromFile2_1("FileCopyrightText", "copyright (c) me") 511 if err != nil { 512 t.Errorf("expected nil error, got %v", err) 513 } 514 if parser.file.FileCopyrightText != "copyright (c) me" { 515 t.Errorf("got %v for FileCopyrightText", parser.file.FileCopyrightText) 516 } 517 518 // Artifact of Projects: Name, HomePage and URI 519 // Artifact set 1 520 err = parser.parsePairFromFile2_1("ArtifactOfProjectName", "project1") 521 if err != nil { 522 t.Errorf("expected nil error, got %v", err) 523 } 524 err = parser.parsePairFromFile2_1("ArtifactOfProjectHomePage", "http://example.com/1/") 525 if err != nil { 526 t.Errorf("expected nil error, got %v", err) 527 } 528 err = parser.parsePairFromFile2_1("ArtifactOfProjectURI", "http://example.com/1/uri.whatever") 529 if err != nil { 530 t.Errorf("expected nil error, got %v", err) 531 } 532 // Artifact set 2 -- just name 533 err = parser.parsePairFromFile2_1("ArtifactOfProjectName", "project2") 534 if err != nil { 535 t.Errorf("expected nil error, got %v", err) 536 } 537 // Artifact set 3 -- just name and home page 538 err = parser.parsePairFromFile2_1("ArtifactOfProjectName", "project3") 539 if err != nil { 540 t.Errorf("expected nil error, got %v", err) 541 } 542 err = parser.parsePairFromFile2_1("ArtifactOfProjectHomePage", "http://example.com/3/") 543 if err != nil { 544 t.Errorf("expected nil error, got %v", err) 545 } 546 // Artifact set 4 -- just name and URI 547 err = parser.parsePairFromFile2_1("ArtifactOfProjectName", "project4") 548 if err != nil { 549 t.Errorf("expected nil error, got %v", err) 550 } 551 err = parser.parsePairFromFile2_1("ArtifactOfProjectURI", "http://example.com/4/uri.whatever") 552 if err != nil { 553 t.Errorf("expected nil error, got %v", err) 554 } 555 556 if len(parser.file.ArtifactOfProjects) != 4 { 557 t.Fatalf("expected len %d, got %d", 4, len(parser.file.ArtifactOfProjects)) 558 } 559 560 aop := parser.file.ArtifactOfProjects[0] 561 if aop.Name != "project1" { 562 t.Errorf("expected %v, got %v", "project1", aop.Name) 563 } 564 if aop.HomePage != "http://example.com/1/" { 565 t.Errorf("expected %v, got %v", "http://example.com/1/", aop.HomePage) 566 } 567 if aop.URI != "http://example.com/1/uri.whatever" { 568 t.Errorf("expected %v, got %v", "http://example.com/1/uri.whatever", aop.URI) 569 } 570 571 aop = parser.file.ArtifactOfProjects[1] 572 if aop.Name != "project2" { 573 t.Errorf("expected %v, got %v", "project2", aop.Name) 574 } 575 if aop.HomePage != "" { 576 t.Errorf("expected %v, got %v", "", aop.HomePage) 577 } 578 if aop.URI != "" { 579 t.Errorf("expected %v, got %v", "", aop.URI) 580 } 581 582 aop = parser.file.ArtifactOfProjects[2] 583 if aop.Name != "project3" { 584 t.Errorf("expected %v, got %v", "project3", aop.Name) 585 } 586 if aop.HomePage != "http://example.com/3/" { 587 t.Errorf("expected %v, got %v", "http://example.com/3/", aop.HomePage) 588 } 589 if aop.URI != "" { 590 t.Errorf("expected %v, got %v", "", aop.URI) 591 } 592 593 aop = parser.file.ArtifactOfProjects[3] 594 if aop.Name != "project4" { 595 t.Errorf("expected %v, got %v", "project4", aop.Name) 596 } 597 if aop.HomePage != "" { 598 t.Errorf("expected %v, got %v", "", aop.HomePage) 599 } 600 if aop.URI != "http://example.com/4/uri.whatever" { 601 t.Errorf("expected %v, got %v", "http://example.com/4/uri.whatever", aop.URI) 602 } 603 604 // File Comment 605 err = parser.parsePairFromFile2_1("FileComment", "this is a comment") 606 if err != nil { 607 t.Errorf("expected nil error, got %v", err) 608 } 609 if parser.file.FileComment != "this is a comment" { 610 t.Errorf("got %v for FileComment", parser.file.FileComment) 611 } 612 613 // File Notice 614 err = parser.parsePairFromFile2_1("FileNotice", "this is a Notice") 615 if err != nil { 616 t.Errorf("expected nil error, got %v", err) 617 } 618 if parser.file.FileNotice != "this is a Notice" { 619 t.Errorf("got %v for FileNotice", parser.file.FileNotice) 620 } 621 622 // File Contributor 623 contribs := []string{ 624 "John Doe [email protected]", 625 "EvilCorp", 626 } 627 for _, contrib := range contribs { 628 err = parser.parsePairFromFile2_1("FileContributor", contrib) 629 if err != nil { 630 t.Errorf("expected nil error, got %v", err) 631 } 632 } 633 for _, contribWant := range contribs { 634 flagFound := false 635 for _, contribCheck := range parser.file.FileContributors { 636 if contribWant == contribCheck { 637 flagFound = true 638 } 639 } 640 if flagFound == false { 641 t.Errorf("didn't find %s in FileContributors", contribWant) 642 } 643 } 644 if len(contribs) != len(parser.file.FileContributors) { 645 t.Errorf("expected %d contribenses in FileContributors, got %d", len(contribs), 646 len(parser.file.FileContributors)) 647 } 648 649 // File Dependencies 650 deps := []string{ 651 "f-1.txt", 652 "g.txt", 653 } 654 for _, dep := range deps { 655 err = parser.parsePairFromFile2_1("FileDependency", dep) 656 if err != nil { 657 t.Errorf("expected nil error, got %v", err) 658 } 659 } 660 for _, depWant := range deps { 661 flagFound := false 662 for _, depCheck := range parser.file.FileDependencies { 663 if depWant == depCheck { 664 flagFound = true 665 } 666 } 667 if flagFound == false { 668 t.Errorf("didn't find %s in FileDependency", depWant) 669 } 670 } 671 if len(deps) != len(parser.file.FileDependencies) { 672 t.Errorf("expected %d depenses in FileDependency, got %d", len(deps), 673 len(parser.file.FileDependencies)) 674 } 675 676} 677 678func TestParser2_1FileCreatesRelationshipInDocument(t *testing.T) { 679 parser := tvParser2_1{ 680 doc: &v2_1.Document{Packages: []*v2_1.Package{}}, 681 st: psFile2_1, 682 pkg: &v2_1.Package{PackageName: "test", PackageSPDXIdentifier: "test", Files: []*v2_1.File{}}, 683 file: &v2_1.File{FileName: "f1.txt", FileSPDXIdentifier: "f1"}, 684 } 685 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 686 parser.pkg.Files = append(parser.pkg.Files, parser.file) 687 688 err := parser.parsePair2_1("Relationship", "SPDXRef-blah CONTAINS SPDXRef-blah-whatever") 689 if err != nil { 690 t.Errorf("got error when calling parsePair2_1: %v", err) 691 } 692 if parser.rln == nil { 693 t.Fatalf("parser didn't create and point to Relationship struct") 694 } 695 if parser.rln != parser.doc.Relationships[0] { 696 t.Errorf("pointer to new Relationship doesn't match idx 0 for doc.Relationships[]") 697 } 698} 699 700func TestParser2_1FileCreatesAnnotationInDocument(t *testing.T) { 701 parser := tvParser2_1{ 702 doc: &v2_1.Document{Packages: []*v2_1.Package{}}, 703 st: psFile2_1, 704 pkg: &v2_1.Package{PackageName: "test", PackageSPDXIdentifier: "test", Files: []*v2_1.File{}}, 705 file: &v2_1.File{FileName: "f1.txt", FileSPDXIdentifier: "f1"}, 706 } 707 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 708 parser.pkg.Files = append(parser.pkg.Files, parser.file) 709 710 err := parser.parsePair2_1("Annotator", "Person: John Doe ()") 711 if err != nil { 712 t.Errorf("got error when calling parsePair2_1: %v", err) 713 } 714 if parser.ann == nil { 715 t.Fatalf("parser didn't create and point to Annotation struct") 716 } 717 if parser.ann != parser.doc.Annotations[0] { 718 t.Errorf("pointer to new Annotation doesn't match idx 0 for doc.Annotations[]") 719 } 720} 721 722func TestParser2_1FileUnknownTagFails(t *testing.T) { 723 parser := tvParser2_1{ 724 doc: &v2_1.Document{Packages: []*v2_1.Package{}}, 725 st: psFile2_1, 726 pkg: &v2_1.Package{PackageName: "test", PackageSPDXIdentifier: "test", Files: []*v2_1.File{}}, 727 file: &v2_1.File{FileName: "f1.txt", FileSPDXIdentifier: "f1"}, 728 } 729 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 730 parser.pkg.Files = append(parser.pkg.Files, parser.file) 731 732 err := parser.parsePairFromFile2_1("blah", "something") 733 if err == nil { 734 t.Errorf("expected error from parsing unknown tag") 735 } 736} 737 738func TestFileAOPPointerChangesAfterTags(t *testing.T) { 739 parser := tvParser2_1{ 740 doc: &v2_1.Document{Packages: []*v2_1.Package{}}, 741 st: psFile2_1, 742 pkg: &v2_1.Package{PackageName: "test", PackageSPDXIdentifier: "test", Files: []*v2_1.File{}}, 743 file: &v2_1.File{FileName: "f1.txt", FileSPDXIdentifier: "f1"}, 744 } 745 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 746 parser.pkg.Files = append(parser.pkg.Files, parser.file) 747 748 err := parser.parsePairFromFile2_1("ArtifactOfProjectName", "project1") 749 if err != nil { 750 t.Errorf("expected nil error, got %v", err) 751 } 752 if parser.fileAOP == nil { 753 t.Errorf("expected non-nil AOP pointer, got nil") 754 } 755 curPtr := parser.fileAOP 756 757 // now, a home page; pointer should stay 758 err = parser.parsePairFromFile2_1("ArtifactOfProjectHomePage", "http://example.com/1/") 759 if err != nil { 760 t.Errorf("expected nil error, got %v", err) 761 } 762 if parser.fileAOP != curPtr { 763 t.Errorf("expected no change in AOP pointer, was %v, got %v", curPtr, parser.fileAOP) 764 } 765 766 // a URI; pointer should stay 767 err = parser.parsePairFromFile2_1("ArtifactOfProjectURI", "http://example.com/1/uri.whatever") 768 if err != nil { 769 t.Errorf("expected nil error, got %v", err) 770 } 771 if parser.fileAOP != curPtr { 772 t.Errorf("expected no change in AOP pointer, was %v, got %v", curPtr, parser.fileAOP) 773 } 774 775 // now, another artifact name; pointer should change but be non-nil 776 // now, a home page; pointer should stay 777 err = parser.parsePairFromFile2_1("ArtifactOfProjectName", "project2") 778 if err != nil { 779 t.Errorf("expected nil error, got %v", err) 780 } 781 if parser.fileAOP == curPtr { 782 t.Errorf("expected change in AOP pointer, got no change") 783 } 784 785 // finally, an unrelated tag; pointer should go away 786 err = parser.parsePairFromFile2_1("FileComment", "whatever") 787 if err != nil { 788 t.Errorf("expected nil error, got %v", err) 789 } 790 if parser.fileAOP != nil { 791 t.Errorf("expected nil AOP pointer, got %v", parser.fileAOP) 792 } 793} 794 795func TestParser2_1FailsIfInvalidSPDXIDInFileSection(t *testing.T) { 796 parser := tvParser2_1{ 797 doc: &v2_1.Document{Packages: []*v2_1.Package{}}, 798 st: psFile2_1, 799 pkg: &v2_1.Package{PackageName: "test", PackageSPDXIdentifier: "test", Files: []*v2_1.File{}}, 800 } 801 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 802 803 // start with File Name 804 err := parser.parsePairFromFile2_1("FileName", "f1.txt") 805 if err != nil { 806 t.Errorf("expected nil error, got %v", err) 807 } 808 // invalid SPDX Identifier 809 err = parser.parsePairFromFile2_1("SPDXID", "whoops") 810 if err == nil { 811 t.Errorf("expected non-nil error, got nil") 812 } 813} 814 815func TestParser2_1FailsIfInvalidChecksumFormatInFileSection(t *testing.T) { 816 parser := tvParser2_1{ 817 doc: &v2_1.Document{Packages: []*v2_1.Package{}}, 818 st: psFile2_1, 819 pkg: &v2_1.Package{PackageName: "test", PackageSPDXIdentifier: "test", Files: []*v2_1.File{}}, 820 } 821 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 822 823 // start with File Name 824 err := parser.parsePairFromFile2_1("FileName", "f1.txt") 825 if err != nil { 826 t.Errorf("expected nil error, got %v", err) 827 } 828 // invalid format for checksum line, missing colon 829 err = parser.parsePairFromFile2_1("FileChecksum", "SHA1 85ed0817af83a24ad8da68c2b5094de69833983c") 830 if err == nil { 831 t.Errorf("expected non-nil error, got nil") 832 } 833} 834 835func TestParser2_1FailsIfUnknownChecksumTypeInFileSection(t *testing.T) { 836 parser := tvParser2_1{ 837 doc: &v2_1.Document{Packages: []*v2_1.Package{}}, 838 st: psFile2_1, 839 pkg: &v2_1.Package{PackageName: "test", PackageSPDXIdentifier: "test", Files: []*v2_1.File{}}, 840 } 841 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 842 843 // start with File Name 844 err := parser.parsePairFromFile2_1("FileName", "f1.txt") 845 if err != nil { 846 t.Errorf("expected nil error, got %v", err) 847 } 848 // unknown checksum type 849 err = parser.parsePairFromFile2_1("FileChecksum", "Special: 85ed0817af83a24ad8da68c2b5094de69833983c") 850 if err == nil { 851 t.Errorf("expected non-nil error, got nil") 852 } 853} 854 855func TestParser2_1FailsIfArtifactHomePageBeforeArtifactName(t *testing.T) { 856 parser := tvParser2_1{ 857 doc: &v2_1.Document{Packages: []*v2_1.Package{}}, 858 st: psFile2_1, 859 pkg: &v2_1.Package{PackageName: "test", PackageSPDXIdentifier: "test", Files: []*v2_1.File{}}, 860 } 861 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 862 863 // start with File Name 864 err := parser.parsePairFromFile2_1("FileName", "f1.txt") 865 if err != nil { 866 t.Errorf("expected nil error, got %v", err) 867 } 868 // artifact home page appears before artifact name 869 err = parser.parsePairFromFile2_1("ArtifactOfProjectHomePage", "https://example.com") 870 if err == nil { 871 t.Errorf("expected non-nil error, got nil") 872 } 873} 874 875func TestParser2_1FailsIfArtifactURIBeforeArtifactName(t *testing.T) { 876 parser := tvParser2_1{ 877 doc: &v2_1.Document{Packages: []*v2_1.Package{}}, 878 st: psFile2_1, 879 pkg: &v2_1.Package{PackageName: "test", PackageSPDXIdentifier: "test", Files: []*v2_1.File{}}, 880 } 881 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 882 883 // start with File Name 884 err := parser.parsePairFromFile2_1("FileName", "f1.txt") 885 if err != nil { 886 t.Errorf("expected nil error, got %v", err) 887 } 888 // artifact home page appears before artifact name 889 err = parser.parsePairFromFile2_1("ArtifactOfProjectURI", "https://example.com") 890 if err == nil { 891 t.Errorf("expected non-nil error, got nil") 892 } 893} 894 895func TestParser2_1FilesWithoutSpdxIdThrowError(t *testing.T) { 896 // case 1: The previous file (packaged or unpackaged) does not contain spdxID 897 parser1 := tvParser2_1{ 898 doc: &v2_1.Document{Packages: []*v2_1.Package{}}, 899 st: psFile2_1, 900 file: &v2_1.File{FileName: "FileName"}, 901 } 902 903 err := parser1.parsePair2_1("FileName", "f2") 904 if err == nil { 905 t.Errorf("file without SPDX Identifier getting accepted") 906 } 907 908 // case 2: Invalid file with snippet 909 // Last unpackaged file before a snippet starts 910 sid1 := common.ElementID("s1") 911 fileName := "f2.txt" 912 parser2 := tvParser2_1{ 913 doc: &v2_1.Document{}, 914 st: psCreationInfo2_1, 915 file: &v2_1.File{FileName: fileName}, 916 } 917 err = parser2.parsePair2_1("SnippetSPDXID", string(sid1)) 918 if err == nil { 919 t.Errorf("file without SPDX Identifier getting accepted") 920 } 921 922 // case 3 : Invalid File without snippets 923 // Last unpackaged file before a package starts 924 // Last file of a package and New package starts 925 parser3 := tvParser2_1{ 926 doc: &v2_1.Document{}, 927 st: psCreationInfo2_1, 928 } 929 fileName = "f3.txt" 930 err = parser3.parsePair2_1("FileName", fileName) 931 if err != nil { 932 t.Errorf("%s", err) 933 } 934 err = parser3.parsePair2_1("PackageName", "p2") 935 if err == nil { 936 t.Errorf("files withoutSpdx Identifier getting accepted") 937 } 938} 939