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