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 }