Skip to content

Commit

Permalink
add custom rule messages
Browse files Browse the repository at this point in the history
  • Loading branch information
aacebo committed Oct 7, 2024
1 parent 26708f4 commit 4859e3a
Show file tree
Hide file tree
Showing 21 changed files with 225 additions and 31 deletions.
21 changes: 16 additions & 5 deletions any.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type AnySchema struct {

func Any() *AnySchema {
self := &AnySchema{[]Rule{}}
self.Rule("type", self.Type(), func(value reflect.Value) (any, error) {
self.Rule("type", self.Type(), func(rule Rule, value reflect.Value) (any, error) {
if !value.IsValid() {
return nil, nil
}
Expand All @@ -38,8 +38,13 @@ func (self *AnySchema) Rule(key string, value any, rule RuleFn) *AnySchema {
return self
}

func (self *AnySchema) Message(message string) *AnySchema {
self.rules[len(self.rules)-1].Message = message
return self
}

func (self *AnySchema) Required() *AnySchema {
return self.Rule("required", true, func(value reflect.Value) (any, error) {
return self.Rule("required", true, func(rule Rule, value reflect.Value) (any, error) {
if !value.IsValid() {
return nil, errors.New("required")
}
Expand All @@ -49,7 +54,7 @@ func (self *AnySchema) Required() *AnySchema {
}

func (self *AnySchema) Enum(values ...any) *AnySchema {
return self.Rule("enum", values, func(value reflect.Value) (any, error) {
return self.Rule("enum", values, func(rule Rule, value reflect.Value) (any, error) {
if !value.IsValid() {
return nil, nil
}
Expand Down Expand Up @@ -86,10 +91,16 @@ func (self AnySchema) validate(key string, value reflect.Value) error {
continue
}

v, e := rule.Resolve(value)
v, e := rule.Resolve(rule, value)

if e != nil {
err = err.Add(NewError(rule.Key, key, e.Error()))
message := e.Error()

if rule.Message != "" {
message = rule.Message
}

err = err.Add(NewError(rule.Key, key, message))
continue
}

Expand Down
18 changes: 18 additions & 0 deletions any_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,24 @@ func Test_Any(t *testing.T) {
})
})

t.Run("message", func(t *testing.T) {
t.Run("should have custom error message", func(t *testing.T) {
err := owl.Any().Required().Message("a test message").Validate(nil)

if err == nil {
t.FailNow()
}

if err.Error() != `{"errors":[{"rule":"required","message":"a test message"}]}` {
t.Errorf(
"expected `%s`, received `%s`",
`{"errors":[{"rule":"required","message":"required"}]}`,
err.Error(),
)
}
})
})

t.Run("json", func(t *testing.T) {
t.Run("serialize", func(t *testing.T) {
schema := owl.Any().Enum(1, true, "hi").Required()
Expand Down
7 changes: 6 additions & 1 deletion bool.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type BoolSchema struct {

func Bool() *BoolSchema {
self := &BoolSchema{Any()}
self.Rule("type", self.Type(), func(value reflect.Value) (any, error) {
self.Rule("type", self.Type(), func(rule Rule, value reflect.Value) (any, error) {
if !value.IsValid() {
return nil, nil
}
Expand All @@ -36,6 +36,11 @@ func (self *BoolSchema) Rule(key string, value any, rule RuleFn) *BoolSchema {
return self
}

func (self *BoolSchema) Message(message string) *BoolSchema {
self.schema.Message(message)
return self
}

func (self *BoolSchema) Required() *BoolSchema {
self.schema.Required()
return self
Expand Down
18 changes: 18 additions & 0 deletions bool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,24 @@ func Test_Bool(t *testing.T) {
})
})

t.Run("message", func(t *testing.T) {
t.Run("should have custom error message", func(t *testing.T) {
err := owl.Bool().Required().Message("a test message").Validate(nil)

if err == nil {
t.FailNow()
}

if err.Error() != `{"errors":[{"rule":"required","message":"a test message"}]}` {
t.Errorf(
"expected `%s`, received `%s`",
`{"errors":[{"rule":"required","message":"required"}]}`,
err.Error(),
)
}
})
})

t.Run("json", func(t *testing.T) {
t.Run("serialize", func(t *testing.T) {
schema := owl.Bool()
Expand Down
2 changes: 1 addition & 1 deletion error.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func NewError(rule string, key string, message string) Error {
}

func (self Error) Error() string {
b, _ := json.MarshalIndent(self, "", " ")
b, _ := json.Marshal(self)
return string(b)
}

Expand Down
2 changes: 1 addition & 1 deletion error_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func (self ErrorGroup) Add(err error) ErrorGroup {
}

func (self ErrorGroup) Error() string {
b, _ := json.MarshalIndent(self, "", " ")
b, _ := json.Marshal(self)
return string(b)
}

Expand Down
4 changes: 2 additions & 2 deletions error_group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ func Test_ErrorGroup(t *testing.T) {
t.FailNow()
}

if len(err.Error()) != 507 {
if len(err.Error()) != 238 {
t.Errorf(
"expected `%d`, received `%d`",
507,
238,
len(err.Error()),
)
}
Expand Down
4 changes: 2 additions & 2 deletions error_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ func Test_Error(t *testing.T) {
t.FailNow()
}

if len(err.Error()) != 91 {
if len(err.Error()) != 57 {
t.Errorf(
"expected `%d`, received `%d`",
91,
57,
len(err.Error()),
)
}
Expand Down
11 changes: 8 additions & 3 deletions float.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type FloatSchema struct {

func Float() *FloatSchema {
self := &FloatSchema{Any()}
self.Rule("type", self.Type(), func(value reflect.Value) (any, error) {
self.Rule("type", self.Type(), func(rule Rule, value reflect.Value) (any, error) {
if !value.IsValid() {
return nil, nil
}
Expand Down Expand Up @@ -41,6 +41,11 @@ func (self *FloatSchema) Rule(key string, value any, rule RuleFn) *FloatSchema {
return self
}

func (self *FloatSchema) Message(message string) *FloatSchema {
self.schema.Message(message)
return self
}

func (self *FloatSchema) Required() *FloatSchema {
self.schema.Required()
return self
Expand All @@ -58,7 +63,7 @@ func (self *FloatSchema) Enum(values ...float64) *FloatSchema {
}

func (self *FloatSchema) Min(min float64) *FloatSchema {
return self.Rule("min", min, func(value reflect.Value) (any, error) {
return self.Rule("min", min, func(rule Rule, value reflect.Value) (any, error) {
if !value.IsValid() {
return nil, nil
}
Expand All @@ -72,7 +77,7 @@ func (self *FloatSchema) Min(min float64) *FloatSchema {
}

func (self *FloatSchema) Max(max float64) *FloatSchema {
return self.Rule("max", max, func(value reflect.Value) (any, error) {
return self.Rule("max", max, func(rule Rule, value reflect.Value) (any, error) {
if !value.IsValid() {
return nil, nil
}
Expand Down
18 changes: 18 additions & 0 deletions float_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,24 @@ func Test_Float(t *testing.T) {
})
})

t.Run("message", func(t *testing.T) {
t.Run("should have custom error message", func(t *testing.T) {
err := owl.Float().Required().Message("a test message").Validate(nil)

if err == nil {
t.FailNow()
}

if err.Error() != `{"errors":[{"rule":"required","message":"a test message"}]}` {
t.Errorf(
"expected `%s`, received `%s`",
`{"errors":[{"rule":"required","message":"required"}]}`,
err.Error(),
)
}
})
})

t.Run("type", func(t *testing.T) {
t.Run("should succeed when float", func(t *testing.T) {
err := owl.Float().Validate(1.5)
Expand Down
11 changes: 8 additions & 3 deletions int.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type IntSchema struct {

func Int() *IntSchema {
self := &IntSchema{Any()}
self.Rule("type", self.Type(), func(value reflect.Value) (any, error) {
self.Rule("type", self.Type(), func(rule Rule, value reflect.Value) (any, error) {
if !value.IsValid() {
return nil, nil
}
Expand Down Expand Up @@ -41,6 +41,11 @@ func (self *IntSchema) Rule(key string, value any, rule RuleFn) *IntSchema {
return self
}

func (self *IntSchema) Message(message string) *IntSchema {
self.schema.Message(message)
return self
}

func (self *IntSchema) Required() *IntSchema {
self.schema.Required()
return self
Expand All @@ -58,7 +63,7 @@ func (self *IntSchema) Enum(values ...int) *IntSchema {
}

func (self *IntSchema) Min(min int) *IntSchema {
return self.Rule("min", min, func(value reflect.Value) (any, error) {
return self.Rule("min", min, func(rule Rule, value reflect.Value) (any, error) {
if !value.IsValid() {
return nil, nil
}
Expand All @@ -72,7 +77,7 @@ func (self *IntSchema) Min(min int) *IntSchema {
}

func (self *IntSchema) Max(max int) *IntSchema {
return self.Rule("max", max, func(value reflect.Value) (any, error) {
return self.Rule("max", max, func(rule Rule, value reflect.Value) (any, error) {
if !value.IsValid() {
return nil, nil
}
Expand Down
18 changes: 18 additions & 0 deletions int_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,24 @@ func Test_Int(t *testing.T) {
})
})

t.Run("message", func(t *testing.T) {
t.Run("should have custom error message", func(t *testing.T) {
err := owl.Int().Required().Message("a test message").Validate(nil)

if err == nil {
t.FailNow()
}

if err.Error() != `{"errors":[{"rule":"required","message":"a test message"}]}` {
t.Errorf(
"expected `%s`, received `%s`",
`{"errors":[{"rule":"required","message":"required"}]}`,
err.Error(),
)
}
})
})

t.Run("min", func(t *testing.T) {
t.Run("should succeed when nil", func(t *testing.T) {
err := owl.Int().Min(5).Validate(nil)
Expand Down
7 changes: 6 additions & 1 deletion object.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type ObjectSchema struct {
func Object() *ObjectSchema {
self := &ObjectSchema{Any(), map[string]Schema{}}
self.Rule("fields", self.fields, nil)
self.Rule("type", self.Type(), func(value reflect.Value) (any, error) {
self.Rule("type", self.Type(), func(rule Rule, value reflect.Value) (any, error) {
if !value.IsValid() {
return nil, nil
}
Expand All @@ -38,6 +38,11 @@ func (self *ObjectSchema) Rule(key string, value any, rule RuleFn) *ObjectSchema
return self
}

func (self *ObjectSchema) Message(message string) *ObjectSchema {
self.schema.Message(message)
return self
}

func (self *ObjectSchema) Required() *ObjectSchema {
self.schema.Required()
return self
Expand Down
18 changes: 18 additions & 0 deletions object_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,24 @@ func Test_Object(t *testing.T) {
})
})

t.Run("message", func(t *testing.T) {
t.Run("should have custom error message", func(t *testing.T) {
err := owl.Object().Required().Message("a test message").Validate(nil)

if err == nil {
t.FailNow()
}

if err.Error() != `{"errors":[{"rule":"required","message":"a test message"}]}` {
t.Errorf(
"expected `%s`, received `%s`",
`{"errors":[{"rule":"required","message":"required"}]}`,
err.Error(),
)
}
})
})

t.Run("map", func(t *testing.T) {
t.Run("should succeed", func(t *testing.T) {
err := owl.Object().Field(
Expand Down
3 changes: 2 additions & 1 deletion rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import "reflect"
type Rule struct {
Key string `json:"key"`
Value any `json:"value"`
Message string `json:"message"`
Resolve RuleFn `json:"-"`
}

type RuleFn func(value reflect.Value) (any, error)
type RuleFn func(rule Rule, value reflect.Value) (any, error)
Loading

0 comments on commit 4859e3a

Please sign in to comment.