github.com/anchore/syft@v1.4.2-0.20240516191711-1bec1fc5d397/syft/pkg/cataloger/r/parse_description_test.go (about)

     1  package r
     2  
     3  import (
     4  	"context"
     5  	"os"
     6  	"path/filepath"
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/require"
    11  
    12  	"github.com/anchore/syft/syft/file"
    13  	"github.com/anchore/syft/syft/pkg"
    14  )
    15  
    16  func Test_parseDescriptionFile(t *testing.T) {
    17  	type packageAssertions []func(*testing.T, []pkg.Package)
    18  	tests := []struct {
    19  		name       string
    20  		assertions packageAssertions
    21  		fixture    string
    22  	}{
    23  		{
    24  			name:    "no package is returned if no version found",
    25  			fixture: filepath.Join("test-fixtures", "map-parse", "no-version"),
    26  			assertions: packageAssertions{
    27  				func(t *testing.T, p []pkg.Package) {
    28  					assert.Empty(t, p)
    29  				},
    30  			},
    31  		},
    32  		{
    33  			name:    "no package is returned if no package name found",
    34  			fixture: filepath.Join("test-fixtures", "map-parse", "no-name"),
    35  			assertions: packageAssertions{
    36  				func(t *testing.T, p []pkg.Package) {
    37  					assert.Empty(t, p)
    38  				},
    39  			},
    40  		},
    41  		{
    42  			name:    "package return if both name and version found",
    43  			fixture: filepath.Join("test-fixtures", "map-parse", "simple"),
    44  			assertions: packageAssertions{
    45  				func(t *testing.T, p []pkg.Package) {
    46  					assert.Equal(t, 1, len(p))
    47  					assert.Equal(t, "base", p[0].Name)
    48  					assert.Equal(t, "4.3.0", p[0].Version)
    49  				},
    50  			},
    51  		},
    52  	}
    53  
    54  	for _, tt := range tests {
    55  		t.Run(tt.name, func(t *testing.T) {
    56  			f, err := os.Open(tt.fixture)
    57  			input := file.LocationReadCloser{
    58  				Location:   file.NewLocation(tt.fixture),
    59  				ReadCloser: f,
    60  			}
    61  			got, _, err := parseDescriptionFile(context.Background(), nil, nil, input)
    62  			assert.NoError(t, err)
    63  			for _, assertion := range tt.assertions {
    64  				assertion(t, got)
    65  			}
    66  		})
    67  	}
    68  }
    69  
    70  func Test_extractFieldsFromDescriptionFile(t *testing.T) {
    71  	tests := []struct {
    72  		name    string
    73  		fixture string
    74  		want    map[string]string
    75  	}{
    76  		{
    77  			name:    "go case",
    78  			fixture: "test-fixtures/map-parse/simple",
    79  			want: map[string]string{
    80  				"Package":  "base",
    81  				"Version":  "4.3.0",
    82  				"Suggests": "methods",
    83  				"Built":    "R 4.3.0; ; 2023-04-21 11:33:09 UTC; unix",
    84  			},
    85  		},
    86  		{
    87  			name:    "bad cases",
    88  			fixture: "test-fixtures/map-parse/bad",
    89  			want: map[string]string{
    90  				"Key":        "",
    91  				"Whitespace": "",
    92  			},
    93  		},
    94  		{
    95  			name:    "multiline key-value",
    96  			fixture: "test-fixtures/map-parse/multiline",
    97  			want: map[string]string{
    98  				"Description": `A consistent, simple and easy to use set of wrappers around
    99  the fantastic 'stringi' package. All function and argument names (and
   100  positions) are consistent, all functions deal with "NA"'s and zero
   101  length vectors in the same way, and the output from one function is
   102  easy to feed into the input of another.`,
   103  				"License": "MIT + file LICENSE",
   104  				"Key":     "value",
   105  			},
   106  		},
   107  		{
   108  			name:    "eof multiline",
   109  			fixture: "test-fixtures/map-parse/eof-multiline",
   110  			want: map[string]string{
   111  				"License": "MIT + file LICENSE",
   112  				"Description": `A consistent, simple and easy to use set of wrappers around
   113  the fantastic 'stringi' package. All function and argument names (and
   114  positions) are consistent, all functions deal with "NA"'s and zero
   115  length vectors in the same way, and the output from one function is
   116  easy to feed into the input of another.`,
   117  			},
   118  		},
   119  	}
   120  
   121  	for _, test := range tests {
   122  		t.Run(test.name, func(t *testing.T) {
   123  			file, err := os.Open(test.fixture)
   124  			require.NoError(t, err)
   125  
   126  			result := extractFieldsFromDescriptionFile(file)
   127  
   128  			assert.Equal(t, test.want, result)
   129  		})
   130  	}
   131  
   132  }