github.com/noqcks/syft@v0.0.0-20230920222752-a9e2c4e288e5/syft/pkg/cataloger/common/cpe/field_candidate_test.go (about) 1 package cpe 2 3 import ( 4 "strings" 5 "testing" 6 7 "github.com/stretchr/testify/assert" 8 ) 9 10 func Test_cpeCandidateValues_filter(t *testing.T) { 11 tests := []struct { 12 name string 13 input []fieldCandidate 14 exclusionConditions []fieldCandidateCondition 15 expect []string 16 }{ 17 { 18 name: "gocase", 19 input: []fieldCandidate{ 20 { 21 value: "allow anything", 22 }, 23 { 24 value: "no-sub-selections", 25 disallowSubSelections: true, 26 }, 27 { 28 value: "no-delimiter-variations", 29 disallowDelimiterVariations: true, 30 }, 31 { 32 value: "allow nothing", 33 disallowSubSelections: true, 34 disallowDelimiterVariations: true, 35 }, 36 }, 37 expect: []string{ 38 "allow anything", 39 "no-sub-selections", 40 "no-delimiter-variations", 41 "allow nothing", 42 }, 43 }, 44 { 45 name: "filter out sub-selections", 46 input: []fieldCandidate{ 47 { 48 value: "allow anything", 49 }, 50 { 51 value: "no-sub-selections", 52 disallowSubSelections: true, 53 }, 54 { 55 value: "no-delimiter-variations", 56 disallowDelimiterVariations: true, 57 }, 58 { 59 value: "allow nothing", 60 disallowSubSelections: true, 61 disallowDelimiterVariations: true, 62 }, 63 }, 64 exclusionConditions: []fieldCandidateCondition{ 65 subSelectionsDisallowed, 66 }, 67 expect: []string{ 68 "allow anything", 69 "no-delimiter-variations", 70 }, 71 }, 72 { 73 name: "filter out delimiter-variations", 74 input: []fieldCandidate{ 75 { 76 value: "allow anything", 77 }, 78 { 79 value: "no-sub-selections", 80 disallowSubSelections: true, 81 }, 82 { 83 value: "no-delimiter-variations", 84 disallowDelimiterVariations: true, 85 }, 86 { 87 value: "allow nothing", 88 disallowSubSelections: true, 89 disallowDelimiterVariations: true, 90 }, 91 }, 92 exclusionConditions: []fieldCandidateCondition{ 93 delimiterVariationsDisallowed, 94 }, 95 expect: []string{ 96 "allow anything", 97 "no-sub-selections", 98 }, 99 }, 100 { 101 name: "all exclusionConditions", 102 input: []fieldCandidate{ 103 { 104 value: "allow anything", 105 }, 106 { 107 value: "no-sub-selections", 108 disallowSubSelections: true, 109 }, 110 { 111 value: "no-delimiter-variations", 112 disallowDelimiterVariations: true, 113 }, 114 { 115 value: "allow nothing", 116 disallowSubSelections: true, 117 disallowDelimiterVariations: true, 118 }, 119 }, 120 exclusionConditions: []fieldCandidateCondition{ 121 delimiterVariationsDisallowed, 122 subSelectionsDisallowed, 123 }, 124 expect: []string{ 125 "allow anything", 126 }, 127 }, 128 } 129 130 for _, test := range tests { 131 t.Run(test.name, func(t *testing.T) { 132 set := newFieldCandidateSet() 133 set.add(test.input...) 134 135 for _, condition := range test.exclusionConditions { 136 set.removeWhere(condition) 137 } 138 139 assert.ElementsMatch(t, test.expect, set.values()) 140 }) 141 } 142 } 143 144 func Test_cpeFieldCandidateSet_addValue(t *testing.T) { 145 s := newFieldCandidateSet() 146 // we should clean all values (unquote strings) 147 s.addValue(`"string!"`) 148 assert.ElementsMatch(t, []string{"string!"}, s.values()) 149 } 150 151 func Test_cpeFieldCandidateSet_add(t *testing.T) { 152 s := newFieldCandidateSet() 153 // we should clean all values (unquote strings) 154 s.add(fieldCandidate{ 155 value: `"string!"`, 156 }) 157 assert.ElementsMatch(t, []string{"string!"}, s.values()) 158 } 159 160 func Test_cpeFieldCandidateSet_clear(t *testing.T) { 161 s := newFieldCandidateSet("1", "2") 162 assert.NotEmpty(t, s.values()) 163 s.clear() 164 assert.Empty(t, s.values()) 165 } 166 167 func Test_cpeFieldCandidateSet_union(t *testing.T) { 168 s1 := newFieldCandidateSet("1", "2") 169 assert.Len(t, s1.list(), 2) 170 s2 := newFieldCandidateSet("2", "3", "4") 171 assert.Len(t, s2.list(), 3) 172 s3 := newFieldCandidateSet() 173 s3.add( 174 fieldCandidate{ 175 value: "1", 176 disallowSubSelections: true, 177 disallowDelimiterVariations: false, 178 }, 179 fieldCandidate{ 180 value: "4", 181 disallowSubSelections: false, 182 disallowDelimiterVariations: true, 183 }, 184 fieldCandidate{ 185 value: "5", 186 disallowSubSelections: true, 187 disallowDelimiterVariations: true, 188 }, 189 ) 190 assert.Len(t, s3.list(), 3) 191 192 s1.union(s2, s3) 193 194 // 1 & 4 have duplicate entries since there are candidate conditions set 195 assert.ElementsMatch(t, s1.values(), []string{"1", "1", "2", "3", "4", "4", "5"}) 196 197 assert.ElementsMatch(t, s1.list(), []fieldCandidate{ 198 { 199 value: "1", 200 }, 201 { 202 value: "1", 203 disallowSubSelections: true, 204 disallowDelimiterVariations: false, 205 }, 206 { 207 value: "2", 208 }, 209 { 210 value: "3", 211 }, 212 { 213 value: "4", 214 }, 215 { 216 value: "4", 217 disallowSubSelections: false, 218 disallowDelimiterVariations: true, 219 }, 220 { 221 value: "5", 222 disallowSubSelections: true, 223 disallowDelimiterVariations: true, 224 }, 225 }) 226 } 227 228 func Test_cpeFieldCandidateSet_union_byValue(t *testing.T) { 229 s1 := newFieldCandidateSet("1", "2") 230 assert.Len(t, s1.list(), 2) 231 s2 := newFieldCandidateSet("2", "3", "4") 232 assert.Len(t, s2.list(), 3) 233 s3 := newFieldCandidateSet("1", "4", "5") 234 assert.Len(t, s3.list(), 3) 235 236 s1.union(s2, s3) 237 238 assert.ElementsMatch(t, s1.values(), []string{"1", "2", "3", "4", "5"}) 239 240 assert.ElementsMatch(t, s1.list(), []fieldCandidate{ 241 { 242 value: "1", 243 }, 244 { 245 value: "2", 246 }, 247 { 248 value: "3", 249 }, 250 { 251 value: "4", 252 }, 253 { 254 value: "5", 255 }, 256 }) 257 } 258 259 func Test_cpeFieldCandidateSet_uniqueValues(t *testing.T) { 260 set := newFieldCandidateSet() 261 set.add( 262 fieldCandidate{ 263 value: "1", 264 }, 265 fieldCandidate{ 266 value: "1", 267 disallowSubSelections: true, 268 }, 269 fieldCandidate{ 270 value: "2", 271 disallowDelimiterVariations: true, 272 }, 273 fieldCandidate{ 274 value: "2", 275 }, 276 fieldCandidate{ 277 value: "3", 278 disallowSubSelections: true, 279 disallowDelimiterVariations: true, 280 }, 281 ) 282 283 assert.ElementsMatch(t, []string{"1", "2", "3"}, set.uniqueValues()) 284 285 } 286 287 func Test_cpeFieldCandidateSet_removeByValue(t *testing.T) { 288 s := newFieldCandidateSet() 289 290 // should be removed 291 s.add(fieldCandidate{ 292 value: "1", 293 disallowSubSelections: true, 294 disallowDelimiterVariations: true, 295 }) 296 s.add(fieldCandidate{ 297 value: "1", 298 disallowSubSelections: true, 299 }) 300 s.add(fieldCandidate{ 301 value: "1", 302 disallowDelimiterVariations: true, 303 }) 304 s.add(fieldCandidate{ 305 value: "1", 306 }) 307 308 // should not be removed 309 s.add(fieldCandidate{ 310 value: "2", 311 }) 312 313 assert.Len(t, s.values(), 5) 314 315 s.removeByValue("1") 316 317 assert.Len(t, s.values(), 1) 318 } 319 320 func Test_cpeFieldCandidateSet_removeByCondition(t *testing.T) { 321 s := newFieldCandidateSet() 322 323 // should be removed 324 s.add(fieldCandidate{ 325 value: "1", 326 disallowSubSelections: true, 327 }) 328 s.add(fieldCandidate{ 329 value: "hello-world", 330 }) 331 332 // should not be removed 333 s.add(fieldCandidate{ 334 value: "2", 335 }) 336 337 assert.Len(t, s.values(), 3) 338 339 s.removeWhere(func(candidate fieldCandidate) bool { 340 return candidate.disallowSubSelections == true 341 }) 342 343 assert.Len(t, s.values(), 2) 344 345 s.removeWhere(func(candidate fieldCandidate) bool { 346 return strings.Contains(candidate.value, "-") 347 }) 348 349 assert.Len(t, s.values(), 1) 350 }