github.com/noqcks/syft@v0.0.0-20230920222752-a9e2c4e288e5/syft/pkg/cataloger/javascript/parse_package_lock_test.go (about)

     1  package javascript
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/anchore/syft/syft/artifact"
     7  	"github.com/anchore/syft/syft/file"
     8  	"github.com/anchore/syft/syft/pkg"
     9  	"github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest"
    10  )
    11  
    12  func TestParsePackageLock(t *testing.T) {
    13  	var expectedRelationships []artifact.Relationship
    14  	expectedPkgs := []pkg.Package{
    15  		{
    16  			Name:         "pkg-lock",
    17  			Version:      "0.0.0",
    18  			PURL:         "pkg:npm/pkg-lock@0.0.0",
    19  			Language:     pkg.JavaScript,
    20  			Type:         pkg.NpmPkg,
    21  			MetadataType: "NpmPackageLockJsonMetadata",
    22  			Metadata:     pkg.NpmPackageLockJSONMetadata{},
    23  		},
    24  		{
    25  			Name:         "@actions/core",
    26  			Version:      "1.6.0",
    27  			PURL:         "pkg:npm/%40actions/core@1.6.0",
    28  			Language:     pkg.JavaScript,
    29  			Type:         pkg.NpmPkg,
    30  			MetadataType: "NpmPackageLockJsonMetadata",
    31  			Metadata:     pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/@actions/core/-/core-1.6.0.tgz", Integrity: "sha512-NB1UAZomZlCV/LmJqkLhNTqtKfFXJZAUPcfl/zqG7EfsQdeUJtaWO98SGbuQ3pydJ3fHl2CvI/51OKYlCYYcaw=="},
    32  		},
    33  		{
    34  			Name:         "ansi-regex",
    35  			Version:      "3.0.0",
    36  			PURL:         "pkg:npm/ansi-regex@3.0.0",
    37  			Language:     pkg.JavaScript,
    38  			Type:         pkg.NpmPkg,
    39  			MetadataType: "NpmPackageLockJsonMetadata",
    40  			Metadata:     pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", Integrity: "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="},
    41  		},
    42  		{
    43  			Name:         "cowsay",
    44  			Version:      "1.4.0",
    45  			PURL:         "pkg:npm/cowsay@1.4.0",
    46  			Language:     pkg.JavaScript,
    47  			Type:         pkg.NpmPkg,
    48  			MetadataType: "NpmPackageLockJsonMetadata",
    49  			Metadata:     pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/cowsay/-/cowsay-1.4.0.tgz", Integrity: "sha512-rdg5k5PsHFVJheO/pmE3aDg2rUDDTfPJau6yYkZYlHFktUz+UxbE+IgnUAEyyCyv4noL5ltxXD0gZzmHPCy/9g=="},
    50  		},
    51  		{
    52  			Name:         "get-stdin",
    53  			Version:      "5.0.1",
    54  			PURL:         "pkg:npm/get-stdin@5.0.1",
    55  			Language:     pkg.JavaScript,
    56  			Type:         pkg.NpmPkg,
    57  			MetadataType: "NpmPackageLockJsonMetadata",
    58  			Metadata:     pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", Integrity: "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g="},
    59  		},
    60  		{
    61  			Name:         "is-fullwidth-code-point",
    62  			Version:      "2.0.0",
    63  			PURL:         "pkg:npm/is-fullwidth-code-point@2.0.0",
    64  			Language:     pkg.JavaScript,
    65  			Type:         pkg.NpmPkg,
    66  			MetadataType: "NpmPackageLockJsonMetadata",
    67  			Metadata:     pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", Integrity: "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="},
    68  		},
    69  		{
    70  			Name:         "minimist",
    71  			Version:      "0.0.10",
    72  			PURL:         "pkg:npm/minimist@0.0.10",
    73  			Language:     pkg.JavaScript,
    74  			Type:         pkg.NpmPkg,
    75  			MetadataType: "NpmPackageLockJsonMetadata",
    76  			Metadata:     pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", Integrity: "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="},
    77  		},
    78  		{
    79  			Name:         "optimist",
    80  			Version:      "0.6.1",
    81  			PURL:         "pkg:npm/optimist@0.6.1",
    82  			Language:     pkg.JavaScript,
    83  			Type:         pkg.NpmPkg,
    84  			MetadataType: "NpmPackageLockJsonMetadata",
    85  			Metadata:     pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", Integrity: "sha1-2j6nRob6IaGaERwybpDrFaAZZoY="},
    86  		},
    87  		{
    88  			Name:         "string-width",
    89  			Version:      "2.1.1",
    90  			PURL:         "pkg:npm/string-width@2.1.1",
    91  			Language:     pkg.JavaScript,
    92  			Type:         pkg.NpmPkg,
    93  			MetadataType: "NpmPackageLockJsonMetadata",
    94  			Metadata:     pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", Integrity: "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw=="},
    95  		},
    96  		{
    97  			Name:         "strip-ansi",
    98  			Version:      "4.0.0",
    99  			PURL:         "pkg:npm/strip-ansi@4.0.0",
   100  			Language:     pkg.JavaScript,
   101  			Type:         pkg.NpmPkg,
   102  			MetadataType: "NpmPackageLockJsonMetadata",
   103  			Metadata:     pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", Integrity: "sha1-qEeQIusaw2iocTibY1JixQXuNo8="},
   104  		},
   105  		{
   106  			Name:         "strip-eof",
   107  			Version:      "1.0.0",
   108  			PURL:         "pkg:npm/strip-eof@1.0.0",
   109  			Language:     pkg.JavaScript,
   110  			Type:         pkg.NpmPkg,
   111  			MetadataType: "NpmPackageLockJsonMetadata",
   112  			Metadata:     pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", Integrity: "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="},
   113  		},
   114  		{
   115  			Name:         "wordwrap",
   116  			Version:      "0.0.3",
   117  			PURL:         "pkg:npm/wordwrap@0.0.3",
   118  			Language:     pkg.JavaScript,
   119  			Type:         pkg.NpmPkg,
   120  			MetadataType: "NpmPackageLockJsonMetadata",
   121  			Metadata:     pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", Integrity: "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="},
   122  		},
   123  	}
   124  	fixture := "test-fixtures/pkg-lock/package-lock.json"
   125  	for i := range expectedPkgs {
   126  		expectedPkgs[i].Locations.Add(file.NewLocation(fixture))
   127  	}
   128  
   129  	pkgtest.TestFileParser(t, fixture, parsePackageLock, expectedPkgs, expectedRelationships)
   130  }
   131  
   132  func TestParsePackageLockV2(t *testing.T) {
   133  	fixture := "test-fixtures/pkg-lock/lock-2/package-lock.json"
   134  	locationSet := file.NewLocationSet(file.NewLocation(fixture))
   135  	npm := pkg.Package{
   136  		Name:         "npm",
   137  		Version:      "6.14.6",
   138  		Language:     pkg.JavaScript,
   139  		Type:         pkg.NpmPkg,
   140  		PURL:         "pkg:npm/npm@6.14.6",
   141  		MetadataType: "NpmPackageLockJsonMetadata",
   142  		Locations:    locationSet,
   143  		Metadata:     pkg.NpmPackageLockJSONMetadata{},
   144  	}
   145  	propTypes := pkg.Package{
   146  		Name:     "@types/prop-types",
   147  		Version:  "15.7.5",
   148  		PURL:     "pkg:npm/%40types/prop-types@15.7.5",
   149  		Language: pkg.JavaScript,
   150  		Type:     pkg.NpmPkg,
   151  		Licenses: pkg.NewLicenseSet(
   152  			pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)),
   153  		),
   154  		Locations:    locationSet,
   155  		MetadataType: "NpmPackageLockJsonMetadata",
   156  		Metadata:     pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", Integrity: "sha1-XxnSuFqY6VWANvajysyIGUIPBc8="},
   157  	}
   158  	react := pkg.Package{
   159  		Name:     "@types/react",
   160  		Version:  "18.0.17",
   161  		PURL:     "pkg:npm/%40types/react@18.0.17",
   162  		Language: pkg.JavaScript,
   163  		Type:     pkg.NpmPkg,
   164  		Licenses: pkg.NewLicenseSet(
   165  			pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)),
   166  		),
   167  		Locations:    locationSet,
   168  		MetadataType: "NpmPackageLockJsonMetadata",
   169  		Metadata:     pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/@types/react/-/react-18.0.17.tgz", Integrity: "sha1-RYPZwyLWfv5LOak10iPtzHBQzPQ="},
   170  	}
   171  	scheduler := pkg.Package{
   172  		Name:     "@types/scheduler",
   173  		Version:  "0.16.2",
   174  		PURL:     "pkg:npm/%40types/scheduler@0.16.2",
   175  		Language: pkg.JavaScript,
   176  		Type:     pkg.NpmPkg,
   177  		Licenses: pkg.NewLicenseSet(
   178  			pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)),
   179  		),
   180  		Locations:    locationSet,
   181  		MetadataType: "NpmPackageLockJsonMetadata",
   182  		Metadata:     pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", Integrity: "sha1-GmL4lSVyPd4kuhsBsJK/XfitTTk="},
   183  	}
   184  	csstype := pkg.Package{
   185  		Name:     "csstype",
   186  		Version:  "3.1.0",
   187  		PURL:     "pkg:npm/csstype@3.1.0",
   188  		Language: pkg.JavaScript,
   189  		Type:     pkg.NpmPkg,
   190  		Licenses: pkg.NewLicenseSet(
   191  			pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)),
   192  		),
   193  		Locations:    locationSet,
   194  		MetadataType: "NpmPackageLockJsonMetadata",
   195  		Metadata:     pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz", Integrity: "sha1-TdysNxjXh8+d8NG30VAzklyPKfI="},
   196  	}
   197  
   198  	expectedPkgs := []pkg.Package{
   199  		npm,
   200  		propTypes,
   201  		react,
   202  		scheduler,
   203  		csstype,
   204  	}
   205  	expectedRelationships := []artifact.Relationship{
   206  		{
   207  			From: propTypes,
   208  			To:   react,
   209  			Type: artifact.DependencyOfRelationship,
   210  			Data: nil,
   211  		},
   212  		{
   213  			From: propTypes,
   214  			To:   npm,
   215  			Type: artifact.DependencyOfRelationship,
   216  			Data: nil,
   217  		},
   218  		{
   219  			From: react,
   220  			To:   npm,
   221  			Type: artifact.DependencyOfRelationship,
   222  			Data: nil,
   223  		},
   224  		{
   225  			From: scheduler,
   226  			To:   react,
   227  			Type: artifact.DependencyOfRelationship,
   228  			Data: nil,
   229  		},
   230  		{
   231  			From: scheduler,
   232  			To:   npm,
   233  			Type: artifact.DependencyOfRelationship,
   234  			Data: nil,
   235  		},
   236  		{
   237  			From: csstype,
   238  			To:   react,
   239  			Type: artifact.DependencyOfRelationship,
   240  			Data: nil,
   241  		},
   242  		{
   243  			From: csstype,
   244  			To:   npm,
   245  			Type: artifact.DependencyOfRelationship,
   246  			Data: nil,
   247  		},
   248  	}
   249  
   250  	for i := range expectedPkgs {
   251  		expectedPkgs[i].Locations.Add(file.NewLocation(fixture))
   252  	}
   253  	pkgtest.TestFileParser(t, fixture, parsePackageLock, expectedPkgs, expectedRelationships)
   254  }
   255  
   256  func TestParsePackageLockV3(t *testing.T) {
   257  	fixture := "test-fixtures/pkg-lock/lock-3/package-lock.json"
   258  	locationSet := file.NewLocationSet(file.NewLocation(fixture))
   259  	lockV3Fixture := pkg.Package{
   260  		Name:         "lock-v3-fixture",
   261  		Version:      "1.0.0",
   262  		Language:     pkg.JavaScript,
   263  		Type:         pkg.NpmPkg,
   264  		PURL:         "pkg:npm/lock-v3-fixture@1.0.0",
   265  		MetadataType: "NpmPackageLockJsonMetadata",
   266  		Locations:    locationSet,
   267  		Metadata:     pkg.NpmPackageLockJSONMetadata{},
   268  	}
   269  	propTypes := pkg.Package{
   270  		Name:         "@types/prop-types",
   271  		Version:      "15.7.5",
   272  		Language:     pkg.JavaScript,
   273  		Type:         pkg.NpmPkg,
   274  		PURL:         "pkg:npm/%40types/prop-types@15.7.5",
   275  		MetadataType: "NpmPackageLockJsonMetadata",
   276  		Locations:    locationSet,
   277  		Metadata:     pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", Integrity: "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="},
   278  	}
   279  	react := pkg.Package{
   280  		Name:         "@types/react",
   281  		Version:      "18.0.20",
   282  		Language:     pkg.JavaScript,
   283  		Type:         pkg.NpmPkg,
   284  		PURL:         "pkg:npm/%40types/react@18.0.20",
   285  		MetadataType: "NpmPackageLockJsonMetadata",
   286  		Locations:    locationSet,
   287  		Metadata:     pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/@types/react/-/react-18.0.20.tgz", Integrity: "sha512-MWul1teSPxujEHVwZl4a5HxQ9vVNsjTchVA+xRqv/VYGCuKGAU6UhfrTdF5aBefwD1BHUD8i/zq+O/vyCm/FrA=="},
   288  	}
   289  	scheduler := pkg.Package{
   290  		Name:         "@types/scheduler",
   291  		Version:      "0.16.2",
   292  		Language:     pkg.JavaScript,
   293  		Type:         pkg.NpmPkg,
   294  		PURL:         "pkg:npm/%40types/scheduler@0.16.2",
   295  		MetadataType: "NpmPackageLockJsonMetadata",
   296  		Locations:    locationSet,
   297  		Metadata:     pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", Integrity: "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="},
   298  	}
   299  	csstype := pkg.Package{
   300  		Name:         "csstype",
   301  		Version:      "3.1.1",
   302  		Language:     pkg.JavaScript,
   303  		Type:         pkg.NpmPkg,
   304  		PURL:         "pkg:npm/csstype@3.1.1",
   305  		MetadataType: "NpmPackageLockJsonMetadata",
   306  		Locations:    locationSet,
   307  		Metadata:     pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", Integrity: "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw=="},
   308  	}
   309  
   310  	expectedPkgs := []pkg.Package{
   311  		lockV3Fixture,
   312  		propTypes,
   313  		react,
   314  		scheduler,
   315  		csstype,
   316  	}
   317  
   318  	expectedRelationships := []artifact.Relationship{
   319  		{
   320  			From: propTypes,
   321  			To:   react,
   322  			Type: artifact.DependencyOfRelationship,
   323  			Data: nil,
   324  		},
   325  		{
   326  			From: propTypes,
   327  			To:   lockV3Fixture,
   328  			Type: artifact.DependencyOfRelationship,
   329  			Data: nil,
   330  		},
   331  		{
   332  			From: react,
   333  			To:   lockV3Fixture,
   334  			Type: artifact.DependencyOfRelationship,
   335  			Data: nil,
   336  		},
   337  		{
   338  			From: scheduler,
   339  			To:   react,
   340  			Type: artifact.DependencyOfRelationship,
   341  			Data: nil,
   342  		},
   343  		{
   344  			From: scheduler,
   345  			To:   lockV3Fixture,
   346  			Type: artifact.DependencyOfRelationship,
   347  			Data: nil,
   348  		},
   349  		{
   350  			From: csstype,
   351  			To:   react,
   352  			Type: artifact.DependencyOfRelationship,
   353  			Data: nil,
   354  		},
   355  		{
   356  			From: csstype,
   357  			To:   lockV3Fixture,
   358  			Type: artifact.DependencyOfRelationship,
   359  			Data: nil,
   360  		},
   361  	}
   362  
   363  	for i := range expectedPkgs {
   364  		expectedPkgs[i].Locations.Add(file.NewLocation(fixture))
   365  	}
   366  	pkgtest.TestFileParser(t, fixture, parsePackageLock, expectedPkgs, expectedRelationships)
   367  }
   368  
   369  func TestParsePackageLockAlias(t *testing.T) {
   370  	var expectedRelationships []artifact.Relationship
   371  	commonPkgs := []pkg.Package{
   372  		{
   373  			Name:         "alias-check",
   374  			Version:      "1.0.0",
   375  			PURL:         "pkg:npm/alias-check@1.0.0",
   376  			Language:     pkg.JavaScript,
   377  			Type:         pkg.NpmPkg,
   378  			MetadataType: "NpmPackageLockJsonMetadata",
   379  			Metadata:     pkg.NpmPackageLockJSONMetadata{},
   380  		},
   381  		{
   382  			Name:         "case",
   383  			Version:      "1.6.2",
   384  			PURL:         "pkg:npm/case@1.6.2",
   385  			Language:     pkg.JavaScript,
   386  			Type:         pkg.NpmPkg,
   387  			MetadataType: "NpmPackageLockJsonMetadata",
   388  			Metadata:     pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/case/-/case-1.6.2.tgz", Integrity: "sha512-ll380ZRoraT7mUK2G92UbH+FJVD5AwdVIAYk9xhV1tauh0carDgYByUD1HhjCWsWgxrfQvCeHvtfj7IYR6TKeg=="},
   389  		},
   390  		{
   391  			Name:         "case",
   392  			Version:      "1.6.3",
   393  			PURL:         "pkg:npm/case@1.6.3",
   394  			Language:     pkg.JavaScript,
   395  			Type:         pkg.NpmPkg,
   396  			MetadataType: "NpmPackageLockJsonMetadata",
   397  			Metadata:     pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/case/-/case-1.6.3.tgz", Integrity: "sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ=="},
   398  		},
   399  		{
   400  			Name:         "@bundled-es-modules/chai",
   401  			Version:      "4.2.2",
   402  			PURL:         "pkg:npm/%40bundled-es-modules/chai@4.2.2",
   403  			Language:     pkg.JavaScript,
   404  			Type:         pkg.NpmPkg,
   405  			MetadataType: "NpmPackageLockJsonMetadata",
   406  			Metadata:     pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/@bundled-es-modules/chai/-/chai-4.2.2.tgz", Integrity: "sha512-iGmVYw2/zJCoqyKTtWEYCtFmMyi8WmACQKtky0lpNyEKWX0YIOpKWGD7saMXL+tPpllss0otilxV0SLwyi3Ytg=="},
   407  		},
   408  	}
   409  
   410  	packageLockV1 := "test-fixtures/pkg-lock/alias-1/package-lock.json"
   411  	packageLockV2 := "test-fixtures/pkg-lock/alias-2/package-lock.json"
   412  	packageLocks := []string{packageLockV1}
   413  
   414  	v2Pkg := pkg.Package{
   415  		Name:     "alias-check",
   416  		Version:  "1.0.0",
   417  		PURL:     "pkg:npm/alias-check@1.0.0",
   418  		Language: pkg.JavaScript,
   419  		Type:     pkg.NpmPkg,
   420  		Licenses: pkg.NewLicenseSet(
   421  			pkg.NewLicenseFromLocations("ISC", file.NewLocation(packageLockV2)),
   422  		),
   423  		MetadataType: "NpmPackageLockJsonMetadata",
   424  		Metadata:     pkg.NpmPackageLockJSONMetadata{},
   425  	}
   426  
   427  	for _, pl := range packageLocks {
   428  		expected := make([]pkg.Package, len(commonPkgs))
   429  		copy(expected, commonPkgs)
   430  
   431  		if pl == packageLockV2 {
   432  			expected = append(expected, v2Pkg)
   433  		}
   434  
   435  		for i := range expected {
   436  			expected[i].Locations.Add(file.NewLocation(pl))
   437  		}
   438  		pkgtest.TestFileParser(t, pl, parsePackageLock, expected, expectedRelationships)
   439  	}
   440  }
   441  
   442  func TestParsePackageLockLicenseWithArray(t *testing.T) {
   443  	fixture := "test-fixtures/pkg-lock/array-license/package-lock.json"
   444  	locationSet := file.NewLocationSet(file.NewLocation(fixture))
   445  	pauseStream := pkg.Package{
   446  		Name:     "pause-stream",
   447  		Version:  "0.0.11",
   448  		Language: pkg.JavaScript,
   449  		Type:     pkg.NpmPkg,
   450  		Licenses: pkg.NewLicenseSet(
   451  			pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)),
   452  			pkg.NewLicenseFromLocations("Apache2", file.NewLocation(fixture)),
   453  		),
   454  		Locations:    locationSet,
   455  		PURL:         "pkg:npm/pause-stream@0.0.11",
   456  		MetadataType: "NpmPackageLockJsonMetadata",
   457  		Metadata:     pkg.NpmPackageLockJSONMetadata{},
   458  	}
   459  	through := pkg.Package{
   460  		Name:     "through",
   461  		Version:  "2.3.8",
   462  		Language: pkg.JavaScript,
   463  		Type:     pkg.NpmPkg,
   464  		Licenses: pkg.NewLicenseSet(
   465  			pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)),
   466  		),
   467  		Locations:    locationSet,
   468  		PURL:         "pkg:npm/through@2.3.8",
   469  		MetadataType: "NpmPackageLockJsonMetadata",
   470  		Metadata:     pkg.NpmPackageLockJSONMetadata{},
   471  	}
   472  	tmp := pkg.Package{
   473  		Name:     "tmp",
   474  		Version:  "1.0.0",
   475  		Language: pkg.JavaScript,
   476  		Type:     pkg.NpmPkg,
   477  		Licenses: pkg.NewLicenseSet(
   478  			pkg.NewLicenseFromLocations("ISC", file.NewLocation(fixture)),
   479  		),
   480  		Locations:    locationSet,
   481  		PURL:         "pkg:npm/tmp@1.0.0",
   482  		MetadataType: "NpmPackageLockJsonMetadata",
   483  		Metadata:     pkg.NpmPackageLockJSONMetadata{},
   484  	}
   485  
   486  	expectedPkgs := []pkg.Package{
   487  		pauseStream,
   488  		through,
   489  		tmp,
   490  	}
   491  	expectedRelationships := []artifact.Relationship{
   492  		{
   493  			From: pauseStream,
   494  			To:   tmp,
   495  			Type: artifact.DependencyOfRelationship,
   496  			Data: nil,
   497  		},
   498  		{
   499  			From: through,
   500  			To:   pauseStream,
   501  			Type: artifact.DependencyOfRelationship,
   502  			Data: nil,
   503  		},
   504  		{
   505  			From: through,
   506  			To:   tmp,
   507  			Type: artifact.DependencyOfRelationship,
   508  			Data: nil,
   509  		},
   510  	}
   511  	for i := range expectedPkgs {
   512  		expectedPkgs[i].Locations.Add(file.NewLocation(fixture))
   513  	}
   514  	pkgtest.TestFileParser(t, fixture, parsePackageLock, expectedPkgs, expectedRelationships)
   515  }