github.com/openebs/api@v1.12.0/pkg/util/util_test.go (about)

     1  /*
     2  Copyright 2020 The OpenEBS Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package util
    18  
    19  import (
    20  	"reflect"
    21  	"testing"
    22  )
    23  
    24  func TestContainsString(t *testing.T) {
    25  	tests := map[string]struct {
    26  		array     []string
    27  		element   string
    28  		isPresent bool
    29  	}{
    30  		"contains string - positive test case - element is present": {
    31  			array:     []string{"hi", "hello"},
    32  			element:   "hello",
    33  			isPresent: true,
    34  		},
    35  		"contains string - positive test case - element is not present": {
    36  			array:     []string{"there", "you", "go"},
    37  			element:   "there",
    38  			isPresent: true,
    39  		},
    40  		"contains string - boundary test case - similar elements but not same": {
    41  			array:     []string{"hi there", "ok now"},
    42  			element:   "hi there ",
    43  			isPresent: false,
    44  		},
    45  	}
    46  
    47  	for name, mock := range tests {
    48  		t.Run(name, func(t *testing.T) {
    49  			isPresent := ContainsString(mock.array, mock.element)
    50  
    51  			if mock.isPresent != isPresent {
    52  				t.Fatalf("failed to test contains string: expected element '%t': actual element '%t'", mock.isPresent, isPresent)
    53  			}
    54  		})
    55  	}
    56  }
    57  
    58  func TestListDiff(t *testing.T) {
    59  	tests := map[string]struct {
    60  		listA        []string
    61  		listB        []string
    62  		expectedLen  int
    63  		expectedList []string
    64  	}{
    65  		"list diff operation - positive test case - element is present": {
    66  			listA:        []string{"hi", "hello", "crazzy"},
    67  			listB:        []string{"hello"},
    68  			expectedLen:  2,
    69  			expectedList: []string{"hi", "crazzy"},
    70  		},
    71  		"list diff operation - positive test case - element is not present": {
    72  			listA:        []string{},
    73  			listB:        []string{"there", "you", "go"},
    74  			expectedLen:  0,
    75  			expectedList: []string{},
    76  		},
    77  		"contains string - boundary test case - similar elements but not same": {
    78  			listA:        []string{"hi there", "ok now"},
    79  			listB:        []string{},
    80  			expectedLen:  2,
    81  			expectedList: []string{"hi there", "ok now"},
    82  		},
    83  	}
    84  
    85  	for name, mock := range tests {
    86  		name := name
    87  		mock := mock
    88  		t.Run(name, func(t *testing.T) {
    89  			resultArr := ListDiff(mock.listA, mock.listB)
    90  			if mock.expectedLen != len(resultArr) {
    91  				t.Fatalf("failed to test %q: expected element count '%d': actual element count '%d'", name, mock.expectedLen, len(resultArr))
    92  			}
    93  			if !reflect.DeepEqual(resultArr, mock.expectedList) {
    94  				t.Fatalf("failed to test %q: expected elements '%v': actual elements  '%v'", name, mock.expectedList, resultArr)
    95  			}
    96  		})
    97  	}
    98  }
    99  
   100  func TestListIntersection(t *testing.T) {
   101  	tests := map[string]struct {
   102  		listA        []string
   103  		listB        []string
   104  		expectedLen  int
   105  		expectedList []string
   106  	}{
   107  		"positive test case - element is present": {
   108  			listA:        []string{"hi", "hello", "crazzy"},
   109  			listB:        []string{"hello"},
   110  			expectedLen:  1,
   111  			expectedList: []string{"hello"},
   112  		},
   113  		"positive test case - ListA is empty": {
   114  			listA:        []string{},
   115  			listB:        []string{"there", "you", "go"},
   116  			expectedLen:  0,
   117  			expectedList: []string{},
   118  		},
   119  		"ListB is empty": {
   120  			listA:        []string{"hi there", "ok now"},
   121  			listB:        []string{},
   122  			expectedLen:  0,
   123  			expectedList: []string{},
   124  		},
   125  		"List is missmatch - boundary test case - similar elements but not same": {
   126  			listA:        []string{"hi there", "ok now"},
   127  			listB:        []string{"h ithere"},
   128  			expectedLen:  0,
   129  			expectedList: []string{},
   130  		},
   131  		"List is match in different order": {
   132  			listA:        []string{"hi there", "ok now"},
   133  			listB:        []string{"ok now", "hi there"},
   134  			expectedLen:  2,
   135  			expectedList: []string{"hi there", "ok now"},
   136  		},
   137  	}
   138  
   139  	for name, mock := range tests {
   140  		name := name
   141  		mock := mock
   142  		t.Run(name, func(t *testing.T) {
   143  			resultArr := ListIntersection(mock.listA, mock.listB)
   144  			if mock.expectedLen != len(resultArr) {
   145  				t.Fatalf("failed to test %q: expected element count '%d': actual element count '%d'", name, mock.expectedLen, len(resultArr))
   146  			}
   147  			if !reflect.DeepEqual(resultArr, mock.expectedList) {
   148  				t.Fatalf("failed to test %q: expected elements '%v': actual elements  '%v'", name, mock.expectedList, resultArr)
   149  			}
   150  		})
   151  	}
   152  }
   153  
   154  func TestContainsKey(t *testing.T) {
   155  	tests := map[string]struct {
   156  		mapOfObjs map[string]interface{}
   157  		searchKey string
   158  		hasKey    bool
   159  	}{
   160  		"contains key - +ve test case - map having the key": {
   161  			mapOfObjs: map[string]interface{}{
   162  				"k1": "v1",
   163  			},
   164  			searchKey: "k1",
   165  			hasKey:    true,
   166  		},
   167  		"contains key - +ve test case - map without the key": {
   168  			mapOfObjs: map[string]interface{}{
   169  				"k1": "v1",
   170  			},
   171  			searchKey: "k2",
   172  			hasKey:    false,
   173  		},
   174  		"contains key - +ve test case - empty map": {
   175  			mapOfObjs: map[string]interface{}{},
   176  			searchKey: "k1",
   177  			hasKey:    false,
   178  		},
   179  		"contains key - +ve test case - nil map": {
   180  			mapOfObjs: nil,
   181  			searchKey: "k1",
   182  			hasKey:    false,
   183  		},
   184  		"contains key - +ve test case - with empty search key": {
   185  			mapOfObjs: map[string]interface{}{
   186  				"k1": "v1",
   187  			},
   188  			searchKey: "",
   189  			hasKey:    false,
   190  		},
   191  	}
   192  
   193  	for name, mock := range tests {
   194  		t.Run(name, func(t *testing.T) {
   195  			hasKey := ContainsKey(mock.mapOfObjs, mock.searchKey)
   196  
   197  			if hasKey != mock.hasKey {
   198  				t.Fatalf("failed to test contains key: expected key '%s': actual 'not found'", mock.searchKey)
   199  			}
   200  		})
   201  	}
   202  }
   203  
   204  func TestContainKeys(t *testing.T) {
   205  	tests := map[string]struct {
   206  		mapOfObjs  map[string]interface{}
   207  		searchKeys []string
   208  		hasKeys    bool
   209  	}{
   210  		"contains key - +ve test case - map having the key": {
   211  			mapOfObjs: map[string]interface{}{
   212  				"k1": "v1",
   213  			},
   214  			searchKeys: []string{"k1"},
   215  			hasKeys:    true,
   216  		},
   217  		"contains key - +ve test case - map without the keys": {
   218  			mapOfObjs: map[string]interface{}{
   219  				"k1": "v1",
   220  			},
   221  			searchKeys: []string{"k2"},
   222  			hasKeys:    false,
   223  		},
   224  		"contains key - +ve test case - empty map": {
   225  			mapOfObjs:  map[string]interface{}{},
   226  			searchKeys: []string{"k1"},
   227  			hasKeys:    false,
   228  		},
   229  		"contains key - +ve test case - nil map": {
   230  			mapOfObjs:  nil,
   231  			searchKeys: []string{"k1"},
   232  			hasKeys:    false,
   233  		},
   234  		"contains key - +ve test case - with no search keys": {
   235  			mapOfObjs: map[string]interface{}{
   236  				"k1": "v1",
   237  			},
   238  			searchKeys: []string{},
   239  			hasKeys:    false,
   240  		},
   241  	}
   242  
   243  	for name, mock := range tests {
   244  		t.Run(name, func(t *testing.T) {
   245  			hasKeys := ContainKeys(mock.mapOfObjs, mock.searchKeys)
   246  
   247  			if hasKeys != mock.hasKeys {
   248  				t.Fatalf("failed to test contains key: expected key '%s': actual 'not found'", mock.searchKeys)
   249  			}
   250  		})
   251  	}
   252  }
   253  
   254  func TestMergeMap(t *testing.T) {
   255  	tests := map[string]struct {
   256  		Map1        map[string]interface{}
   257  		Map2        map[string]interface{}
   258  		expectedMap map[string]interface{}
   259  	}{
   260  		"merge map of 2 objects": {
   261  			Map1: map[string]interface{}{
   262  				"k1": "v1",
   263  			},
   264  			Map2: map[string]interface{}{
   265  				"k2": "v2",
   266  			},
   267  			expectedMap: map[string]interface{}{
   268  				"k1": "v1",
   269  				"k2": "v2",
   270  			},
   271  		},
   272  		"merge map of 2 similar key objects": {
   273  			Map1: map[string]interface{}{
   274  				"k1": "v1",
   275  			},
   276  			Map2: map[string]interface{}{
   277  				"k1": "v2",
   278  			},
   279  			expectedMap: map[string]interface{}{
   280  				"k1": "v2",
   281  			},
   282  		},
   283  		"merge map of different k/v objects": {
   284  			Map1: map[string]interface{}{
   285  				"k1": "v1",
   286  				"k2": "v1",
   287  				"k4": "v4",
   288  			},
   289  			Map2: map[string]interface{}{
   290  				"k1": "v2",
   291  				"k3": "v3",
   292  			},
   293  			expectedMap: map[string]interface{}{
   294  				"k1": "v2",
   295  				"k2": "v1",
   296  				"k4": "v4",
   297  				"k3": "v3",
   298  			},
   299  		},
   300  		"merge map of 1 nil objects": {
   301  			Map1: map[string]interface{}{
   302  				"k1": "v1",
   303  				"k2": "v1",
   304  				"k4": "v4",
   305  			},
   306  			Map2: nil,
   307  			expectedMap: map[string]interface{}{
   308  				"k1": "v1",
   309  				"k2": "v1",
   310  				"k4": "v4",
   311  			},
   312  		},
   313  		"merge map of nil values objects": {
   314  			Map1: map[string]interface{}{
   315  				"k1": "v1",
   316  				"k2": "v1",
   317  				"k4": "v4",
   318  			},
   319  			Map2: map[string]interface{}{
   320  				"k1": "",
   321  				"k3": "",
   322  			},
   323  
   324  			expectedMap: map[string]interface{}{
   325  				"k1": "",
   326  				"k2": "v1",
   327  				"k4": "v4",
   328  				"k3": "",
   329  			},
   330  		},
   331  	}
   332  
   333  	for name, maps := range tests {
   334  		t.Run(name, func(t *testing.T) {
   335  			MergedMap := MergeMaps(maps.Map1, maps.Map2)
   336  			if !reflect.DeepEqual(MergedMap, maps.expectedMap) {
   337  				t.Fatalf(" failed to test MergeMaps: expected Map '%v': actual Map '%v'", maps.expectedMap, MergedMap)
   338  			}
   339  		})
   340  
   341  	}
   342  }
   343  
   344  func TestRemoveString(t *testing.T) {
   345  	slice1 := []string{"val1", "val2", "val3"}
   346  	slice2 := []string{"val1", "val2", "val3", "val1"}
   347  	slice3 := []string{"val1", "val2", "val1", "val3"}
   348  	slice4 := []string{"val2", "val1", "val1", "val3"}
   349  	tests := map[string]struct {
   350  		actual      []string
   351  		removeValue string
   352  		expected    []string
   353  	}{
   354  		"value is at start":                 {slice1, "val1", []string{"val2", "val3"}},
   355  		"value is at end":                   {slice1, "val3", []string{"val1", "val2"}},
   356  		"value is in between":               {slice1, "val2", []string{"val1", "val3"}},
   357  		"value is twice at start & end":     {slice2, "val1", []string{"val2", "val3"}},
   358  		"value is twice at start & between": {slice3, "val1", []string{"val2", "val3"}},
   359  		"value is twice in between":         {slice4, "val1", []string{"val2", "val3"}},
   360  		"nil array and non empty value":     {nil, "val1", nil},
   361  		"empty string to be removed":        {slice1, "", slice1},
   362  		"nil array and empty string":        {nil, "", nil},
   363  	}
   364  	for name, test := range tests {
   365  		// pinning the values
   366  		name := name
   367  		test := test
   368  		t.Run(name, func(t *testing.T) {
   369  			newSlice := RemoveString(test.actual, test.removeValue)
   370  			if !reflect.DeepEqual(newSlice, test.expected) {
   371  				t.Fatalf(" failed to test RemoveString: expected slice '%v': actual slice '%v'", test.expected, newSlice)
   372  			}
   373  		})
   374  	}
   375  }