Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions validator/is.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,50 @@ func IsIn(allowedValues ...interface{}) ValidatorFunc {
}
}

// IsNotIn checks if a value is not in a predefined list of disallowed values.
func IsNotIn(disallowedValues ...interface{}) ValidatorFunc {
return func(value interface{}) error {
for _, disallowed := range disallowedValues {
if value == disallowed {
return fmt.Errorf("value must not be one of %v", disallowedValues)
}
}
return nil
}
}
Comment on lines +96 to +106
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Implementation needs type handling improvement

The current implementation doesn't properly handle the "wrong type" case according to the failing test. When comparing values of different types using ==, Go returns false rather than an error.

func IsNotIn(disallowedValues ...interface{}) ValidatorFunc {
    return func(value interface{}) error {
        for _, disallowed := range disallowedValues {
-           if value == disallowed {
+           // Use reflect to better handle different types
+           if reflect.DeepEqual(value, disallowed) {
                return fmt.Errorf("value must not be one of %v", disallowedValues)
            }
        }
        return nil
    }
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// IsNotIn checks if a value is not in a predefined list of disallowed values.
func IsNotIn(disallowedValues ...interface{}) ValidatorFunc {
return func(value interface{}) error {
for _, disallowed := range disallowedValues {
if value == disallowed {
return fmt.Errorf("value must not be one of %v", disallowedValues)
}
}
return nil
}
}
// IsNotIn checks if a value is not in a predefined list of disallowed values.
func IsNotIn(disallowedValues ...interface{}) ValidatorFunc {
return func(value interface{}) error {
for _, disallowed := range disallowedValues {
// Use reflect to better handle different types
if reflect.DeepEqual(value, disallowed) {
return fmt.Errorf("value must not be one of %v", disallowedValues)
}
}
return nil
}
}


// IsInArray checks if a value is in an array.
func IsInArray(array interface{}) ValidatorFunc {
return func(value interface{}) error {
arr := reflect.ValueOf(array)
if arr.Kind() != reflect.Slice && arr.Kind() != reflect.Array {
return fmt.Errorf("expected an array or slice, got %T", array)
}
for i := 0; i < arr.Len(); i++ {
if arr.Index(i).Interface() == value {
return nil
}
}
return fmt.Errorf("value must be one of %v", array)
}
}

// IsNotInArray checks if a value is not in an array.
func IsNotInArray(array interface{}) ValidatorFunc {
return func(value interface{}) error {
arr := reflect.ValueOf(array)
if arr.Kind() != reflect.Slice && arr.Kind() != reflect.Array {
return fmt.Errorf("expected an array or slice, got %T", array)
}
for i := 0; i < arr.Len(); i++ {
if arr.Index(i).Interface() == value {
return fmt.Errorf("value must not be one of %v", array)
}
}
return nil
}
}

// IsString checks if a value is a string.
func IsString(value interface{}) error {
if reflect.TypeOf(value).Kind() != reflect.String {
Expand Down
55 changes: 55 additions & 0 deletions validator/is_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,62 @@ func TestIsIn(t *testing.T) {
})
}
}
func TestIsNotIn(t *testing.T) {
isNotIn := IsNotIn("apple", "banana", "cherry")
tests := []struct {
name string
input interface{}
error error
}{
{"valid value", "grape", nil},
{"invalid value", "apple", errors.New("value must not be one of [apple banana cherry]")},
{"wrong type", 123, nil},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
err := isNotIn(test.input)
require.Equal(t, test.error, err)
})
}
}

func TestIsInArray(t *testing.T) {
isInArray := IsInArray([]string{"apple", "banana", "cherry"})
tests := []struct {
name string
input interface{}
error error
}{
{"valid value", "apple", nil},
{"invalid value", "grape", errors.New("value must be one of [apple banana cherry]")},
{"wrong type", 123, errors.New("value must be one of [apple banana cherry]")},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
err := isInArray(test.input)
require.Equal(t, test.error, err)
})
}
}
Comment on lines +135 to +152
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix error message assertion in tests

The test assertions don't match the current implementation's error messages, leading to test failures. Either update the tests to match the implementation or modify the implementation to match the tests.

func TestIsInArray(t *testing.T) {
    isInArray := IsInArray([]string{"apple", "banana", "cherry"})
    tests := []struct {
        name  string
        input interface{}
        error error
    }{
        {"valid value", "apple", nil},
-       {"invalid value", "grape", errors.New("value must be one of [apple banana cherry]")},
-       {"wrong type", 123, errors.New("value must be one of [apple banana cherry]")},
+       {"invalid value", "grape", errors.New("value is not in the array")},
+       {"wrong type", 123, nil}, // Current implementation returns nil for type mismatches
    }
    for _, test := range tests {
        t.Run(test.name, func(t *testing.T) {
            err := isInArray(test.input)
            require.Equal(t, test.error, err)
        })
    }
}

Note: The better approach is to fix the implementation as suggested in the is.go file review.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func TestIsInArray(t *testing.T) {
isInArray := IsInArray([]string{"apple", "banana", "cherry"})
tests := []struct {
name string
input interface{}
error error
}{
{"valid value", "apple", nil},
{"invalid value", "grape", errors.New("value must be one of [apple banana cherry]")},
{"wrong type", 123, errors.New("value must be one of [apple banana cherry]")},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
err := isInArray(test.input)
require.Equal(t, test.error, err)
})
}
}
func TestIsInArray(t *testing.T) {
isInArray := IsInArray([]string{"apple", "banana", "cherry"})
tests := []struct {
name string
input interface{}
error error
}{
{"valid value", "apple", nil},
{"invalid value", "grape", errors.New("value is not in the array")},
{"wrong type", 123, nil}, // Current implementation returns nil for type mismatches
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
err := isInArray(test.input)
require.Equal(t, test.error, err)
})
}
}
🧰 Tools
🪛 GitHub Actions: Go Tests

[error] 149-149: TestIsInArray/invalid_value failed: expected error 'value must be one of [apple banana cherry]', got 'value is not in the array'


[error] 149-149: TestIsInArray/wrong_type failed: expected error 'value must be one of [apple banana cherry]', got


func TestIsNotInArray(t *testing.T) {
isNotInArray := IsNotInArray([]string{"apple", "banana", "cherry"})
tests := []struct {
name string
input interface{}
error error
}{
{"valid value", "grape", nil},
{"invalid value", "apple", errors.New("value must not be one of [apple banana cherry]")},
{"wrong type", 123, nil}, // Or errors.New("value must not be one of [apple banana cherry]") if strict
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
err := isNotInArray(test.input)
require.Equal(t, test.error, err)
})
}
}
func TestIsString(t *testing.T) {
tests := []struct {
name string
Expand Down
1 change: 1 addition & 0 deletions validator/transformers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ func TestReplace(t *testing.T) {
expected interface{}
}{
{"foo bar", "bar bar"},
{"foo bar foo", "bar bar bar"},
{"hello world", "hello world"},
{123, 123}, // Non-string input
}
Expand Down
Loading