From 99200ca89b359e252134cb402de606bf0336c359 Mon Sep 17 00:00:00 2001 From: Onur Cinar Date: Thu, 15 Jun 2023 23:14:00 +0000 Subject: [PATCH] Same checker is added. --- README.md | 1 + checker.go | 1 + doc/checkers/same.md | 20 ++++++ check_required.go => required.go | 0 check_required_test.go => required_test.go | 0 same.go | 32 +++++++++ same_test.go | 80 ++++++++++++++++++++++ 7 files changed, 134 insertions(+) create mode 100644 doc/checkers/same.md rename check_required.go => required.go (100%) rename check_required_test.go => required_test.go (100%) create mode 100644 same.go create mode 100644 same_test.go diff --git a/README.md b/README.md index b89b0f5..0496e21 100644 --- a/README.md +++ b/README.md @@ -67,3 +67,4 @@ type Person struct { This package currently provides the following checkers: - [required](docs/checkers/required.md) checks if the required value is provided. +- [same](docs/checkers/same.md) checks if the given value is equal to the value of the field with the given name. diff --git a/checker.go b/checker.go index cf17830..f39a0a1 100644 --- a/checker.go +++ b/checker.go @@ -32,6 +32,7 @@ const ResultValid Result = "VALID" // makers provides mapping to maker function for the checkers. var makers = map[string]MakeFunc{ "required": makeRequired, + "same": makeSame, } // Register registers the given checker name and the maker function. diff --git a/doc/checkers/same.md b/doc/checkers/same.md new file mode 100644 index 0000000..7ee6e22 --- /dev/null +++ b/doc/checkers/same.md @@ -0,0 +1,20 @@ +# Same Checker + +The ```same``` checker checks if the given value is equal to the value of the other field specified by its name. If they are not equal, the checker will return the ```NOT_SAME``` result. In the example below, the ```same``` checker ensures that the value in the ```Confirm``` field matches the value in the ```Password``` field. + +```golang +type User struct { + Password string + Confirm string `checkers:"same:Password"` +} + +user := &User{ + Password: "1234", + Confirm: "1234", +} + +mistakes, valid := checker.Check(user) +if !valid { + // Send the mistakes back to the user +} +``` \ No newline at end of file diff --git a/check_required.go b/required.go similarity index 100% rename from check_required.go rename to required.go diff --git a/check_required_test.go b/required_test.go similarity index 100% rename from check_required_test.go rename to required_test.go diff --git a/same.go b/same.go new file mode 100644 index 0000000..15999e8 --- /dev/null +++ b/same.go @@ -0,0 +1,32 @@ +package checker + +import ( + "reflect" +) + +// ResultNotSame indicates that the given two values are not equal to each other. +const ResultNotSame = "NOT_SAME" + +// makeSame makes a checker function for the same checker. +func makeSame(config string) CheckFunc { + return func(value, parent reflect.Value) Result { + return checkSame(value, parent, config) + } +} + +// checkSame checks if the given value is equal to the value of the field with the given name. +func checkSame(value, parent reflect.Value, name string) Result { + other := parent.FieldByName(name) + + if !other.IsValid() { + panic("other field not found") + } + + other = reflect.Indirect(other) + + if !value.Equal(other) { + return ResultNotSame + } + + return ResultValid +} diff --git a/same_test.go b/same_test.go new file mode 100644 index 0000000..b2a1db8 --- /dev/null +++ b/same_test.go @@ -0,0 +1,80 @@ +package checker + +import ( + "reflect" + "testing" +) + +func TestSameValid(t *testing.T) { + type User struct { + Password string + Confirm string `checkers:"same:Password"` + } + + user := &User{ + Password: "1234", + Confirm: "1234", + } + + _, valid := Check(user) + if !valid { + t.Fail() + } +} + +func TestSameInvalid(t *testing.T) { + type User struct { + Password string + Confirm string `checkers:"same:Password"` + } + + user := &User{ + Password: "1234", + Confirm: "12", + } + + _, valid := Check(user) + if valid { + t.Fail() + } +} + +func TestSameWithoutParent(t *testing.T) { + defer func() { + if r := recover(); r == nil { + t.Fail() + } + }() + + type User struct { + Password string + Confirm string `checkers:"same:Password"` + } + + user := &User{ + Password: "1234", + Confirm: "12", + } + + checkSame(reflect.ValueOf(user.Confirm), reflect.ValueOf(nil), "Password") +} + +func TestSameInvalidName(t *testing.T) { + defer func() { + if r := recover(); r == nil { + t.Fail() + } + }() + + type User struct { + Password string + Confirm string `checkers:"same:Unknown"` + } + + user := &User{ + Password: "1234", + Confirm: "1234", + } + + Check(user) +}