github.com/google/osv-scalibr@v0.4.1/extractor/filesystem/language/ruby/gemfilelock/gemfilelock_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 gemfilelock_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/ruby/gemfilelock" 24 "github.com/google/osv-scalibr/extractor/filesystem/simplefileapi" 25 "github.com/google/osv-scalibr/inventory" 26 "github.com/google/osv-scalibr/purl" 27 "github.com/google/osv-scalibr/testing/extracttest" 28 ) 29 30 func TestExtractor_FileRequired(t *testing.T) { 31 tests := []struct { 32 inputPath string 33 want bool 34 }{ 35 { 36 inputPath: "", 37 want: false, 38 }, 39 { 40 inputPath: "Gemfile.lock", 41 want: true, 42 }, 43 { 44 inputPath: "gems.locked", 45 want: true, 46 }, 47 { 48 inputPath: "path/to/my/Gemfile.lock", 49 want: true, 50 }, 51 { 52 inputPath: "path/to/my/gems.locked", 53 want: true, 54 }, 55 { 56 inputPath: "path/to/my/Gemfile.lock/file", 57 want: false, 58 }, 59 { 60 inputPath: "path/to/my/Gemfile.lock.file", 61 want: false, 62 }, 63 { 64 inputPath: "path.to.my.Gemfile.lock", 65 want: false, 66 }, 67 } 68 for _, tt := range tests { 69 t.Run(tt.inputPath, func(t *testing.T) { 70 e := gemfilelock.Extractor{} 71 got := e.FileRequired(simplefileapi.New(tt.inputPath, nil)) 72 if got != tt.want { 73 t.Errorf("FileRequired(%s, FileInfo) got = %v, want %v", tt.inputPath, got, tt.want) 74 } 75 }) 76 } 77 } 78 79 func TestExtractor_Extract(t *testing.T) { 80 tests := []extracttest.TestTableEntry{ 81 { 82 Name: "no spec section", 83 InputConfig: extracttest.ScanInputMockConfig{ 84 Path: "testdata/no-spec-section.lock", 85 }, 86 WantPackages: []*extractor.Package{}, 87 }, 88 { 89 Name: "no gem section", 90 InputConfig: extracttest.ScanInputMockConfig{ 91 Path: "testdata/no-gem-section.lock", 92 }, 93 WantPackages: []*extractor.Package{}, 94 }, 95 { 96 Name: "no gems", 97 InputConfig: extracttest.ScanInputMockConfig{ 98 Path: "testdata/no-gems.lock", 99 }, 100 WantPackages: []*extractor.Package{}, 101 }, 102 { 103 Name: "invalid spec", 104 InputConfig: extracttest.ScanInputMockConfig{ 105 Path: "testdata/invalid.lock", 106 }, 107 WantPackages: []*extractor.Package{}, 108 }, 109 { 110 Name: "one gem", 111 InputConfig: extracttest.ScanInputMockConfig{ 112 Path: "testdata/one-gem.lock", 113 }, 114 WantPackages: []*extractor.Package{ 115 { 116 Name: "ast", 117 Version: "2.4.2", 118 PURLType: purl.TypeGem, 119 Locations: []string{"testdata/one-gem.lock"}, 120 }, 121 }, 122 }, 123 { 124 Name: "trailing source section ", 125 InputConfig: extracttest.ScanInputMockConfig{ 126 Path: "testdata/source-section-at-end.lock", 127 }, 128 WantPackages: []*extractor.Package{ 129 { 130 Name: "ast", 131 Version: "2.4.2", 132 PURLType: purl.TypeGem, 133 Locations: []string{"testdata/source-section-at-end.lock"}, 134 }, 135 }, 136 }, 137 { 138 Name: "some gems", 139 InputConfig: extracttest.ScanInputMockConfig{ 140 Path: "testdata/some-gems.lock", 141 }, 142 WantPackages: []*extractor.Package{ 143 { 144 Name: "coderay", 145 Version: "1.1.3", 146 PURLType: purl.TypeGem, 147 Locations: []string{"testdata/some-gems.lock"}, 148 }, 149 { 150 Name: "method_source", 151 Version: "1.0.0", 152 PURLType: purl.TypeGem, 153 Locations: []string{"testdata/some-gems.lock"}, 154 }, 155 { 156 Name: "pry", 157 Version: "0.14.1", 158 PURLType: purl.TypeGem, 159 Locations: []string{"testdata/some-gems.lock"}, 160 }, 161 }, 162 }, 163 { 164 Name: "multiple gems", 165 InputConfig: extracttest.ScanInputMockConfig{ 166 Path: "testdata/multiple-gems.lock", 167 }, 168 WantPackages: []*extractor.Package{ 169 { 170 Name: "bundler-audit", 171 Version: "0.9.0.1", 172 PURLType: purl.TypeGem, 173 Locations: []string{"testdata/multiple-gems.lock"}, 174 }, 175 { 176 Name: "coderay", 177 Version: "1.1.3", 178 PURLType: purl.TypeGem, 179 Locations: []string{"testdata/multiple-gems.lock"}, 180 }, 181 { 182 Name: "dotenv", 183 Version: "2.7.6", 184 PURLType: purl.TypeGem, 185 Locations: []string{"testdata/multiple-gems.lock"}, 186 }, 187 { 188 Name: "method_source", 189 Version: "1.0.0", 190 PURLType: purl.TypeGem, 191 Locations: []string{"testdata/multiple-gems.lock"}, 192 }, 193 { 194 Name: "pry", 195 Version: "0.14.1", 196 PURLType: purl.TypeGem, 197 Locations: []string{"testdata/multiple-gems.lock"}, 198 }, 199 { 200 Name: "thor", 201 Version: "1.2.1", 202 PURLType: purl.TypeGem, 203 Locations: []string{"testdata/multiple-gems.lock"}, 204 }, 205 }, 206 }, 207 { 208 Name: "rails", 209 InputConfig: extracttest.ScanInputMockConfig{ 210 Path: "testdata/rails.lock", 211 }, 212 WantPackages: []*extractor.Package{ 213 { 214 Name: "actioncable", 215 Version: "7.0.2.2", 216 PURLType: purl.TypeGem, 217 Locations: []string{"testdata/rails.lock"}, 218 }, 219 { 220 Name: "actionmailbox", 221 Version: "7.0.2.2", 222 PURLType: purl.TypeGem, 223 Locations: []string{"testdata/rails.lock"}, 224 }, 225 { 226 Name: "actionmailer", 227 Version: "7.0.2.2", 228 PURLType: purl.TypeGem, 229 Locations: []string{"testdata/rails.lock"}, 230 }, 231 { 232 Name: "actionpack", 233 Version: "7.0.2.2", 234 PURLType: purl.TypeGem, 235 Locations: []string{"testdata/rails.lock"}, 236 }, 237 { 238 Name: "actiontext", 239 Version: "7.0.2.2", 240 PURLType: purl.TypeGem, 241 Locations: []string{"testdata/rails.lock"}, 242 }, 243 { 244 Name: "actionview", 245 Version: "7.0.2.2", 246 PURLType: purl.TypeGem, 247 Locations: []string{"testdata/rails.lock"}, 248 }, 249 { 250 Name: "activejob", 251 Version: "7.0.2.2", 252 PURLType: purl.TypeGem, 253 Locations: []string{"testdata/rails.lock"}, 254 }, 255 { 256 Name: "activemodel", 257 Version: "7.0.2.2", 258 PURLType: purl.TypeGem, 259 Locations: []string{"testdata/rails.lock"}, 260 }, 261 { 262 Name: "activerecord", 263 Version: "7.0.2.2", 264 PURLType: purl.TypeGem, 265 Locations: []string{"testdata/rails.lock"}, 266 }, 267 { 268 Name: "activestorage", 269 Version: "7.0.2.2", 270 PURLType: purl.TypeGem, 271 Locations: []string{"testdata/rails.lock"}, 272 }, 273 { 274 Name: "activesupport", 275 Version: "7.0.2.2", 276 PURLType: purl.TypeGem, 277 Locations: []string{"testdata/rails.lock"}, 278 }, 279 { 280 Name: "builder", 281 Version: "3.2.4", 282 PURLType: purl.TypeGem, 283 Locations: []string{"testdata/rails.lock"}, 284 }, 285 { 286 Name: "concurrent-ruby", 287 Version: "1.1.9", 288 PURLType: purl.TypeGem, 289 Locations: []string{"testdata/rails.lock"}, 290 }, 291 { 292 Name: "crass", 293 Version: "1.0.6", 294 PURLType: purl.TypeGem, 295 Locations: []string{"testdata/rails.lock"}, 296 }, 297 { 298 Name: "digest", 299 Version: "3.1.0", 300 PURLType: purl.TypeGem, 301 Locations: []string{"testdata/rails.lock"}, 302 }, 303 { 304 Name: "erubi", 305 Version: "1.10.0", 306 PURLType: purl.TypeGem, 307 Locations: []string{"testdata/rails.lock"}, 308 }, 309 { 310 Name: "globalid", 311 Version: "1.0.0", 312 PURLType: purl.TypeGem, 313 Locations: []string{"testdata/rails.lock"}, 314 }, 315 { 316 Name: "i18n", 317 Version: "1.10.0", 318 PURLType: purl.TypeGem, 319 Locations: []string{"testdata/rails.lock"}, 320 }, 321 { 322 Name: "io-wait", 323 Version: "0.2.1", 324 PURLType: purl.TypeGem, 325 Locations: []string{"testdata/rails.lock"}, 326 }, 327 { 328 Name: "loofah", 329 Version: "2.14.0", 330 PURLType: purl.TypeGem, 331 Locations: []string{"testdata/rails.lock"}, 332 }, 333 { 334 Name: "mail", 335 Version: "2.7.1", 336 PURLType: purl.TypeGem, 337 Locations: []string{"testdata/rails.lock"}, 338 }, 339 { 340 Name: "marcel", 341 Version: "1.0.2", 342 PURLType: purl.TypeGem, 343 Locations: []string{"testdata/rails.lock"}, 344 }, 345 { 346 Name: "method_source", 347 Version: "1.0.0", 348 PURLType: purl.TypeGem, 349 Locations: []string{"testdata/rails.lock"}, 350 }, 351 { 352 Name: "mini_mime", 353 Version: "1.1.2", 354 PURLType: purl.TypeGem, 355 Locations: []string{"testdata/rails.lock"}, 356 }, 357 { 358 Name: "minitest", 359 Version: "5.15.0", 360 PURLType: purl.TypeGem, 361 Locations: []string{"testdata/rails.lock"}, 362 }, 363 { 364 Name: "net-imap", 365 Version: "0.2.3", 366 PURLType: purl.TypeGem, 367 Locations: []string{"testdata/rails.lock"}, 368 }, 369 { 370 Name: "net-pop", 371 Version: "0.1.1", 372 PURLType: purl.TypeGem, 373 Locations: []string{"testdata/rails.lock"}, 374 }, 375 { 376 Name: "net-protocol", 377 Version: "0.1.2", 378 PURLType: purl.TypeGem, 379 Locations: []string{"testdata/rails.lock"}, 380 }, 381 { 382 Name: "net-smtp", 383 Version: "0.3.1", 384 PURLType: purl.TypeGem, 385 Locations: []string{"testdata/rails.lock"}, 386 }, 387 { 388 Name: "nio4r", 389 Version: "2.5.8", 390 PURLType: purl.TypeGem, 391 Locations: []string{"testdata/rails.lock"}, 392 }, 393 { 394 Name: "racc", 395 Version: "1.6.0", 396 PURLType: purl.TypeGem, 397 Locations: []string{"testdata/rails.lock"}, 398 }, 399 { 400 Name: "rack", 401 Version: "2.2.3", 402 PURLType: purl.TypeGem, 403 Locations: []string{"testdata/rails.lock"}, 404 }, 405 { 406 Name: "rack-test", 407 Version: "1.1.0", 408 PURLType: purl.TypeGem, 409 Locations: []string{"testdata/rails.lock"}, 410 }, 411 { 412 Name: "rails", 413 Version: "7.0.2.2", 414 PURLType: purl.TypeGem, 415 Locations: []string{"testdata/rails.lock"}, 416 }, 417 { 418 Name: "rails-dom-testing", 419 Version: "2.0.3", 420 PURLType: purl.TypeGem, 421 Locations: []string{"testdata/rails.lock"}, 422 }, 423 { 424 Name: "rails-html-sanitizer", 425 Version: "1.4.2", 426 PURLType: purl.TypeGem, 427 Locations: []string{"testdata/rails.lock"}, 428 }, 429 { 430 Name: "railties", 431 Version: "7.0.2.2", 432 PURLType: purl.TypeGem, 433 Locations: []string{"testdata/rails.lock"}, 434 }, 435 { 436 Name: "rake", 437 Version: "13.0.6", 438 PURLType: purl.TypeGem, 439 Locations: []string{"testdata/rails.lock"}, 440 }, 441 { 442 Name: "strscan", 443 Version: "3.0.1", 444 PURLType: purl.TypeGem, 445 Locations: []string{"testdata/rails.lock"}, 446 }, 447 { 448 Name: "thor", 449 Version: "1.2.1", 450 PURLType: purl.TypeGem, 451 Locations: []string{"testdata/rails.lock"}, 452 }, 453 { 454 Name: "timeout", 455 Version: "0.2.0", 456 PURLType: purl.TypeGem, 457 Locations: []string{"testdata/rails.lock"}, 458 }, 459 { 460 Name: "tzinfo", 461 Version: "2.0.4", 462 PURLType: purl.TypeGem, 463 Locations: []string{"testdata/rails.lock"}, 464 }, 465 { 466 Name: "websocket-driver", 467 Version: "0.7.5", 468 PURLType: purl.TypeGem, 469 Locations: []string{"testdata/rails.lock"}, 470 }, 471 { 472 Name: "websocket-extensions", 473 Version: "0.1.5", 474 PURLType: purl.TypeGem, 475 Locations: []string{"testdata/rails.lock"}, 476 }, 477 { 478 Name: "zeitwerk", 479 Version: "2.5.4", 480 PURLType: purl.TypeGem, 481 Locations: []string{"testdata/rails.lock"}, 482 }, 483 { 484 Name: "nokogiri", 485 Version: "1.13.3", 486 PURLType: purl.TypeGem, 487 Locations: []string{"testdata/rails.lock"}, 488 }, 489 }, 490 }, 491 { 492 Name: "rubocop", 493 InputConfig: extracttest.ScanInputMockConfig{ 494 Path: "testdata/rubocop.lock", 495 }, 496 WantPackages: []*extractor.Package{ 497 { 498 Name: "ast", 499 Version: "2.4.2", 500 PURLType: purl.TypeGem, 501 Locations: []string{"testdata/rubocop.lock"}, 502 }, 503 { 504 Name: "parallel", 505 Version: "1.21.0", 506 PURLType: purl.TypeGem, 507 Locations: []string{"testdata/rubocop.lock"}, 508 }, 509 { 510 Name: "parser", 511 Version: "3.1.1.0", 512 PURLType: purl.TypeGem, 513 Locations: []string{"testdata/rubocop.lock"}, 514 }, 515 { 516 Name: "rainbow", 517 Version: "3.1.1", 518 PURLType: purl.TypeGem, 519 Locations: []string{"testdata/rubocop.lock"}, 520 }, 521 { 522 Name: "regexp_parser", 523 Version: "2.2.1", 524 PURLType: purl.TypeGem, 525 Locations: []string{"testdata/rubocop.lock"}, 526 }, 527 { 528 Name: "rexml", 529 Version: "3.2.5", 530 PURLType: purl.TypeGem, 531 Locations: []string{"testdata/rubocop.lock"}, 532 }, 533 { 534 Name: "rubocop", 535 Version: "1.25.1", 536 PURLType: purl.TypeGem, 537 Locations: []string{"testdata/rubocop.lock"}, 538 }, 539 { 540 Name: "rubocop-ast", 541 Version: "1.16.0", 542 PURLType: purl.TypeGem, 543 Locations: []string{"testdata/rubocop.lock"}, 544 }, 545 { 546 Name: "ruby-progressbar", 547 Version: "1.11.0", 548 PURLType: purl.TypeGem, 549 Locations: []string{"testdata/rubocop.lock"}, 550 }, 551 { 552 Name: "unicode-display_width", 553 Version: "2.1.0", 554 PURLType: purl.TypeGem, 555 Locations: []string{"testdata/rubocop.lock"}, 556 }, 557 }, 558 }, 559 { 560 Name: "has local gem", 561 InputConfig: extracttest.ScanInputMockConfig{ 562 Path: "testdata/has-local-gem.lock", 563 }, 564 WantPackages: []*extractor.Package{ 565 { 566 Name: "backbone-on-rails", 567 Version: "1.2.0.0", 568 PURLType: purl.TypeGem, 569 Locations: []string{"testdata/has-local-gem.lock"}, 570 }, 571 { 572 Name: "actionpack", 573 Version: "7.0.2.2", 574 PURLType: purl.TypeGem, 575 Locations: []string{"testdata/has-local-gem.lock"}, 576 }, 577 { 578 Name: "actionview", 579 Version: "7.0.2.2", 580 PURLType: purl.TypeGem, 581 Locations: []string{"testdata/has-local-gem.lock"}, 582 }, 583 { 584 Name: "activesupport", 585 Version: "7.0.2.2", 586 PURLType: purl.TypeGem, 587 Locations: []string{"testdata/has-local-gem.lock"}, 588 }, 589 { 590 Name: "builder", 591 Version: "3.2.4", 592 PURLType: purl.TypeGem, 593 Locations: []string{"testdata/has-local-gem.lock"}, 594 }, 595 { 596 Name: "coffee-script", 597 Version: "2.4.1", 598 PURLType: purl.TypeGem, 599 Locations: []string{"testdata/has-local-gem.lock"}, 600 }, 601 { 602 Name: "coffee-script-source", 603 Version: "1.12.2", 604 PURLType: purl.TypeGem, 605 Locations: []string{"testdata/has-local-gem.lock"}, 606 }, 607 { 608 Name: "concurrent-ruby", 609 Version: "1.1.9", 610 PURLType: purl.TypeGem, 611 Locations: []string{"testdata/has-local-gem.lock"}, 612 }, 613 { 614 Name: "crass", 615 Version: "1.0.6", 616 PURLType: purl.TypeGem, 617 Locations: []string{"testdata/has-local-gem.lock"}, 618 }, 619 { 620 Name: "eco", 621 Version: "1.0.0", 622 PURLType: purl.TypeGem, 623 Locations: []string{"testdata/has-local-gem.lock"}, 624 }, 625 { 626 Name: "ejs", 627 Version: "1.1.1", 628 PURLType: purl.TypeGem, 629 Locations: []string{"testdata/has-local-gem.lock"}, 630 }, 631 { 632 Name: "erubi", 633 Version: "1.10.0", 634 PURLType: purl.TypeGem, 635 Locations: []string{"testdata/has-local-gem.lock"}, 636 }, 637 { 638 Name: "execjs", 639 Version: "2.8.1", 640 PURLType: purl.TypeGem, 641 Locations: []string{"testdata/has-local-gem.lock"}, 642 }, 643 { 644 Name: "i18n", 645 Version: "1.10.0", 646 PURLType: purl.TypeGem, 647 Locations: []string{"testdata/has-local-gem.lock"}, 648 }, 649 { 650 Name: "jquery-rails", 651 Version: "4.4.0", 652 PURLType: purl.TypeGem, 653 Locations: []string{"testdata/has-local-gem.lock"}, 654 }, 655 { 656 Name: "loofah", 657 Version: "2.14.0", 658 PURLType: purl.TypeGem, 659 Locations: []string{"testdata/has-local-gem.lock"}, 660 }, 661 { 662 Name: "method_source", 663 Version: "1.0.0", 664 PURLType: purl.TypeGem, 665 Locations: []string{"testdata/has-local-gem.lock"}, 666 }, 667 { 668 Name: "minitest", 669 Version: "5.15.0", 670 PURLType: purl.TypeGem, 671 Locations: []string{"testdata/has-local-gem.lock"}, 672 }, 673 { 674 Name: "racc", 675 Version: "1.6.0", 676 PURLType: purl.TypeGem, 677 Locations: []string{"testdata/has-local-gem.lock"}, 678 }, 679 { 680 Name: "rack", 681 Version: "2.2.3", 682 PURLType: purl.TypeGem, 683 Locations: []string{"testdata/has-local-gem.lock"}, 684 }, 685 { 686 Name: "rack-test", 687 Version: "1.1.0", 688 PURLType: purl.TypeGem, 689 Locations: []string{"testdata/has-local-gem.lock"}, 690 }, 691 { 692 Name: "rails-dom-testing", 693 Version: "2.0.3", 694 PURLType: purl.TypeGem, 695 Locations: []string{"testdata/has-local-gem.lock"}, 696 }, 697 { 698 Name: "rails-html-sanitizer", 699 Version: "1.4.2", 700 PURLType: purl.TypeGem, 701 Locations: []string{"testdata/has-local-gem.lock"}, 702 }, 703 { 704 Name: "railties", 705 Version: "7.0.2.2", 706 PURLType: purl.TypeGem, 707 Locations: []string{"testdata/has-local-gem.lock"}, 708 }, 709 { 710 Name: "rake", 711 Version: "13.0.6", 712 PURLType: purl.TypeGem, 713 Locations: []string{"testdata/has-local-gem.lock"}, 714 }, 715 { 716 Name: "thor", 717 Version: "1.2.1", 718 PURLType: purl.TypeGem, 719 Locations: []string{"testdata/has-local-gem.lock"}, 720 }, 721 { 722 Name: "tzinfo", 723 Version: "2.0.4", 724 PURLType: purl.TypeGem, 725 Locations: []string{"testdata/has-local-gem.lock"}, 726 }, 727 { 728 Name: "zeitwerk", 729 Version: "2.5.4", 730 PURLType: purl.TypeGem, 731 Locations: []string{"testdata/has-local-gem.lock"}, 732 }, 733 { 734 Name: "nokogiri", 735 Version: "1.13.3", 736 PURLType: purl.TypeGem, 737 Locations: []string{"testdata/has-local-gem.lock"}, 738 }, 739 { 740 Name: "eco-source", 741 Version: "1.1.0.rc.1", 742 PURLType: purl.TypeGem, 743 Locations: []string{"testdata/has-local-gem.lock"}, 744 }, 745 }, 746 }, 747 { 748 Name: "has git gem", 749 InputConfig: extracttest.ScanInputMockConfig{ 750 Path: "testdata/has-git-gem.lock", 751 }, 752 WantPackages: []*extractor.Package{ 753 { 754 Name: "hanami-controller", 755 Version: "2.0.0.alpha1", 756 PURLType: purl.TypeGem, 757 Locations: []string{"testdata/has-git-gem.lock"}, 758 SourceCode: &extractor.SourceCodeIdentifier{ 759 Commit: "027dbe2e56397b534e859fc283990cad1b6addd6", 760 }, 761 }, 762 { 763 Name: "hanami-utils", 764 Version: "2.0.0.alpha1", 765 PURLType: purl.TypeGem, 766 Locations: []string{"testdata/has-git-gem.lock"}, 767 SourceCode: &extractor.SourceCodeIdentifier{ 768 Commit: "5904fc9a70683b8749aa2861257d0c8c01eae4aa", 769 }, 770 }, 771 { 772 Name: "concurrent-ruby", 773 Version: "1.1.7", 774 PURLType: purl.TypeGem, 775 Locations: []string{"testdata/has-git-gem.lock"}, 776 }, 777 { 778 Name: "rack", 779 Version: "2.2.3", 780 PURLType: purl.TypeGem, 781 Locations: []string{"testdata/has-git-gem.lock"}, 782 }, 783 { 784 Name: "transproc", 785 Version: "1.1.1", 786 PURLType: purl.TypeGem, 787 Locations: []string{"testdata/has-git-gem.lock"}, 788 }, 789 }, 790 }, 791 } 792 793 for _, tt := range tests { 794 t.Run(tt.Name, func(t *testing.T) { 795 extr := gemfilelock.Extractor{} 796 797 scanInput := extracttest.GenerateScanInputMock(t, tt.InputConfig) 798 defer extracttest.CloseTestScanInput(t, scanInput) 799 800 got, err := extr.Extract(t.Context(), &scanInput) 801 802 if diff := cmp.Diff(tt.WantErr, err, cmpopts.EquateErrors()); diff != "" { 803 t.Errorf("%s.Extract(%q) error diff (-want +got):\n%s", extr.Name(), tt.InputConfig.Path, diff) 804 return 805 } 806 807 wantInv := inventory.Inventory{Packages: tt.WantPackages} 808 if diff := cmp.Diff(wantInv, got, cmpopts.SortSlices(extracttest.PackageCmpLess)); diff != "" { 809 t.Errorf("%s.Extract(%q) diff (-want +got):\n%s", extr.Name(), tt.InputConfig.Path, diff) 810 } 811 }) 812 } 813 }