-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Gte and Lte checks are added. (#161)
# Describe Request Greater than or equal tp (Gte) and less than or equal to (Lte) checks are added. # Change Type New checks.
- Loading branch information
Showing
9 changed files
with
460 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// Copyright (c) 2023-2024 Onur Cinar. | ||
// Use of this source code is governed by a MIT-style | ||
// license that can be found in the LICENSE file. | ||
// https://github.com/cinar/checker | ||
|
||
package v2 | ||
|
||
import ( | ||
"cmp" | ||
"reflect" | ||
"strconv" | ||
) | ||
|
||
const ( | ||
// nameGte is the name of the greater than or equal to check. | ||
nameGte = "gte" | ||
) | ||
|
||
var ( | ||
// ErrGte indicates that the value is not greater than or equal to the given value. | ||
ErrGte = NewCheckError("NOT_GTE") | ||
) | ||
|
||
// IsGte checks if the value is greater than or equal to the given value. | ||
func IsGte[T cmp.Ordered](value, n T) (T, error) { | ||
if cmp.Compare(value, n) < 0 { | ||
return value, newGteError(n) | ||
} | ||
|
||
return value, nil | ||
} | ||
|
||
// makeGte creates a greater than or equal to check function from a string parameter. | ||
// Panics if the parameter cannot be parsed as a number. | ||
func makeGte(params string) CheckFunc[reflect.Value] { | ||
n, err := strconv.ParseFloat(params, 64) | ||
if err != nil { | ||
panic("unable to parse params as float") | ||
} | ||
|
||
return func(value reflect.Value) (reflect.Value, error) { | ||
v := reflect.Indirect(value) | ||
|
||
switch { | ||
case v.CanInt(): | ||
_, err := IsGte(float64(v.Int()), n) | ||
return v, err | ||
|
||
case v.CanFloat(): | ||
_, err := IsGte(v.Float(), n) | ||
return v, err | ||
|
||
default: | ||
panic("value is not numeric") | ||
} | ||
} | ||
} | ||
|
||
// newGteError creates a new greater than or equal to error with the given value. | ||
func newGteError[T cmp.Ordered](n T) error { | ||
return NewCheckErrorWithData( | ||
ErrGte.Code, | ||
map[string]interface{}{ | ||
"n": n, | ||
}, | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
// Copyright (c) 2023-2024 Onur Cinar. | ||
// Use of this source code is governed by a MIT-style | ||
// license that can be found in the LICENSE file. | ||
// https://github.com/cinar/checker | ||
|
||
package v2_test | ||
|
||
import ( | ||
"errors" | ||
"testing" | ||
|
||
v2 "github.com/cinar/checker/v2" | ||
) | ||
|
||
func TestGteIntSuccess(t *testing.T) { | ||
value := 4 | ||
|
||
result, err := v2.IsGte(value, 4) | ||
if result != value { | ||
t.Fatalf("result (%d) is not the original value (%d)", result, value) | ||
} | ||
|
||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
} | ||
|
||
func TestGteIntError(t *testing.T) { | ||
value := 4 | ||
|
||
result, err := v2.IsGte(value, 5) | ||
if result != value { | ||
t.Fatalf("result (%d) is not the original value (%d)", result, value) | ||
} | ||
|
||
if err == nil { | ||
t.Fatal("expected error") | ||
} | ||
|
||
message := "Value cannot be less than 5." | ||
|
||
if err.Error() != message { | ||
t.Fatalf("expected %s actual %s", message, err.Error()) | ||
} | ||
} | ||
|
||
func TestReflectGteIntError(t *testing.T) { | ||
type Person struct { | ||
Age int `checkers:"gte:18"` | ||
} | ||
|
||
person := &Person{ | ||
Age: 16, | ||
} | ||
|
||
errs, ok := v2.CheckStruct(person) | ||
if ok { | ||
t.Fatalf("expected errors") | ||
} | ||
|
||
if !errors.Is(errs["Age"], v2.ErrGte) { | ||
t.Fatalf("expected ErrGte") | ||
} | ||
} | ||
|
||
func TestReflectGteIntInvalidGte(t *testing.T) { | ||
defer FailIfNoPanic(t, "expected panic") | ||
|
||
type Person struct { | ||
Age int `checkers:"gte:abcd"` | ||
} | ||
|
||
person := &Person{ | ||
Age: 16, | ||
} | ||
|
||
v2.CheckStruct(person) | ||
} | ||
|
||
func TestReflectGteIntInvalidType(t *testing.T) { | ||
defer FailIfNoPanic(t, "expected panic") | ||
|
||
type Person struct { | ||
Age string `checkers:"gte:18"` | ||
} | ||
|
||
person := &Person{ | ||
Age: "18", | ||
} | ||
|
||
v2.CheckStruct(person) | ||
} | ||
|
||
func TestReflectGteFloatError(t *testing.T) { | ||
type Person struct { | ||
Weight float64 `checkers:"gte:165.0"` | ||
} | ||
|
||
person := &Person{ | ||
Weight: 150, | ||
} | ||
|
||
errs, ok := v2.CheckStruct(person) | ||
if ok { | ||
t.Fatalf("expected errors") | ||
} | ||
|
||
if !errors.Is(errs["Weight"], v2.ErrGte) { | ||
t.Fatalf("expected ErrGte") | ||
} | ||
} | ||
|
||
func TestReflectGteFloatInvalidGte(t *testing.T) { | ||
defer FailIfNoPanic(t, "expected panic") | ||
|
||
type Person struct { | ||
Weight float64 `checkers:"gte:abcd"` | ||
} | ||
|
||
person := &Person{ | ||
Weight: 170, | ||
} | ||
|
||
v2.CheckStruct(person) | ||
} | ||
|
||
func TestReflectGteFloatInvalidType(t *testing.T) { | ||
defer FailIfNoPanic(t, "expected panic") | ||
|
||
type Person struct { | ||
Weight string `checkers:"gte:165.0"` | ||
} | ||
|
||
person := &Person{ | ||
Weight: "170", | ||
} | ||
|
||
v2.CheckStruct(person) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.