github.com/google/osv-scalibr@v0.4.1/extractor/filesystem/language/r/renvlock/renvlock_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 renvlock_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/r/renvlock" 24 "github.com/google/osv-scalibr/inventory" 25 "github.com/google/osv-scalibr/purl" 26 "github.com/google/osv-scalibr/testing/extracttest" 27 ) 28 29 func TestExtractor_Extract(t *testing.T) { 30 tests := []extracttest.TestTableEntry{ 31 { 32 Name: "invalid json", 33 InputConfig: extracttest.ScanInputMockConfig{ 34 Path: "testdata/not-json.txt", 35 }, 36 WantPackages: nil, 37 WantErr: extracttest.ContainsErrStr{Str: "could not extract"}, 38 }, 39 { 40 Name: "no packages", 41 InputConfig: extracttest.ScanInputMockConfig{ 42 Path: "testdata/empty.lock", 43 }, 44 WantPackages: []*extractor.Package{}, 45 }, 46 { 47 Name: "one package", 48 InputConfig: extracttest.ScanInputMockConfig{ 49 Path: "testdata/one-package.lock", 50 }, 51 WantPackages: []*extractor.Package{ 52 { 53 Name: "morning", 54 Version: "0.1.0", 55 PURLType: purl.TypeCran, 56 Locations: []string{"testdata/one-package.lock"}, 57 }, 58 }, 59 }, 60 { 61 Name: "two packages", 62 InputConfig: extracttest.ScanInputMockConfig{ 63 Path: "testdata/two-packages.lock", 64 }, 65 WantPackages: []*extractor.Package{ 66 { 67 Name: "markdown", 68 Version: "1.0", 69 PURLType: purl.TypeCran, 70 Locations: []string{"testdata/two-packages.lock"}, 71 }, 72 { 73 Name: "mime", 74 Version: "0.7", 75 PURLType: purl.TypeCran, 76 Locations: []string{"testdata/two-packages.lock"}, 77 }, 78 }, 79 }, 80 { 81 Name: "with mixed sources", 82 InputConfig: extracttest.ScanInputMockConfig{ 83 Path: "testdata/with-mixed-sources.lock", 84 }, 85 WantPackages: []*extractor.Package{ 86 { 87 Name: "markdown", 88 Version: "1.0", 89 PURLType: purl.TypeCran, 90 Locations: []string{"testdata/with-mixed-sources.lock"}, 91 }, 92 }, 93 }, 94 { 95 Name: "with bioconductor", 96 InputConfig: extracttest.ScanInputMockConfig{ 97 Path: "testdata/with-bioconductor.lock", 98 }, 99 WantPackages: []*extractor.Package{ 100 { 101 Name: "BH", 102 Version: "1.75.0-0", 103 PURLType: purl.TypeCran, 104 Locations: []string{"testdata/with-bioconductor.lock"}, 105 }, 106 }, 107 }, 108 { 109 Name: "without repository", 110 InputConfig: extracttest.ScanInputMockConfig{ 111 Path: "testdata/without-repository.lock", 112 }, 113 WantPackages: []*extractor.Package{}, 114 }, 115 } 116 117 for _, tt := range tests { 118 t.Run(tt.Name, func(t *testing.T) { 119 extr := renvlock.Extractor{} 120 121 scanInput := extracttest.GenerateScanInputMock(t, tt.InputConfig) 122 defer extracttest.CloseTestScanInput(t, scanInput) 123 124 got, err := extr.Extract(t.Context(), &scanInput) 125 126 if diff := cmp.Diff(tt.WantErr, err, cmpopts.EquateErrors()); diff != "" { 127 t.Errorf("%s.Extract(%q) error diff (-want +got):\n%s", extr.Name(), tt.InputConfig.Path, diff) 128 return 129 } 130 131 wantInv := inventory.Inventory{Packages: tt.WantPackages} 132 if diff := cmp.Diff(wantInv, got, cmpopts.SortSlices(extracttest.PackageCmpLess)); diff != "" { 133 t.Errorf("%s.Extract(%q) diff (-want +got):\n%s", extr.Name(), tt.InputConfig.Path, diff) 134 } 135 }) 136 } 137 }