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  }