github.com/anchore/syft@v1.38.2/syft/pkg/cataloger/dart/parse_pubspec_lock_test.go (about)

     1  package dart
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/assert"
     7  
     8  	"github.com/anchore/syft/syft/artifact"
     9  	"github.com/anchore/syft/syft/file"
    10  	"github.com/anchore/syft/syft/pkg"
    11  	"github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest"
    12  )
    13  
    14  func TestParsePubspecLock(t *testing.T) {
    15  	tests := []struct {
    16  		name                  string
    17  		fixture               string
    18  		expectedPackages      []pkg.Package
    19  		expectedRelationships []artifact.Relationship
    20  	}{
    21  		{
    22  			name:    "standard pubspec.lock",
    23  			fixture: "test-fixtures/pubspec_locks/pubspec.lock",
    24  			expectedPackages: []pkg.Package{
    25  				{
    26  					Name:      "ale",
    27  					Version:   "3.3.0",
    28  					PURL:      "pkg:pub/ale@3.3.0?hosted_url=pub.hosted.org",
    29  					Locations: file.NewLocationSet(file.NewLocation("test-fixtures/pubspec_locks/pubspec.lock")),
    30  					Language:  pkg.Dart,
    31  					Type:      pkg.DartPubPkg,
    32  					Metadata: pkg.DartPubspecLockEntry{
    33  						Name:      "ale",
    34  						Version:   "3.3.0",
    35  						HostedURL: "pub.hosted.org",
    36  					},
    37  				},
    38  				{
    39  					Name:      "analyzer",
    40  					Version:   "0.40.7",
    41  					PURL:      "pkg:pub/analyzer@0.40.7",
    42  					Locations: file.NewLocationSet(file.NewLocation("test-fixtures/pubspec_locks/pubspec.lock")),
    43  					Language:  pkg.Dart,
    44  					Type:      pkg.DartPubPkg,
    45  					Metadata: pkg.DartPubspecLockEntry{
    46  						Name:    "analyzer",
    47  						Version: "0.40.7",
    48  					},
    49  				},
    50  				{
    51  					Name:      "ansicolor",
    52  					Version:   "1.1.1",
    53  					PURL:      "pkg:pub/ansicolor@1.1.1",
    54  					Locations: file.NewLocationSet(file.NewLocation("test-fixtures/pubspec_locks/pubspec.lock")),
    55  					Language:  pkg.Dart,
    56  					Type:      pkg.DartPubPkg,
    57  					Metadata: pkg.DartPubspecLockEntry{
    58  						Name:    "ansicolor",
    59  						Version: "1.1.1",
    60  					},
    61  				},
    62  				{
    63  					Name:      "archive",
    64  					Version:   "2.0.13",
    65  					PURL:      "pkg:pub/archive@2.0.13",
    66  					Locations: file.NewLocationSet(file.NewLocation("test-fixtures/pubspec_locks/pubspec.lock")),
    67  					Language:  pkg.Dart,
    68  					Type:      pkg.DartPubPkg,
    69  					Metadata: pkg.DartPubspecLockEntry{
    70  						Name:    "archive",
    71  						Version: "2.0.13",
    72  					},
    73  				},
    74  				{
    75  					Name:      "args",
    76  					Version:   "1.6.0",
    77  					PURL:      "pkg:pub/args@1.6.0",
    78  					Locations: file.NewLocationSet(file.NewLocation("test-fixtures/pubspec_locks/pubspec.lock")),
    79  					Language:  pkg.Dart,
    80  					Type:      pkg.DartPubPkg,
    81  					Metadata: pkg.DartPubspecLockEntry{
    82  						Name:    "args",
    83  						Version: "1.6.0",
    84  					},
    85  				},
    86  				{
    87  					Name:      "flutter",
    88  					Version:   "3.24.5",
    89  					PURL:      "pkg:pub/flutter@3.24.5",
    90  					Locations: file.NewLocationSet(file.NewLocation("test-fixtures/pubspec_locks/pubspec.lock")),
    91  					Language:  pkg.Dart,
    92  					Type:      pkg.DartPubPkg,
    93  					Metadata: pkg.DartPubspecLockEntry{
    94  						Name:    "flutter",
    95  						Version: "3.24.5",
    96  					},
    97  				},
    98  				{
    99  					Name:      "key_binder",
   100  					Version:   "1.11.20",
   101  					PURL:      "pkg:pub/key_binder@1.11.20?vcs_url=git%40github.com%3AWorkiva%2Fkey_binder.git%403f7b3a6350e73c7dcac45301c0e18fbd42af02f7",
   102  					Locations: file.NewLocationSet(file.NewLocation("test-fixtures/pubspec_locks/pubspec.lock")),
   103  					Language:  pkg.Dart,
   104  					Type:      pkg.DartPubPkg,
   105  					Metadata: pkg.DartPubspecLockEntry{
   106  						Name:    "key_binder",
   107  						Version: "1.11.20",
   108  						VcsURL:  "git@github.com:Workiva/key_binder.git@3f7b3a6350e73c7dcac45301c0e18fbd42af02f7",
   109  					},
   110  				},
   111  			},
   112  			expectedRelationships: nil,
   113  		},
   114  	}
   115  
   116  	for _, test := range tests {
   117  		t.Run(test.name, func(t *testing.T) {
   118  			pkgtest.TestFileParser(t, test.fixture, parsePubspecLock, test.expectedPackages, test.expectedRelationships)
   119  		})
   120  	}
   121  }
   122  
   123  func Test_corruptPubspecLock(t *testing.T) {
   124  	pkgtest.NewCatalogTester().
   125  		FromFile(t, "test-fixtures/corrupt/pubspec.lock").
   126  		WithError().
   127  		TestParser(t, parsePubspecLock)
   128  }
   129  
   130  func Test_missingSdkEntryPubspecLock(t *testing.T) {
   131  	fixture := "test-fixtures/missing-sdk/pubspec.lock"
   132  	fixtureLocationSet := file.NewLocationSet(file.NewLocation(fixture))
   133  
   134  	// SDK version is missing, so flutter version cannot be determined and
   135  	// is ignored, expecting args as only package in the list as a result.
   136  	expected := []pkg.Package{
   137  		{
   138  			Name:      "args",
   139  			Version:   "1.6.0",
   140  			PURL:      "pkg:pub/args@1.6.0",
   141  			Locations: fixtureLocationSet,
   142  			Language:  pkg.Dart,
   143  			Type:      pkg.DartPubPkg,
   144  			Metadata: pkg.DartPubspecLockEntry{
   145  				Name:    "args",
   146  				Version: "1.6.0",
   147  			},
   148  		},
   149  	}
   150  
   151  	// TODO: relationships are not under test
   152  	var expectedRelationships []artifact.Relationship
   153  
   154  	pkgtest.TestFileParser(t, fixture, parsePubspecLock, expected, expectedRelationships)
   155  }
   156  
   157  func Test_invalidSdkEntryPubspecLock(t *testing.T) {
   158  	fixture := "test-fixtures/invalid-sdk/pubspec.lock"
   159  	fixtureLocationSet := file.NewLocationSet(file.NewLocation(fixture))
   160  
   161  	// SDK version is invalid, so flutter version cannot be determined and
   162  	// is ignored, expecting args as only package in the list as a result.
   163  	expected := []pkg.Package{
   164  		{
   165  			Name:      "args",
   166  			Version:   "1.6.0",
   167  			PURL:      "pkg:pub/args@1.6.0",
   168  			Locations: fixtureLocationSet,
   169  			Language:  pkg.Dart,
   170  			Type:      pkg.DartPubPkg,
   171  			Metadata: pkg.DartPubspecLockEntry{
   172  				Name:    "args",
   173  				Version: "1.6.0",
   174  			},
   175  		},
   176  	}
   177  
   178  	// TODO: relationships are not under test
   179  	var expectedRelationships []artifact.Relationship
   180  
   181  	pkgtest.TestFileParser(t, fixture, parsePubspecLock, expected, expectedRelationships)
   182  }
   183  
   184  func Test_sdkVersionLookup(t *testing.T) {
   185  	psl := &pubspecLock{
   186  		Sdks: make(map[string]string, 5),
   187  	}
   188  
   189  	psl.Sdks["minVersionSdk"] = ">=0.1.2"
   190  	psl.Sdks["rangeVersionSdk"] = ">=1.2.3 <2.0.0"
   191  	psl.Sdks["caretVersionSdk"] = "^2.3.4"
   192  	psl.Sdks["emptyVersionSdk"] = ""
   193  	psl.Sdks["invalidVersionSdk"] = "not a constraint"
   194  
   195  	var version string
   196  	var err error
   197  
   198  	version, err = psl.getSdkVersion("minVersionSdk")
   199  	assert.NoError(t, err)
   200  	assert.Equal(t, "0.1.2", version)
   201  
   202  	version, err = psl.getSdkVersion("rangeVersionSdk")
   203  	assert.NoError(t, err)
   204  	assert.Equal(t, "1.2.3", version)
   205  
   206  	version, err = psl.getSdkVersion("caretVersionSdk")
   207  	assert.NoError(t, err)
   208  	assert.Equal(t, "2.3.4", version)
   209  
   210  	version, err = psl.getSdkVersion("emptyVersionSdk")
   211  	assert.Error(t, err)
   212  	assert.Equal(t, "", version)
   213  
   214  	version, err = psl.getSdkVersion("invalidVersionSdk")
   215  	assert.Error(t, err)
   216  	assert.Equal(t, "", version)
   217  
   218  	version, err = psl.getSdkVersion("nonexistantSdk")
   219  	assert.Error(t, err)
   220  	assert.Equal(t, "", version)
   221  }
   222  
   223  func Test_sdkVersionParser_valid(t *testing.T) {
   224  	var version string
   225  	var err error
   226  
   227  	// map constraints to expected version
   228  	patterns := map[string]string{
   229  		"^0.0.0":                "0.0.0",
   230  		">=0.0.0":               "0.0.0",
   231  		"^1.23.4":               "1.23.4",
   232  		">=1.23.4":              "1.23.4",
   233  		"^11.22.33":             "11.22.33",
   234  		">=11.22.33":            "11.22.33",
   235  		"^123.123456.12345678":  "123.123456.12345678",
   236  		">=123.123456.12345678": "123.123456.12345678",
   237  		">=1.2.3 <2.3.4":        "1.2.3",
   238  		">=1.2.3 random string": "1.2.3",
   239  		">=1.2.3 >=0.1.2":       "1.2.3",
   240  		"^1.2":                  "1.2",
   241  		">=1.2":                 "1.2",
   242  		"^1.2.3-rc4":            "1.2.3-rc4",
   243  		">=1.2.3-rc4":           "1.2.3-rc4",
   244  		"^2.34.5+hotfix6":       "2.34.5+hotfix6",
   245  		">=2.34.5+hotfix6":      "2.34.5+hotfix6",
   246  	}
   247  
   248  	for constraint, expected := range patterns {
   249  		t.Run(constraint, func(t *testing.T) {
   250  			version, err = parseMinimumSdkVersion(constraint)
   251  			assert.NoError(t, err)
   252  			assert.Equal(t, expected, version)
   253  		})
   254  	}
   255  }
   256  
   257  func Test_sdkVersionParser_invalid(t *testing.T) {
   258  	var version string
   259  	var err error
   260  
   261  	patterns := []string{
   262  		"",
   263  		"abc",
   264  		"^abc",
   265  		">=abc",
   266  		"^a.b.c",
   267  		">=a.b.c",
   268  		"1.2.34",
   269  		">1.2.34",
   270  		"<=1.2.34",
   271  		"<1.2.34",
   272  		"^1.2.3.4",
   273  		">=1.2.3.4",
   274  		"^1.x.0",
   275  		">=1.x.0",
   276  		"^1x2x3",
   277  		">=1x2x3",
   278  		"^1.-2.3",
   279  		">=1.-2.3",
   280  		"abc <1.2.34",
   281  		"^2.3.45hotfix6",
   282  		">=2.3.45hotfix6",
   283  	}
   284  
   285  	for _, pattern := range patterns {
   286  		version, err = parseMinimumSdkVersion(pattern)
   287  		assert.Error(t, err)
   288  		assert.Equalf(t, "", version, "constraint '%s'", pattern)
   289  	}
   290  }