github.com/anchore/syft@v1.4.2-0.20240516191711-1bec1fc5d397/syft/pkg/license_set_test.go (about) 1 package pkg 2 3 import ( 4 "testing" 5 6 "github.com/google/go-cmp/cmp" 7 8 "github.com/anchore/syft/syft/file" 9 "github.com/anchore/syft/syft/license" 10 ) 11 12 func TestLicenseSet_Add(t *testing.T) { 13 tests := []struct { 14 name string 15 licenses []License 16 want []License 17 }{ 18 { 19 name: "add one simple license", 20 licenses: []License{ 21 NewLicense("MIT"), 22 }, 23 want: []License{ 24 NewLicense("MIT"), 25 }, 26 }, 27 { 28 name: "add multiple simple licenses", 29 licenses: []License{ 30 NewLicense("MIT"), 31 NewLicense("MIT"), 32 NewLicense("Apache-2.0"), 33 }, 34 want: []License{ 35 NewLicense("Apache-2.0"), 36 NewLicense("MIT"), 37 }, 38 }, 39 { 40 name: "attempt to add a license with no name", 41 licenses: []License{ 42 NewLicense(""), 43 }, 44 want: nil, 45 }, 46 { 47 name: "keep multiple licenses sorted", 48 licenses: []License{ 49 NewLicense("MIT"), 50 NewLicense("Apache-2.0"), 51 }, 52 want: []License{ 53 NewLicense("Apache-2.0"), 54 NewLicense("MIT"), 55 }, 56 }, 57 { 58 name: "deduplicate licenses with locations", 59 licenses: []License{ 60 NewLicenseFromLocations("MIT", file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "1"})), 61 NewLicenseFromLocations("MIT", file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "1"})), 62 NewLicenseFromLocations("MIT", file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "2"})), 63 }, 64 want: []License{ 65 NewLicenseFromLocations( 66 "MIT", 67 file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "1"}), 68 file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "2"}), 69 ), 70 }, 71 }, 72 { 73 name: "same licenses with different locations", 74 licenses: []License{ 75 NewLicense("MIT"), 76 NewLicenseFromLocations("MIT", file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "2"})), 77 NewLicenseFromLocations("MIT", file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "1"})), 78 }, 79 want: []License{ 80 NewLicenseFromLocations( 81 "MIT", 82 file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "1"}), 83 file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "2"}), 84 ), 85 }, 86 }, 87 { 88 name: "same license from different sources", 89 licenses: []License{ 90 NewLicense("MIT"), 91 NewLicenseFromLocations("MIT", file.NewLocation("/place")), 92 NewLicenseFromURLs("MIT", "https://example.com"), 93 }, 94 want: []License{ 95 { 96 Value: "MIT", 97 SPDXExpression: "MIT", 98 Type: license.Declared, 99 URLs: []string{"https://example.com"}, 100 Locations: file.NewLocationSet(file.NewLocation("/place")), 101 }, 102 }, 103 }, 104 { 105 name: "different licenses from different sources with different types constitute two licenses", 106 licenses: []License{ 107 NewLicenseFromType("MIT", license.Concluded), 108 NewLicenseFromType("MIT", license.Declared), 109 NewLicenseFromLocations("MIT", file.NewLocation("/place")), 110 NewLicenseFromURLs("MIT", "https://example.com"), 111 }, 112 want: []License{ 113 { 114 Value: "MIT", 115 SPDXExpression: "MIT", 116 Type: license.Concluded, 117 Locations: file.NewLocationSet(), 118 }, 119 { 120 Value: "MIT", 121 SPDXExpression: "MIT", 122 Type: license.Declared, 123 URLs: []string{"https://example.com"}, 124 Locations: file.NewLocationSet(file.NewLocation("/place")), 125 }, 126 }, 127 }, 128 } 129 for _, tt := range tests { 130 t.Run(tt.name, func(t *testing.T) { 131 s := NewLicenseSet() 132 s.Add(tt.licenses...) 133 testMe := s.ToSlice() 134 if d := cmp.Diff(tt.want, testMe, cmp.Comparer(defaultLicenseComparer)); d != "" { 135 t.Errorf("unexpected license set (-want +got):\n%s", d) 136 } 137 }) 138 } 139 } 140 141 func defaultLocationComparer(x, y file.Location) bool { 142 return cmp.Equal(x.Coordinates, y.Coordinates) && cmp.Equal(x.AccessPath, y.AccessPath) 143 } 144 145 func defaultLicenseComparer(x, y License) bool { 146 return cmp.Equal(x, y, cmp.Comparer(defaultLocationComparer), cmp.Comparer( 147 func(x, y file.LocationSet) bool { 148 xs := x.ToSlice() 149 ys := y.ToSlice() 150 if len(xs) != len(ys) { 151 return false 152 } 153 for i, xe := range xs { 154 ye := ys[i] 155 if !defaultLocationComparer(xe, ye) { 156 return false 157 } 158 } 159 return true 160 }, 161 )) 162 }