github.com/angryronald/go-kit@v0.0.0-20240505173814-ff2bd9c79dbf/generic/repository/memcached/generic.utils_test.go (about)

     1  package memcached
     2  
     3  import (
     4  	"reflect"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  
    10  	"github.com/angryronald/go-kit/generic/repository"
    11  )
    12  
    13  func TestCheckRelationalOperation(t *testing.T) {
    14  	tests := []struct {
    15  		prev      bool
    16  		current   bool
    17  		operation repository.RelationalOperation
    18  		expected  bool
    19  		expectErr error
    20  	}{
    21  		{true, true, repository.AND, true, nil},
    22  		{true, false, repository.AND, false, nil},
    23  		{true, true, repository.OR, true, nil},
    24  		{false, false, repository.OR, false, nil},
    25  		{true, true, repository.RelationalOperation("!"), false, repository.ErrNotImplement},
    26  	}
    27  
    28  	for _, test := range tests {
    29  		result, err := checkRelationalOperation(test.prev, test.current, test.operation)
    30  
    31  		if err != nil && err != test.expectErr {
    32  			t.Errorf("Expected no error, but got error: %v", err)
    33  		}
    34  
    35  		if result != test.expected {
    36  			t.Errorf("Expected result %v, but got %v", test.expected, result)
    37  		}
    38  	}
    39  }
    40  
    41  func TestCheckConditionalOperation(t *testing.T) {
    42  	tests := []struct {
    43  		expected       interface{}
    44  		actual         interface{}
    45  		operation      repository.ConditionalOperation
    46  		expectedResult bool
    47  		expectErr      error
    48  	}{
    49  		{"hello", "world", repository.EQUAL_WITH, false, nil},
    50  		{42, 43, repository.GREATER_THAN, true, nil},
    51  		{"prefix%", "prefixsum", repository.LIKE, true, nil},
    52  		{"%suffix", "thereisasuffix", repository.LIKE, true, nil},
    53  		{"%substring%", "thisissubstringinthemiddle", repository.LIKE, true, nil},
    54  		{"%substring", "thisissub", repository.LIKE, false, nil},
    55  		{"abc", nil, repository.IS, false, repository.ErrNotImplement},
    56  		{"abc", nil, repository.IS_NOT, false, repository.ErrNotImplement},
    57  		{"abc", nil, repository.IN, false, repository.ErrNotImplement},
    58  	}
    59  
    60  	for _, test := range tests {
    61  		result, err := checkConditionalOperation(test.expected, test.actual, test.operation)
    62  
    63  		if err != nil && err != test.expectErr {
    64  			t.Errorf("Expected no error, but got error: %v", err)
    65  		}
    66  
    67  		if result != test.expectedResult {
    68  			t.Errorf("Expected result %v, but got %v", test.expectedResult, result)
    69  		}
    70  	}
    71  }
    72  
    73  func TestExtractObjectAndCheckConditions(t *testing.T) {
    74  	type TestStruct struct {
    75  		Field1 string
    76  		Field2 int
    77  	}
    78  
    79  	params := map[string]interface{}{
    80  		"FIELD1": "hello",
    81  		"Field2": 42,
    82  	}
    83  
    84  	tests := []struct {
    85  		object         interface{}
    86  		conditionalOps []repository.ConditionalOperation
    87  		relationalOps  []repository.RelationalOperation
    88  		expectedResult bool
    89  		expectErr      bool
    90  	}{
    91  		{TestStruct{"hello", 43}, []repository.ConditionalOperation{repository.EQUAL_WITH, repository.GREATER_THAN}, []repository.RelationalOperation{repository.AND}, true, false},
    92  		{TestStruct{"world", 23}, []repository.ConditionalOperation{repository.EQUAL_WITH, repository.GREATER_THAN}, []repository.RelationalOperation{repository.AND}, false, false},
    93  	}
    94  
    95  	for _, test := range tests {
    96  		result, err := extractObjectAndCheckConditions(test.object, params, test.conditionalOps, test.relationalOps)
    97  
    98  		if err != nil && !test.expectErr {
    99  			t.Errorf("Expected no error, but got error: %v", err)
   100  		}
   101  
   102  		if result != test.expectedResult {
   103  			t.Errorf("Expected result %v, but got %v", test.expectedResult, result)
   104  		}
   105  	}
   106  }
   107  
   108  // func TestCreateStructPointerSlice(t *testing.T) {
   109  // 	type Person struct {
   110  // 		Name string
   111  // 		Age  int
   112  // 	}
   113  
   114  // 	type Address struct {
   115  // 		Street  string
   116  // 		City    string
   117  // 		ZipCode string
   118  // 	}
   119  
   120  // 	// Create a slice of struct pointers for the Person struct.
   121  // 	personSlice := CreateStructPointerSlice(Person{}, 3)
   122  
   123  // 	// Check if the returned value is a slice of pointers to the correct struct type.
   124  // 	if reflect.TypeOf(personSlice).Kind() != reflect.Slice {
   125  // 		t.Errorf("Expected a slice, got %v", reflect.TypeOf(personSlice))
   126  // 	}
   127  
   128  // 	elemType := reflect.TypeOf(personSlice).Elem()
   129  // 	if elemType.Kind() != reflect.Ptr || elemType.Elem() != reflect.TypeOf(Person{}) {
   130  // 		t.Errorf("Expected a slice of pointers to Person, got %v", elemType)
   131  // 	}
   132  
   133  // 	// Access and modify elements in the slice.
   134  // 	// Note that you need to use reflection to set field values.
   135  // 	for i := 0; i < 3; i++ {
   136  // 		personPtr := personSlice.([]*Person)[i]
   137  // 		personPtr.Name = fmt.Sprintf("Person%d", i+1)
   138  // 		personPtr.Age = 30 + i
   139  // 	}
   140  
   141  // 	// Check if the modifications were successful.
   142  // 	for i, personPtr := range personSlice.([]*Person) {
   143  // 		expectedName := fmt.Sprintf("Person%d", i+1)
   144  // 		expectedAge := 30 + i
   145  
   146  // 		if personPtr.Name != expectedName {
   147  // 			t.Errorf("Expected Name: %s, got: %s", expectedName, personPtr.Name)
   148  // 		}
   149  
   150  // 		if personPtr.Age != expectedAge {
   151  // 			t.Errorf("Expected Age: %d, got: %d", expectedAge, personPtr.Age)
   152  // 		}
   153  // 	}
   154  
   155  // 	// Create a slice of struct pointers for the Address struct.
   156  // 	addressSlice := CreateStructPointerSlice(Address{}, 2)
   157  
   158  // 	// Check if the returned value is a slice of pointers to the correct struct type.
   159  // 	if reflect.TypeOf(addressSlice).Kind() != reflect.Slice {
   160  // 		t.Errorf("Expected a slice, got %v", reflect.TypeOf(addressSlice))
   161  // 	}
   162  
   163  // 	elemType = reflect.TypeOf(addressSlice).Elem()
   164  // 	if elemType.Kind() != reflect.Ptr || elemType.Elem() != reflect.TypeOf(Address{}) {
   165  // 		t.Errorf("Expected a slice of pointers to Address, got %v", elemType)
   166  // 	}
   167  // }
   168  
   169  func TestCreateStructPointerSlice(t *testing.T) {
   170  	type Person struct {
   171  		Name  string
   172  		Age   int
   173  		City  string
   174  		Email string
   175  	}
   176  
   177  	// Create a sample struct object.
   178  	originalStruct := Person{
   179  		Name:  "John",
   180  		Age:   30,
   181  		City:  "New York",
   182  		Email: "john@example.com",
   183  	}
   184  
   185  	// Create a slice of pointers to the struct.
   186  	result := CreateStructPointerSlice(originalStruct, 3)
   187  
   188  	// Check the type of the result.
   189  	resultType := reflect.TypeOf(result)
   190  
   191  	// Ensure that the result is a slice.
   192  	if resultType.Kind() != reflect.Slice {
   193  		t.Errorf("Expected a slice, got %v", resultType.Kind())
   194  	}
   195  
   196  	// Check the length of the slice.
   197  	sliceValue := reflect.ValueOf(result)
   198  	if sliceValue.Len() != 3 {
   199  		t.Errorf("Expected slice length of 3, got %v", sliceValue.Len())
   200  	}
   201  
   202  	// Check that elements in the slice are pointers to the correct struct type.
   203  	for i := 0; i < sliceValue.Len(); i++ {
   204  		elem := sliceValue.Index(i).Interface()
   205  		elemType := reflect.TypeOf(elem)
   206  
   207  		if elemType.Kind() != reflect.Ptr {
   208  			t.Errorf("Expected pointer to struct, got %v", elemType.Kind())
   209  		}
   210  
   211  		if elemType.Elem() != reflect.TypeOf(originalStruct) {
   212  			t.Errorf("Expected pointer to %v, got pointer to %v", reflect.TypeOf(originalStruct), elemType.Elem())
   213  		}
   214  	}
   215  }
   216  
   217  func TestCreateNewStructObject(t *testing.T) {
   218  	// Define a sample struct for testing.
   219  	type TestStruct struct {
   220  		Name string
   221  		Age  int
   222  	}
   223  
   224  	// Create an instance of the sample struct.
   225  	inputStruct := TestStruct{
   226  		Name: "Alice",
   227  		Age:  30,
   228  	}
   229  
   230  	// Call the function to create a new struct object.
   231  	newObject := CreateNewStructObject(inputStruct)
   232  
   233  	// Check if the new object is of the same type as the input struct.
   234  	if reflect.TypeOf(newObject) != reflect.TypeOf(inputStruct) {
   235  		t.Errorf("Expected object of type %T, got %T", inputStruct, newObject)
   236  	}
   237  
   238  	// If you expect specific default values, you can check them here.
   239  	// For example, check if Age is 30.
   240  	if newObj, ok := newObject.(TestStruct); ok {
   241  		if newObj.Age != 30 {
   242  			t.Errorf("Expected Age to be %d, got %d", inputStruct.Age, newObj.Age)
   243  		}
   244  	} else {
   245  		t.Errorf("Failed to convert newObject to TestStruct")
   246  	}
   247  }
   248  
   249  func TestCreateNewStructObject_WithStructPointerObject(t *testing.T) {
   250  	// Define a sample struct for testing.
   251  	type TestStruct struct {
   252  		Name string
   253  		Age  int
   254  	}
   255  
   256  	// Create an instance of the sample struct.
   257  	inputStruct := &TestStruct{
   258  		Name: "Alice",
   259  		Age:  30,
   260  	}
   261  
   262  	// Call the function to create a new struct object.
   263  	newObject := CreateNewStructObject(inputStruct)
   264  
   265  	// Check if the new object is of the same type as the input struct.
   266  	if reflect.TypeOf(newObject) != reflect.TypeOf(inputStruct) {
   267  		t.Errorf("Expected object of type %T, got %T", inputStruct, newObject)
   268  	}
   269  
   270  	// If you expect specific default values, you can check them here.
   271  	// For example, check if Age is 30.
   272  	if newObj, ok := newObject.(*TestStruct); ok {
   273  		if newObj.Age != 30 {
   274  			t.Errorf("Expected Age to be %d, got %d", inputStruct.Age, newObj.Age)
   275  		}
   276  	} else {
   277  		t.Errorf("Failed to convert newObject to TestStruct")
   278  	}
   279  }
   280  
   281  func TestFindItemByID(t *testing.T) {
   282  	// Create a sample collection
   283  	type TestStruct struct {
   284  		ID   string
   285  		Name string
   286  	}
   287  
   288  	collection := []interface{}{
   289  		&TestStruct{ID: "1", Name: "Item 1"},
   290  		&TestStruct{ID: "2", Name: "Item 2"},
   291  		&TestStruct{ID: "3", Name: "Item 3"},
   292  	}
   293  
   294  	// Test case 1: Item found
   295  	index, err := findItemByID(collection, &TestStruct{ID: "2"})
   296  	assert.NoError(t, err)
   297  	assert.Equal(t, 1, index)
   298  
   299  	// Test case 2: Item not found
   300  	index, err = findItemByID(collection, &TestStruct{ID: "4"})
   301  	assert.Error(t, err)
   302  	assert.Equal(t, -1, index)
   303  }
   304  
   305  func TestUpdateCollection(t *testing.T) {
   306  	// Create a sample collection
   307  	type TestStruct struct {
   308  		ID   string
   309  		Name string
   310  	}
   311  
   312  	collection := []interface{}{
   313  		&TestStruct{ID: "1", Name: "Item 1"},
   314  		&TestStruct{ID: "2", Name: "Item 2"},
   315  		&TestStruct{ID: "3", Name: "Item 3"},
   316  	}
   317  
   318  	// Update an item
   319  	newItem := &TestStruct{ID: "2", Name: "Updated Item 2"}
   320  	updatedCollection, err := UpdateCollection(collection, newItem)
   321  	assert.NoError(t, err)
   322  
   323  	// Verify that the item was updated
   324  	assert.Equal(t, newItem, updatedCollection[1])
   325  }
   326  
   327  func TestDeleteCollection(t *testing.T) {
   328  	// Create a sample collection
   329  	type TestStruct struct {
   330  		ID   string
   331  		Name string
   332  	}
   333  
   334  	collection := []interface{}{
   335  		&TestStruct{ID: "1", Name: "Item 1"},
   336  		&TestStruct{ID: "2", Name: "Item 2"},
   337  		&TestStruct{ID: "3", Name: "Item 3"},
   338  	}
   339  
   340  	// Delete an item
   341  	itemToDelete := &TestStruct{ID: "2"}
   342  	updatedCollection, err := DeleteCollection(collection, itemToDelete)
   343  	assert.NoError(t, err)
   344  
   345  	// Verify that the item was deleted
   346  	for _, item := range updatedCollection {
   347  		assert.NotEqual(t, itemToDelete, item)
   348  	}
   349  }
   350  
   351  func TestAreStructsEqual(t *testing.T) {
   352  	type Person struct {
   353  		Name string
   354  		Age  int
   355  	}
   356  
   357  	type Employee struct {
   358  		Name string
   359  		Age  int
   360  	}
   361  
   362  	tests := []struct {
   363  		name     string
   364  		struct1  interface{}
   365  		struct2  interface{}
   366  		expected bool
   367  	}{
   368  		{
   369  			name:     "EqualStructs",
   370  			struct1:  Person{Name: "Alice", Age: 30},
   371  			struct2:  Person{Name: "Alice", Age: 30},
   372  			expected: true,
   373  		},
   374  		{
   375  			name:     "NotEqualStructs",
   376  			struct1:  Person{Name: "Alice", Age: 30},
   377  			struct2:  Person{Name: "Bob", Age: 25},
   378  			expected: false,
   379  		},
   380  		{
   381  			name:     "DifferentStructTypes",
   382  			struct1:  Person{Name: "Alice", Age: 30},
   383  			struct2:  Employee{Name: "Alice", Age: 30},
   384  			expected: false,
   385  		},
   386  	}
   387  
   388  	for _, test := range tests {
   389  		t.Run(test.name, func(t *testing.T) {
   390  			result := AreStructsEqual(test.struct1, test.struct2)
   391  			if result != test.expected {
   392  				t.Errorf("Expected AreStructsEqual to return %v, but got %v", test.expected, result)
   393  			}
   394  		})
   395  	}
   396  }
   397  
   398  func TestGetPropertyNameToUpperCaseMapping(t *testing.T) {
   399  	type User struct {
   400  		FirstName string
   401  		LastName  string
   402  		Email     string
   403  	}
   404  
   405  	user := User{}
   406  	mapping, err := GetPropertyNameToUpperCaseMapping(user)
   407  	if err != nil {
   408  		t.Errorf("Expected no error, but got: %v", err)
   409  	}
   410  
   411  	expectedMapping := map[string]string{
   412  		"FirstName": "FIRSTNAME",
   413  		"LastName":  "LASTNAME",
   414  		"Email":     "EMAIL",
   415  	}
   416  
   417  	if !reflect.DeepEqual(mapping, expectedMapping) {
   418  		t.Errorf("Mapping not as expected. Got: %v, Expected: %v", mapping, expectedMapping)
   419  	}
   420  }
   421  
   422  func TestGetPropertyNameToUpperCaseMappingWithNonStruct(t *testing.T) {
   423  	nonStruct := "This is not a struct"
   424  	_, err := GetPropertyNameToUpperCaseMapping(nonStruct)
   425  	if err == nil {
   426  		t.Error("Expected an error, but got none")
   427  	} else if !strings.Contains(err.Error(), "input must be a struct") {
   428  		t.Errorf("Expected error message containing 'input must be a struct', but got: %v", err)
   429  	}
   430  }
   431  
   432  func TestGetPropertyNameToUpperCaseMappingWithEmptyStruct(t *testing.T) {
   433  	emptyStruct := struct{}{}
   434  	_, err := GetPropertyNameToUpperCaseMapping(emptyStruct)
   435  	if err != nil {
   436  		t.Errorf("Expected no error, but got: %v", err)
   437  	}
   438  }