github.com/google/osv-scalibr@v0.4.1/extractor/filesystem/language/javascript/bunlock/bunlock_test.go (about) 1 // Copyright 2025 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package bunlock_test 16 17 import ( 18 "testing" 19 20 "github.com/google/go-cmp/cmp" 21 "github.com/google/go-cmp/cmp/cmpopts" 22 "github.com/google/osv-scalibr/extractor" 23 "github.com/google/osv-scalibr/extractor/filesystem/language/javascript/bunlock" 24 "github.com/google/osv-scalibr/extractor/filesystem/osv" 25 "github.com/google/osv-scalibr/extractor/filesystem/simplefileapi" 26 "github.com/google/osv-scalibr/inventory" 27 "github.com/google/osv-scalibr/purl" 28 "github.com/google/osv-scalibr/testing/extracttest" 29 ) 30 31 func TestExtractor_FileRequired(t *testing.T) { 32 tests := []struct { 33 name string 34 inputPath string 35 want bool 36 }{ 37 { 38 name: "", 39 inputPath: "", 40 want: false, 41 }, 42 { 43 name: "", 44 inputPath: "bun.lock", 45 want: true, 46 }, 47 { 48 name: "", 49 inputPath: "path/to/my/bun.lock", 50 want: true, 51 }, 52 { 53 name: "", 54 inputPath: "path/to/my/bun.lock/file", 55 want: false, 56 }, 57 { 58 name: "", 59 inputPath: "path/to/my/bun.lock.file", 60 want: false, 61 }, 62 { 63 name: "", 64 inputPath: "path.to.my.bun.lock", 65 want: false, 66 }, 67 { 68 name: "", 69 inputPath: "foo/node_modules/bar/bun.lock", 70 want: false, 71 }, 72 } 73 for _, tt := range tests { 74 t.Run(tt.name, func(t *testing.T) { 75 e := bunlock.Extractor{} 76 got := e.FileRequired(simplefileapi.New(tt.inputPath, nil)) 77 if got != tt.want { 78 t.Errorf("FileRequired(%s, FileInfo) got = %v, want %v", tt.inputPath, got, tt.want) 79 } 80 }) 81 } 82 } 83 84 func TestExtractor_Extract(t *testing.T) { 85 tests := []extracttest.TestTableEntry{ 86 { 87 Name: "invalid json", 88 InputConfig: extracttest.ScanInputMockConfig{ 89 Path: "testdata/not-json.txt", 90 }, 91 WantErr: extracttest.ContainsErrStr{Str: "could not extract"}, 92 WantPackages: nil, 93 }, 94 { 95 Name: "empty", 96 InputConfig: extracttest.ScanInputMockConfig{ 97 Path: "testdata/empty.json5", 98 }, 99 WantPackages: []*extractor.Package{}, 100 }, 101 { 102 Name: "no packages", 103 InputConfig: extracttest.ScanInputMockConfig{ 104 Path: "testdata/no-packages.json5", 105 }, 106 WantPackages: []*extractor.Package{}, 107 }, 108 { 109 Name: "one package", 110 InputConfig: extracttest.ScanInputMockConfig{ 111 Path: "testdata/one-package.json5", 112 }, 113 WantPackages: []*extractor.Package{ 114 { 115 Name: "wrappy", 116 Version: "1.0.2", 117 PURLType: purl.TypeNPM, 118 Locations: []string{"testdata/one-package.json5"}, 119 SourceCode: &extractor.SourceCodeIdentifier{}, 120 Metadata: osv.DepGroupMetadata{ 121 DepGroupVals: []string{}, 122 }, 123 }, 124 }, 125 }, 126 { 127 Name: "one package dev", 128 InputConfig: extracttest.ScanInputMockConfig{ 129 Path: "testdata/one-package-dev.json5", 130 }, 131 WantPackages: []*extractor.Package{ 132 { 133 Name: "wrappy", 134 Version: "1.0.2", 135 PURLType: purl.TypeNPM, 136 Locations: []string{"testdata/one-package-dev.json5"}, 137 SourceCode: &extractor.SourceCodeIdentifier{}, 138 Metadata: osv.DepGroupMetadata{ 139 DepGroupVals: []string{}, 140 }, 141 }, 142 }, 143 }, 144 { 145 Name: "one package with bad tuple (first error)", 146 InputConfig: extracttest.ScanInputMockConfig{ 147 Path: "testdata/bad-tuple.json5", 148 }, 149 WantErr: extracttest.ContainsErrStr{Str: "could not extract 'wrappy-bad1'"}, 150 WantPackages: []*extractor.Package{ 151 { 152 Name: "wrappy", 153 Version: "1.0.2", 154 PURLType: purl.TypeNPM, 155 Locations: []string{"testdata/bad-tuple.json5"}, 156 SourceCode: &extractor.SourceCodeIdentifier{}, 157 Metadata: osv.DepGroupMetadata{ 158 DepGroupVals: []string{}, 159 }, 160 }, 161 }, 162 }, 163 { 164 Name: "one package with bad tuple (second error)", 165 InputConfig: extracttest.ScanInputMockConfig{ 166 Path: "testdata/bad-tuple.json5", 167 }, 168 WantErr: extracttest.ContainsErrStr{Str: "could not extract 'wrappy-bad2'"}, 169 WantPackages: []*extractor.Package{ 170 { 171 Name: "wrappy", 172 Version: "1.0.2", 173 PURLType: purl.TypeNPM, 174 Locations: []string{"testdata/bad-tuple.json5"}, 175 SourceCode: &extractor.SourceCodeIdentifier{}, 176 Metadata: osv.DepGroupMetadata{ 177 DepGroupVals: []string{}, 178 }, 179 }, 180 }, 181 }, 182 { 183 Name: "two packages", 184 InputConfig: extracttest.ScanInputMockConfig{ 185 Path: "testdata/two-packages.json5", 186 }, 187 WantPackages: []*extractor.Package{ 188 { 189 Name: "has-flag", 190 Version: "4.0.0", 191 PURLType: purl.TypeNPM, 192 Locations: []string{"testdata/two-packages.json5"}, 193 SourceCode: &extractor.SourceCodeIdentifier{}, 194 Metadata: osv.DepGroupMetadata{ 195 DepGroupVals: []string{}, 196 }, 197 }, 198 { 199 Name: "wrappy", 200 Version: "1.0.2", 201 PURLType: purl.TypeNPM, 202 Locations: []string{"testdata/two-packages.json5"}, 203 SourceCode: &extractor.SourceCodeIdentifier{}, 204 Metadata: osv.DepGroupMetadata{ 205 DepGroupVals: []string{}, 206 }, 207 }, 208 }, 209 }, 210 { 211 Name: "same package in different groups", 212 InputConfig: extracttest.ScanInputMockConfig{ 213 Path: "testdata/same-package-different-groups.json5", 214 }, 215 WantPackages: []*extractor.Package{ 216 { 217 Name: "has-flag", 218 Version: "3.0.0", 219 PURLType: purl.TypeNPM, 220 Locations: []string{"testdata/same-package-different-groups.json5"}, 221 SourceCode: &extractor.SourceCodeIdentifier{}, 222 Metadata: osv.DepGroupMetadata{ 223 DepGroupVals: []string{}, 224 }, 225 }, 226 { 227 Name: "supports-color", 228 Version: "5.5.0", 229 PURLType: purl.TypeNPM, 230 Locations: []string{"testdata/same-package-different-groups.json5"}, 231 SourceCode: &extractor.SourceCodeIdentifier{}, 232 Metadata: osv.DepGroupMetadata{ 233 DepGroupVals: []string{}, 234 }, 235 }, 236 }, 237 }, 238 { 239 Name: "scoped packages", 240 InputConfig: extracttest.ScanInputMockConfig{ 241 Path: "testdata/scoped-packages.json5", 242 }, 243 WantPackages: []*extractor.Package{ 244 { 245 Name: "@typescript-eslint/types", 246 Version: "5.62.0", 247 PURLType: purl.TypeNPM, 248 Locations: []string{"testdata/scoped-packages.json5"}, 249 SourceCode: &extractor.SourceCodeIdentifier{}, 250 Metadata: osv.DepGroupMetadata{ 251 DepGroupVals: []string{}, 252 }, 253 }, 254 }, 255 }, 256 { 257 Name: "scoped packages mixed", 258 InputConfig: extracttest.ScanInputMockConfig{ 259 Path: "testdata/scoped-packages-mixed.json5", 260 }, 261 WantPackages: []*extractor.Package{ 262 { 263 Name: "@babel/code-frame", 264 Version: "7.26.2", 265 PURLType: purl.TypeNPM, 266 Locations: []string{"testdata/scoped-packages-mixed.json5"}, 267 SourceCode: &extractor.SourceCodeIdentifier{}, 268 Metadata: osv.DepGroupMetadata{ 269 DepGroupVals: []string{}, 270 }, 271 }, 272 { 273 Name: "@babel/helper-validator-identifier", 274 Version: "7.25.9", 275 PURLType: purl.TypeNPM, 276 Locations: []string{"testdata/scoped-packages-mixed.json5"}, 277 SourceCode: &extractor.SourceCodeIdentifier{}, 278 Metadata: osv.DepGroupMetadata{ 279 DepGroupVals: []string{}, 280 }, 281 }, 282 { 283 Name: "js-tokens", 284 Version: "4.0.0", 285 PURLType: purl.TypeNPM, 286 Locations: []string{"testdata/scoped-packages-mixed.json5"}, 287 SourceCode: &extractor.SourceCodeIdentifier{}, 288 Metadata: osv.DepGroupMetadata{ 289 DepGroupVals: []string{}, 290 }, 291 }, 292 { 293 Name: "picocolors", 294 Version: "1.1.1", 295 PURLType: purl.TypeNPM, 296 Locations: []string{"testdata/scoped-packages-mixed.json5"}, 297 SourceCode: &extractor.SourceCodeIdentifier{}, 298 Metadata: osv.DepGroupMetadata{ 299 DepGroupVals: []string{}, 300 }, 301 }, 302 { 303 Name: "wrappy", 304 Version: "1.0.2", 305 PURLType: purl.TypeNPM, 306 Locations: []string{"testdata/scoped-packages-mixed.json5"}, 307 SourceCode: &extractor.SourceCodeIdentifier{}, 308 Metadata: osv.DepGroupMetadata{ 309 DepGroupVals: []string{}, 310 }, 311 }, 312 }, 313 }, 314 { 315 Name: "optional package", 316 InputConfig: extracttest.ScanInputMockConfig{ 317 Path: "testdata/optional-package.json5", 318 }, 319 WantPackages: []*extractor.Package{ 320 { 321 Name: "acorn", 322 Version: "8.14.0", 323 PURLType: purl.TypeNPM, 324 Locations: []string{"testdata/optional-package.json5"}, 325 SourceCode: &extractor.SourceCodeIdentifier{}, 326 Metadata: osv.DepGroupMetadata{ 327 DepGroupVals: []string{}, 328 }, 329 }, 330 { 331 Name: "fsevents", 332 Version: "0.3.8", 333 PURLType: purl.TypeNPM, 334 Locations: []string{"testdata/optional-package.json5"}, 335 SourceCode: &extractor.SourceCodeIdentifier{}, 336 Metadata: osv.DepGroupMetadata{ 337 DepGroupVals: []string{}, 338 }, 339 }, 340 { 341 Name: "nan", 342 Version: "2.22.0", 343 PURLType: purl.TypeNPM, 344 Locations: []string{"testdata/optional-package.json5"}, 345 SourceCode: &extractor.SourceCodeIdentifier{}, 346 Metadata: osv.DepGroupMetadata{ 347 DepGroupVals: []string{}, 348 }, 349 }, 350 }, 351 }, 352 { 353 Name: "peer dependencies implicit", 354 InputConfig: extracttest.ScanInputMockConfig{ 355 Path: "testdata/peer-dependencies-implicit.json5", 356 }, 357 WantPackages: []*extractor.Package{ 358 { 359 Name: "acorn-jsx", 360 Version: "5.3.2", 361 PURLType: purl.TypeNPM, 362 Locations: []string{"testdata/peer-dependencies-implicit.json5"}, 363 SourceCode: &extractor.SourceCodeIdentifier{}, 364 Metadata: osv.DepGroupMetadata{ 365 DepGroupVals: []string{}, 366 }, 367 }, 368 { 369 Name: "acorn", 370 Version: "8.14.0", 371 PURLType: purl.TypeNPM, 372 Locations: []string{"testdata/peer-dependencies-implicit.json5"}, 373 SourceCode: &extractor.SourceCodeIdentifier{}, 374 Metadata: osv.DepGroupMetadata{ 375 DepGroupVals: []string{}, 376 }, 377 }, 378 }, 379 }, 380 { 381 Name: "peer dependencies explicit", 382 InputConfig: extracttest.ScanInputMockConfig{ 383 Path: "testdata/peer-dependencies-explicit.json5", 384 }, 385 WantPackages: []*extractor.Package{ 386 { 387 Name: "acorn-jsx", 388 Version: "5.3.2", 389 PURLType: purl.TypeNPM, 390 Locations: []string{"testdata/peer-dependencies-explicit.json5"}, 391 SourceCode: &extractor.SourceCodeIdentifier{}, 392 Metadata: osv.DepGroupMetadata{ 393 DepGroupVals: []string{}, 394 }, 395 }, 396 { 397 Name: "acorn", 398 Version: "8.14.0", 399 PURLType: purl.TypeNPM, 400 Locations: []string{"testdata/peer-dependencies-explicit.json5"}, 401 SourceCode: &extractor.SourceCodeIdentifier{}, 402 Metadata: osv.DepGroupMetadata{ 403 DepGroupVals: []string{}, 404 }, 405 }, 406 }, 407 }, 408 { 409 Name: "nested dependencies", 410 InputConfig: extracttest.ScanInputMockConfig{ 411 Path: "testdata/nested-dependencies.json5", 412 }, 413 WantPackages: []*extractor.Package{ 414 { 415 Name: "ansi-styles", 416 Version: "4.3.0", 417 PURLType: purl.TypeNPM, 418 Locations: []string{"testdata/nested-dependencies.json5"}, 419 SourceCode: &extractor.SourceCodeIdentifier{}, 420 Metadata: osv.DepGroupMetadata{ 421 DepGroupVals: []string{}, 422 }, 423 }, 424 { 425 Name: "chalk", 426 Version: "4.1.2", 427 PURLType: purl.TypeNPM, 428 Locations: []string{"testdata/nested-dependencies.json5"}, 429 SourceCode: &extractor.SourceCodeIdentifier{}, 430 Metadata: osv.DepGroupMetadata{ 431 DepGroupVals: []string{}, 432 }, 433 }, 434 { 435 Name: "color-convert", 436 Version: "2.0.1", 437 PURLType: purl.TypeNPM, 438 Locations: []string{"testdata/nested-dependencies.json5"}, 439 SourceCode: &extractor.SourceCodeIdentifier{}, 440 Metadata: osv.DepGroupMetadata{ 441 DepGroupVals: []string{}, 442 }, 443 }, 444 { 445 Name: "color-name", 446 Version: "1.1.4", 447 PURLType: purl.TypeNPM, 448 Locations: []string{"testdata/nested-dependencies.json5"}, 449 SourceCode: &extractor.SourceCodeIdentifier{}, 450 Metadata: osv.DepGroupMetadata{ 451 DepGroupVals: []string{}, 452 }, 453 }, 454 { 455 Name: "has-flag", 456 Version: "2.0.0", 457 PURLType: purl.TypeNPM, 458 Locations: []string{"testdata/nested-dependencies.json5"}, 459 SourceCode: &extractor.SourceCodeIdentifier{}, 460 Metadata: osv.DepGroupMetadata{ 461 DepGroupVals: []string{}, 462 }, 463 }, 464 { 465 Name: "supports-color", 466 Version: "5.5.0", 467 PURLType: purl.TypeNPM, 468 Locations: []string{"testdata/nested-dependencies.json5"}, 469 SourceCode: &extractor.SourceCodeIdentifier{}, 470 Metadata: osv.DepGroupMetadata{ 471 DepGroupVals: []string{}, 472 }, 473 }, 474 { 475 Name: "supports-color", 476 Version: "7.2.0", 477 PURLType: purl.TypeNPM, 478 Locations: []string{"testdata/nested-dependencies.json5"}, 479 SourceCode: &extractor.SourceCodeIdentifier{}, 480 Metadata: osv.DepGroupMetadata{ 481 DepGroupVals: []string{}, 482 }, 483 }, 484 { 485 Name: "has-flag", 486 Version: "3.0.0", 487 PURLType: purl.TypeNPM, 488 Locations: []string{"testdata/nested-dependencies.json5"}, 489 SourceCode: &extractor.SourceCodeIdentifier{}, 490 Metadata: osv.DepGroupMetadata{ 491 DepGroupVals: []string{}, 492 }, 493 }, 494 { 495 Name: "has-flag", 496 Version: "4.0.0", 497 PURLType: purl.TypeNPM, 498 Locations: []string{"testdata/nested-dependencies.json5"}, 499 SourceCode: &extractor.SourceCodeIdentifier{}, 500 Metadata: osv.DepGroupMetadata{ 501 DepGroupVals: []string{}, 502 }, 503 }, 504 }, 505 }, 506 { 507 Name: "nested dependencies with duplicate versions", 508 InputConfig: extracttest.ScanInputMockConfig{ 509 Path: "testdata/nested-dependencies-dup.json5", 510 }, 511 WantPackages: []*extractor.Package{ 512 { 513 Name: "ansi-styles", 514 Version: "4.3.0", 515 PURLType: purl.TypeNPM, 516 Locations: []string{"testdata/nested-dependencies-dup.json5"}, 517 SourceCode: &extractor.SourceCodeIdentifier{}, 518 Metadata: osv.DepGroupMetadata{ 519 DepGroupVals: []string{}, 520 }, 521 }, 522 { 523 Name: "chalk", 524 Version: "4.1.2", 525 PURLType: purl.TypeNPM, 526 Locations: []string{"testdata/nested-dependencies-dup.json5"}, 527 SourceCode: &extractor.SourceCodeIdentifier{}, 528 Metadata: osv.DepGroupMetadata{ 529 DepGroupVals: []string{}, 530 }, 531 }, 532 { 533 Name: "color-convert", 534 Version: "2.0.1", 535 PURLType: purl.TypeNPM, 536 Locations: []string{"testdata/nested-dependencies-dup.json5"}, 537 SourceCode: &extractor.SourceCodeIdentifier{}, 538 Metadata: osv.DepGroupMetadata{ 539 DepGroupVals: []string{}, 540 }, 541 }, 542 { 543 Name: "color-name", 544 Version: "1.1.4", 545 PURLType: purl.TypeNPM, 546 Locations: []string{"testdata/nested-dependencies-dup.json5"}, 547 SourceCode: &extractor.SourceCodeIdentifier{}, 548 Metadata: osv.DepGroupMetadata{ 549 DepGroupVals: []string{}, 550 }, 551 }, 552 { 553 Name: "has-flag", 554 Version: "2.0.0", 555 PURLType: purl.TypeNPM, 556 Locations: []string{"testdata/nested-dependencies-dup.json5"}, 557 SourceCode: &extractor.SourceCodeIdentifier{}, 558 Metadata: osv.DepGroupMetadata{ 559 DepGroupVals: []string{}, 560 }, 561 }, 562 { 563 Name: "supports-color", 564 Version: "7.2.0", 565 PURLType: purl.TypeNPM, 566 Locations: []string{"testdata/nested-dependencies-dup.json5"}, 567 SourceCode: &extractor.SourceCodeIdentifier{}, 568 Metadata: osv.DepGroupMetadata{ 569 DepGroupVals: []string{}, 570 }, 571 }, 572 { 573 Name: "has-flag", 574 Version: "4.0.0", 575 PURLType: purl.TypeNPM, 576 Locations: []string{"testdata/nested-dependencies-dup.json5"}, 577 SourceCode: &extractor.SourceCodeIdentifier{}, 578 Metadata: osv.DepGroupMetadata{ 579 DepGroupVals: []string{}, 580 }, 581 }, 582 }, 583 }, 584 { 585 Name: "alias", 586 InputConfig: extracttest.ScanInputMockConfig{ 587 Path: "testdata/alias.json5", 588 }, 589 WantPackages: []*extractor.Package{ 590 { 591 Name: "has-flag", 592 Version: "4.0.0", 593 PURLType: purl.TypeNPM, 594 Locations: []string{"testdata/alias.json5"}, 595 SourceCode: &extractor.SourceCodeIdentifier{}, 596 Metadata: osv.DepGroupMetadata{ 597 DepGroupVals: []string{}, 598 }, 599 }, 600 { 601 Name: "supports-color", 602 Version: "7.2.0", 603 PURLType: purl.TypeNPM, 604 Locations: []string{"testdata/alias.json5"}, 605 SourceCode: &extractor.SourceCodeIdentifier{}, 606 Metadata: osv.DepGroupMetadata{ 607 DepGroupVals: []string{}, 608 }, 609 }, 610 { 611 Name: "supports-color", 612 Version: "6.1.0", 613 PURLType: purl.TypeNPM, 614 Locations: []string{"testdata/alias.json5"}, 615 SourceCode: &extractor.SourceCodeIdentifier{}, 616 Metadata: osv.DepGroupMetadata{ 617 DepGroupVals: []string{}, 618 }, 619 }, 620 { 621 Name: "has-flag", 622 Version: "3.0.0", 623 PURLType: purl.TypeNPM, 624 Locations: []string{"testdata/alias.json5"}, 625 SourceCode: &extractor.SourceCodeIdentifier{}, 626 Metadata: osv.DepGroupMetadata{ 627 DepGroupVals: []string{}, 628 }, 629 }, 630 }, 631 }, 632 { 633 Name: "commits", 634 InputConfig: extracttest.ScanInputMockConfig{ 635 Path: "testdata/commits.json5", 636 }, 637 WantPackages: []*extractor.Package{ 638 { 639 Name: "@babel/helper-plugin-utils", 640 Version: "7.26.5", 641 PURLType: purl.TypeNPM, 642 Locations: []string{"testdata/commits.json5"}, 643 SourceCode: &extractor.SourceCodeIdentifier{}, 644 Metadata: osv.DepGroupMetadata{ 645 DepGroupVals: []string{}, 646 }, 647 }, 648 { 649 Name: "@babel/helper-string-parser", 650 Version: "7.25.9", 651 PURLType: purl.TypeNPM, 652 Locations: []string{"testdata/commits.json5"}, 653 SourceCode: &extractor.SourceCodeIdentifier{}, 654 Metadata: osv.DepGroupMetadata{ 655 DepGroupVals: []string{}, 656 }, 657 }, 658 { 659 Name: "@babel/helper-validator-identifier", 660 Version: "7.25.9", 661 PURLType: purl.TypeNPM, 662 Locations: []string{"testdata/commits.json5"}, 663 SourceCode: &extractor.SourceCodeIdentifier{}, 664 Metadata: osv.DepGroupMetadata{ 665 DepGroupVals: []string{}, 666 }, 667 }, 668 { 669 Name: "@babel/parser", 670 Version: "7.26.5", 671 PURLType: purl.TypeNPM, 672 Locations: []string{"testdata/commits.json5"}, 673 SourceCode: &extractor.SourceCodeIdentifier{}, 674 Metadata: osv.DepGroupMetadata{ 675 DepGroupVals: []string{}, 676 }, 677 }, 678 { 679 Name: "@babel/types", 680 Version: "7.26.5", 681 PURLType: purl.TypeNPM, 682 Locations: []string{"testdata/commits.json5"}, 683 SourceCode: &extractor.SourceCodeIdentifier{}, 684 Metadata: osv.DepGroupMetadata{ 685 DepGroupVals: []string{}, 686 }, 687 }, 688 { 689 Name: "@prettier/sync", 690 Version: "", 691 PURLType: purl.TypeNPM, 692 Locations: []string{"testdata/commits.json5"}, 693 SourceCode: &extractor.SourceCodeIdentifier{ 694 Commit: "527e8ce", 695 }, 696 Metadata: osv.DepGroupMetadata{ 697 DepGroupVals: []string{}, 698 }, 699 }, 700 { 701 Name: "babel-preset-php", 702 Version: "", 703 PURLType: purl.TypeNPM, 704 Locations: []string{"testdata/commits.json5"}, 705 SourceCode: &extractor.SourceCodeIdentifier{ 706 Commit: "1ae6dc1267500360b411ec711b8aeac8c68b2246", 707 }, 708 Metadata: osv.DepGroupMetadata{ 709 DepGroupVals: []string{}, 710 }, 711 }, 712 { 713 Name: "is-number", 714 Version: "", 715 PURLType: purl.TypeNPM, 716 Locations: []string{"testdata/commits.json5"}, 717 SourceCode: &extractor.SourceCodeIdentifier{ 718 Commit: "98e8ff1", 719 }, 720 Metadata: osv.DepGroupMetadata{ 721 DepGroupVals: []string{}, 722 }, 723 }, 724 { 725 Name: "is-number", 726 Version: "", 727 PURLType: purl.TypeNPM, 728 Locations: []string{"testdata/commits.json5"}, 729 SourceCode: &extractor.SourceCodeIdentifier{ 730 Commit: "d5ac058", 731 }, 732 Metadata: osv.DepGroupMetadata{ 733 DepGroupVals: []string{}, 734 }, 735 }, 736 { 737 Name: "is-number", 738 Version: "", 739 PURLType: purl.TypeNPM, 740 Locations: []string{"testdata/commits.json5"}, 741 SourceCode: &extractor.SourceCodeIdentifier{ 742 Commit: "b7aef34", 743 }, 744 Metadata: osv.DepGroupMetadata{ 745 DepGroupVals: []string{}, 746 }, 747 }, 748 { 749 Name: "jquery", 750 Version: "3.7.1", 751 PURLType: purl.TypeNPM, 752 Locations: []string{"testdata/commits.json5"}, 753 SourceCode: &extractor.SourceCodeIdentifier{}, 754 Metadata: osv.DepGroupMetadata{ 755 DepGroupVals: []string{}, 756 }, 757 }, 758 { 759 Name: "lodash", 760 Version: "1.3.1", 761 PURLType: purl.TypeNPM, 762 Locations: []string{"testdata/commits.json5"}, 763 SourceCode: &extractor.SourceCodeIdentifier{}, 764 Metadata: osv.DepGroupMetadata{ 765 DepGroupVals: []string{}, 766 }, 767 }, 768 { 769 Name: "make-synchronized", 770 Version: "0.2.9", 771 PURLType: purl.TypeNPM, 772 Locations: []string{"testdata/commits.json5"}, 773 SourceCode: &extractor.SourceCodeIdentifier{}, 774 Metadata: osv.DepGroupMetadata{ 775 DepGroupVals: []string{}, 776 }, 777 }, 778 { 779 Name: "php-parser", 780 Version: "2.2.0", 781 PURLType: purl.TypeNPM, 782 Locations: []string{"testdata/commits.json5"}, 783 SourceCode: &extractor.SourceCodeIdentifier{}, 784 Metadata: osv.DepGroupMetadata{ 785 DepGroupVals: []string{}, 786 }, 787 }, 788 { 789 Name: "prettier", 790 Version: "3.4.2", 791 PURLType: purl.TypeNPM, 792 Locations: []string{"testdata/commits.json5"}, 793 SourceCode: &extractor.SourceCodeIdentifier{}, 794 Metadata: osv.DepGroupMetadata{ 795 DepGroupVals: []string{}, 796 }, 797 }, 798 { 799 Name: "raven-js", 800 Version: "", 801 PURLType: purl.TypeNPM, 802 Locations: []string{"testdata/commits.json5"}, 803 SourceCode: &extractor.SourceCodeIdentifier{ 804 Commit: "91ef2d4", 805 }, 806 Metadata: osv.DepGroupMetadata{ 807 DepGroupVals: []string{}, 808 }, 809 }, 810 { 811 Name: "slick-carousel", 812 Version: "", 813 PURLType: purl.TypeNPM, 814 Locations: []string{"testdata/commits.json5"}, 815 SourceCode: &extractor.SourceCodeIdentifier{ 816 Commit: "fc6f7d8", 817 }, 818 Metadata: osv.DepGroupMetadata{ 819 DepGroupVals: []string{}, 820 }, 821 }, 822 { 823 Name: "stopwords", 824 Version: "0.0.1", 825 PURLType: purl.TypeNPM, 826 Locations: []string{"testdata/commits.json5"}, 827 SourceCode: &extractor.SourceCodeIdentifier{}, 828 Metadata: osv.DepGroupMetadata{ 829 DepGroupVals: []string{}, 830 }, 831 }, 832 }, 833 }, 834 { 835 Name: "files", 836 InputConfig: extracttest.ScanInputMockConfig{ 837 Path: "testdata/files.json5", 838 }, 839 WantPackages: []*extractor.Package{ 840 { 841 Name: "etag", 842 Version: "", 843 PURLType: purl.TypeNPM, 844 Locations: []string{"testdata/files.json5"}, 845 SourceCode: &extractor.SourceCodeIdentifier{}, 846 Metadata: osv.DepGroupMetadata{ 847 DepGroupVals: []string{}, 848 }, 849 }, 850 { 851 Name: "lodash", 852 Version: "1.3.1", 853 PURLType: purl.TypeNPM, 854 Locations: []string{"testdata/files.json5"}, 855 SourceCode: &extractor.SourceCodeIdentifier{}, 856 Metadata: osv.DepGroupMetadata{ 857 DepGroupVals: []string{}, 858 }, 859 }, 860 }, 861 }, 862 { 863 Name: "sample from blog post", 864 InputConfig: extracttest.ScanInputMockConfig{ 865 Path: "testdata/blog-sample.json5", 866 }, 867 WantPackages: []*extractor.Package{ 868 { 869 Name: "uWebSockets.js", 870 Version: "", 871 PURLType: purl.TypeNPM, 872 Locations: []string{"testdata/blog-sample.json5"}, 873 SourceCode: &extractor.SourceCodeIdentifier{ 874 Commit: "6609a88", 875 }, 876 Metadata: osv.DepGroupMetadata{ 877 DepGroupVals: []string{}, 878 }, 879 }, 880 }, 881 }, 882 } 883 884 for _, tt := range tests { 885 t.Run(tt.Name, func(t *testing.T) { 886 extr := bunlock.Extractor{} 887 888 scanInput := extracttest.GenerateScanInputMock(t, tt.InputConfig) 889 defer extracttest.CloseTestScanInput(t, scanInput) 890 891 got, err := extr.Extract(t.Context(), &scanInput) 892 893 if diff := cmp.Diff(tt.WantErr, err, cmpopts.EquateErrors()); diff != "" { 894 t.Errorf("%s.Extract(%q) error diff (-want +got):\n%s", extr.Name(), tt.InputConfig.Path, diff) 895 return 896 } 897 898 wantInv := inventory.Inventory{Packages: tt.WantPackages} 899 if diff := cmp.Diff(wantInv, got, cmpopts.SortSlices(extracttest.PackageCmpLess)); diff != "" { 900 t.Errorf("%s.Extract(%q) diff (-want +got):\n%s", extr.Name(), tt.InputConfig.Path, diff) 901 } 902 }) 903 } 904 }