github.com/nextlinux/gosbom@v0.81.1-0.20230627115839-1ff50c281391/gosbom/formats/formats_test.go (about) 1 package formats 2 3 import ( 4 "bytes" 5 "io" 6 "os" 7 "testing" 8 9 "github.com/nextlinux/gosbom/gosbom/formats/cyclonedxjson" 10 "github.com/nextlinux/gosbom/gosbom/formats/cyclonedxxml" 11 "github.com/nextlinux/gosbom/gosbom/formats/github" 12 "github.com/nextlinux/gosbom/gosbom/formats/gosbomjson" 13 "github.com/nextlinux/gosbom/gosbom/formats/spdxjson" 14 "github.com/nextlinux/gosbom/gosbom/formats/spdxtagvalue" 15 "github.com/nextlinux/gosbom/gosbom/formats/table" 16 "github.com/nextlinux/gosbom/gosbom/formats/template" 17 "github.com/nextlinux/gosbom/gosbom/formats/text" 18 "github.com/nextlinux/gosbom/gosbom/sbom" 19 "github.com/stretchr/testify/assert" 20 "github.com/stretchr/testify/require" 21 ) 22 23 func TestIdentify(t *testing.T) { 24 tests := []struct { 25 fixture string 26 expected sbom.FormatID 27 }{ 28 { 29 fixture: "test-fixtures/alpine-gosbom.json", 30 expected: gosbomjson.ID, 31 }, 32 } 33 for _, test := range tests { 34 t.Run(test.fixture, func(t *testing.T) { 35 f, err := os.Open(test.fixture) 36 assert.NoError(t, err) 37 by, err := io.ReadAll(f) 38 assert.NoError(t, err) 39 frmt := Identify(by) 40 assert.NotNil(t, frmt) 41 assert.Equal(t, test.expected, frmt.ID()) 42 }) 43 } 44 } 45 46 func TestFormats_EmptyInput(t *testing.T) { 47 for _, format := range Formats() { 48 t.Run(format.ID().String(), func(t *testing.T) { 49 t.Run("format.Decode", func(t *testing.T) { 50 input := bytes.NewReader(nil) 51 52 assert.NotPanics(t, func() { 53 decodedSBOM, err := format.Decode(input) 54 assert.Error(t, err) 55 assert.Nil(t, decodedSBOM) 56 }) 57 }) 58 59 t.Run("format.Validate", func(t *testing.T) { 60 input := bytes.NewReader(nil) 61 62 assert.NotPanics(t, func() { 63 err := format.Validate(input) 64 assert.Error(t, err) 65 }) 66 }) 67 }) 68 } 69 } 70 71 func TestByName(t *testing.T) { 72 73 tests := []struct { 74 name string 75 want sbom.FormatID 76 }{ 77 // SPDX Tag-Value 78 { 79 name: "spdx", 80 want: spdxtagvalue.ID, 81 }, 82 { 83 name: "spdx-tag-value", 84 want: spdxtagvalue.ID, 85 }, 86 { 87 name: "spdx-tv", 88 want: spdxtagvalue.ID, 89 }, 90 { 91 name: "spdxtv", // clean variant 92 want: spdxtagvalue.ID, 93 }, 94 95 // SPDX JSON 96 { 97 name: "spdx-json", 98 want: spdxjson.ID, 99 }, 100 { 101 name: "spdxjson", // clean variant 102 want: spdxjson.ID, 103 }, 104 105 // Cyclonedx JSON 106 { 107 name: "cyclonedx-json", 108 want: cyclonedxjson.ID, 109 }, 110 { 111 name: "cyclonedxjson", // clean variant 112 want: cyclonedxjson.ID, 113 }, 114 115 // Cyclonedx XML 116 { 117 name: "cyclonedx", 118 want: cyclonedxxml.ID, 119 }, 120 { 121 name: "cyclonedx-xml", 122 want: cyclonedxxml.ID, 123 }, 124 { 125 name: "cyclonedxxml", // clean variant 126 want: cyclonedxxml.ID, 127 }, 128 129 // Gosbom Table 130 { 131 name: "table", 132 want: table.ID, 133 }, 134 { 135 name: "gosbom-table", 136 want: table.ID, 137 }, 138 139 // Gosbom Text 140 { 141 name: "text", 142 want: text.ID, 143 }, 144 { 145 name: "gosbom-text", 146 want: text.ID, 147 }, 148 149 // Gosbom JSON 150 { 151 name: "json", 152 want: gosbomjson.ID, 153 }, 154 { 155 name: "gosbom-json", 156 want: gosbomjson.ID, 157 }, 158 { 159 name: "gosbomjson", // clean variant 160 want: gosbomjson.ID, 161 }, 162 163 // GitHub JSON 164 { 165 name: "github", 166 want: github.ID, 167 }, 168 { 169 name: "github-json", 170 want: github.ID, 171 }, 172 173 // Gosbom template 174 { 175 name: "template", 176 want: template.ID, 177 }, 178 } 179 for _, tt := range tests { 180 t.Run(tt.name, func(t *testing.T) { 181 f := ByName(tt.name) 182 if tt.want == "" { 183 require.Nil(t, f) 184 return 185 } 186 require.NotNil(t, f) 187 assert.Equal(t, tt.want, f.ID()) 188 }) 189 } 190 } 191 192 func Test_versionMatches(t *testing.T) { 193 tests := []struct { 194 name string 195 version string 196 match string 197 matches bool 198 }{ 199 { 200 name: "any version matches number", 201 version: string(sbom.AnyVersion), 202 match: "6", 203 matches: true, 204 }, 205 { 206 name: "number matches any version", 207 version: "6", 208 match: string(sbom.AnyVersion), 209 matches: true, 210 }, 211 { 212 name: "same number matches", 213 version: "3", 214 match: "3", 215 matches: true, 216 }, 217 { 218 name: "same major number matches", 219 version: "3.1", 220 match: "3", 221 matches: true, 222 }, 223 { 224 name: "same minor number matches", 225 version: "3.1", 226 match: "3.1", 227 matches: true, 228 }, 229 { 230 name: "wildcard-version matches minor", 231 version: "7.1.3", 232 match: "7.*", 233 matches: true, 234 }, 235 { 236 name: "wildcard-version matches patch", 237 version: "7.4.8", 238 match: "7.4.*", 239 matches: true, 240 }, 241 { 242 name: "sub-version matches major", 243 version: "7.19.11", 244 match: "7", 245 matches: true, 246 }, 247 { 248 name: "sub-version matches minor", 249 version: "7.55.2", 250 match: "7.55", 251 matches: true, 252 }, 253 { 254 name: "sub-version matches patch", 255 version: "7.32.6", 256 match: "7.32.6", 257 matches: true, 258 }, 259 // negative tests 260 { 261 name: "different number does not match", 262 version: "3", 263 match: "4", 264 matches: false, 265 }, 266 { 267 name: "sub-version doesn't match major", 268 version: "7.2.5", 269 match: "8.2.5", 270 matches: false, 271 }, 272 { 273 name: "sub-version doesn't match minor", 274 version: "7.2.9", 275 match: "7.1", 276 matches: false, 277 }, 278 { 279 name: "sub-version doesn't match patch", 280 version: "7.32.6", 281 match: "7.32.5", 282 matches: false, 283 }, 284 } 285 286 for _, test := range tests { 287 t.Run(test.name, func(t *testing.T) { 288 matches := versionMatches(test.version, test.match) 289 assert.Equal(t, test.matches, matches) 290 }) 291 } 292 }