github.com/anchore/syft@v1.4.2-0.20240516191711-1bec1fc5d397/syft/format/internal/spdxutil/helpers/license_test.go (about) 1 package helpers 2 3 import ( 4 "strings" 5 "testing" 6 7 "github.com/stretchr/testify/assert" 8 9 "github.com/anchore/syft/internal/spdxlicense" 10 "github.com/anchore/syft/syft/pkg" 11 ) 12 13 func Test_License(t *testing.T) { 14 type expected struct { 15 concluded string 16 declared string 17 } 18 tests := []struct { 19 name string 20 input pkg.Package 21 expected expected 22 }{ 23 { 24 name: "no licenses", 25 input: pkg.Package{}, 26 expected: expected{ 27 concluded: "NOASSERTION", 28 declared: "NOASSERTION", 29 }, 30 }, 31 { 32 name: "no SPDX licenses", 33 input: pkg.Package{ 34 Licenses: pkg.NewLicenseSet(pkg.NewLicense("made-up")), 35 }, 36 expected: expected{ 37 concluded: "NOASSERTION", 38 declared: "LicenseRef-made-up", 39 }, 40 }, 41 { 42 name: "with SPDX license", 43 input: pkg.Package{ 44 Licenses: pkg.NewLicenseSet(pkg.NewLicense("MIT")), 45 }, 46 expected: struct { 47 concluded string 48 declared string 49 }{ 50 concluded: "NOASSERTION", 51 declared: "MIT", 52 }, 53 }, 54 { 55 name: "with SPDX license expression", 56 input: pkg.Package{ 57 Licenses: pkg.NewLicenseSet( 58 pkg.NewLicense("MIT"), 59 pkg.NewLicense("GPL-3.0-only"), 60 ), 61 }, 62 expected: expected{ 63 concluded: "NOASSERTION", 64 // because we sort licenses alphabetically GPL ends up at the start 65 declared: "GPL-3.0-only AND MIT", 66 }, 67 }, 68 { 69 name: "includes valid LicenseRef-", 70 input: pkg.Package{ 71 Licenses: pkg.NewLicenseSet( 72 pkg.NewLicense("one thing first"), 73 pkg.NewLicense("two things/#$^second"), 74 pkg.NewLicense("MIT"), 75 ), 76 }, 77 expected: expected{ 78 concluded: "NOASSERTION", 79 // because we separate licenses between valid SPDX and non valid, valid ID always end at the front 80 declared: "MIT AND LicenseRef-one-thing-first AND LicenseRef-two-things----second", 81 }, 82 }, 83 { 84 name: "join parentheses correctly", 85 input: pkg.Package{ 86 Licenses: pkg.NewLicenseSet( 87 pkg.NewLicense("one thing first"), 88 pkg.NewLicense("MIT AND GPL-3.0-only"), 89 pkg.NewLicense("MIT OR APACHE-2.0"), 90 ), 91 }, 92 expected: expected{ 93 concluded: "NOASSERTION", 94 // because we separate licenses between valid SPDX and non valid, valid ID always end at the front 95 declared: "(MIT AND GPL-3.0-only) AND (MIT OR APACHE-2.0) AND LicenseRef-one-thing-first", 96 }, 97 }, 98 } 99 for _, test := range tests { 100 t.Run(test.name, func(t *testing.T) { 101 c, d := License(test.input) 102 assert.Equal(t, test.expected.concluded, c) 103 assert.Equal(t, test.expected.declared, d) 104 }) 105 } 106 } 107 108 func Test_joinLicenses(t *testing.T) { 109 tests := []struct { 110 name string 111 args []string 112 want string 113 }{ 114 { 115 name: "multiple licenses", 116 args: []string{"MIT", "GPL-3.0-only"}, 117 want: "MIT AND GPL-3.0-only", 118 }, 119 { 120 name: "multiple licenses with complex expressions", 121 args: []string{"MIT AND Apache", "GPL-3.0-only"}, 122 want: "(MIT AND Apache) AND GPL-3.0-only", 123 }, 124 } 125 for _, tt := range tests { 126 t.Run(tt.name, func(t *testing.T) { 127 assert.Equalf(t, tt.want, joinLicenses(toSpdxLicenses(tt.args)), "joinLicenses(%v)", tt.args) 128 }) 129 } 130 } 131 132 func toSpdxLicenses(ids []string) (licenses []SPDXLicense) { 133 for _, l := range ids { 134 license := SPDXLicense{ID: l} 135 if strings.HasPrefix(l, spdxlicense.LicenseRefPrefix) { 136 license.Value = l 137 } 138 licenses = append(licenses, license) 139 } 140 return licenses 141 }