github.com/google/osv-scalibr@v0.4.1/extractor/filesystem/language/lua/luarocks/luarocks_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 luarocks_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"
    24  	"github.com/google/osv-scalibr/extractor/filesystem/language/lua/luarocks"
    25  	"github.com/google/osv-scalibr/extractor/filesystem/simplefileapi"
    26  	"github.com/google/osv-scalibr/inventory"
    27  	"github.com/google/osv-scalibr/purl"
    28  )
    29  
    30  func TestFileRequired(t *testing.T) {
    31  	tests := []struct {
    32  		name         string
    33  		path         string
    34  		wantRequired bool
    35  	}{
    36  		{
    37  			name:         "valid .rockspec file with Lua 5.4",
    38  			path:         "/test/rocks-5.4/aesfileencrypt/0.1.3-1/aesfileencrypt-0.1.3-1.rockspec",
    39  			wantRequired: true,
    40  		},
    41  		{
    42  			name:         "valid .rockspec file with Lua 5.2",
    43  			path:         "/test/rocks-5.2/aesfileencrypt/0.1.3-1/aesfileencrypt-0.1.3-1.rockspec",
    44  			wantRequired: true,
    45  		},
    46  		{
    47  			name:         ".rockspec file with missing folder",
    48  			path:         "/test/rocks-5.2/0.1.3-1/aesfileencrypt-0.1.3-1.rockspec",
    49  			wantRequired: false,
    50  		},
    51  		{
    52  			name:         "ordinary text file without correct extension",
    53  			path:         "/test/rocks-5.4/aesfileencrypt/0.1.3-1/rock_manifest",
    54  			wantRequired: false,
    55  		},
    56  		{
    57  			name:         "ordinary Lua file without correct extension",
    58  			path:         "/test/rocks-5.4/aesfileencrypt/0.1.3-1/test/test.lua",
    59  			wantRequired: false,
    60  		},
    61  		{
    62  			name:         ".rockspec file in the wrong path",
    63  			path:         "/test/aesfileencrypt/0.1.3-1/test/test.lua",
    64  			wantRequired: false,
    65  		},
    66  	}
    67  
    68  	for _, tt := range tests {
    69  		t.Run(tt.name, func(t *testing.T) {
    70  			var e filesystem.Extractor = luarocks.Extractor{}
    71  			if got := e.FileRequired(simplefileapi.New(tt.path, nil)); got != tt.wantRequired {
    72  				t.Fatalf("FileRequired(%s): got %v, want %v", tt.path, got, tt.wantRequired)
    73  			}
    74  		})
    75  	}
    76  }
    77  
    78  func pkgLess(i1, i2 *extractor.Package) bool {
    79  	return i1.Name < i2.Name
    80  }
    81  
    82  func TestExtract(t *testing.T) {
    83  	tests := []struct {
    84  		name         string
    85  		path         string
    86  		wantPackages []*extractor.Package
    87  		wantErr      error
    88  	}{
    89  		{
    90  			name: "valid_.rockspec_file_path_for_the_latest_version",
    91  			path: "testdata/rocks-5.4/aesfileencrypt/0.1.3-1/aesfileencrypt-0.1.3-1.rockspec",
    92  			wantPackages: []*extractor.Package{
    93  				{
    94  					Name:      "aesfileencrypt",
    95  					Version:   "0.1.3-1",
    96  					PURLType:  purl.TypeLua,
    97  					Locations: []string{"testdata/rocks-5.4/aesfileencrypt/0.1.3-1/aesfileencrypt-0.1.3-1.rockspec"},
    98  				},
    99  			},
   100  		},
   101  		{
   102  			name: "valid_.rockspec_file_path_for_an_old_version",
   103  			path: "testdata/rocks-5.2/lua-resty-jwt/0.2.3-0/lua-resty-jwt-0.2.3-0.rockspec",
   104  			wantPackages: []*extractor.Package{
   105  				{
   106  					Name:      "lua-resty-jwt",
   107  					Version:   "0.2.3-0",
   108  					PURLType:  purl.TypeLua,
   109  					Locations: []string{"testdata/rocks-5.2/lua-resty-jwt/0.2.3-0/lua-resty-jwt-0.2.3-0.rockspec"},
   110  				},
   111  			},
   112  		},
   113  		{
   114  			name: "valid_.rockspec_file_path_with_string_version",
   115  			path: "testdata/rocks-5.4/gversion/dev-0/gversion-dev-0.rockspec",
   116  			wantPackages: []*extractor.Package{
   117  				{
   118  					Name:      "gversion",
   119  					Version:   "dev-0",
   120  					PURLType:  purl.TypeLua,
   121  					Locations: []string{"testdata/rocks-5.4/gversion/dev-0/gversion-dev-0.rockspec"},
   122  				},
   123  			},
   124  		},
   125  		{
   126  			name:         "invalid path",
   127  			path:         "/gversion/dev-0/gversion-dev-0.rockspec",
   128  			wantPackages: nil,
   129  		},
   130  	}
   131  
   132  	for _, tt := range tests {
   133  		t.Run(tt.name, func(t *testing.T) {
   134  			var e filesystem.Extractor = luarocks.Extractor{}
   135  			input := &filesystem.ScanInput{Path: tt.path, Reader: nil}
   136  			got, err := e.Extract(t.Context(), input)
   137  			if diff := cmp.Diff(tt.wantErr, err, cmpopts.EquateErrors()); diff != "" {
   138  				t.Errorf("Extract(%s) unexpected error (-want +got):\n%s", tt.path, diff)
   139  			}
   140  
   141  			want := inventory.Inventory{Packages: tt.wantPackages}
   142  
   143  			if diff := cmp.Diff(want, got, cmpopts.SortSlices(pkgLess)); diff != "" {
   144  				t.Errorf("Extract(%s) (-want +got):\n%s", tt.path, diff)
   145  			}
   146  		})
   147  	}
   148  }