-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit ad2a49c
Showing
4 changed files
with
148 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// Package check provides convenience helpers to perform validations of any | ||
// kind. | ||
// | ||
// Use That/Thatf to write conditions to check, multiple calls can be chained. | ||
// The last call in the chain must be either FirstError or AllErrors. | ||
package check | ||
|
||
import "fmt" | ||
|
||
// That checks whether cond is true, and if not, records the error. That panics | ||
// if the error is nil. | ||
func That(cond bool, err error) *check { | ||
return new(check).That(cond, err) | ||
} | ||
|
||
// Thatf checks whether cond is true, and if not, creates an error from format | ||
// and args, then records it. | ||
func Thatf(cond bool, format string, args ...any) *check { | ||
return That(cond, fmt.Errorf(format, args...)) | ||
} | ||
|
||
// check holds the conditions to check and their corresponding errors. | ||
type check struct { | ||
conds []bool | ||
errs []error | ||
} | ||
|
||
// That checks whether cond is true, and if not, records the error. That panics | ||
// if the error is nil. | ||
func (ch *check) That(cond bool, err error) *check { | ||
if err == nil { | ||
panic("check: a nil error is provided") | ||
} | ||
ch.conds = append(ch.conds, cond) | ||
ch.errs = append(ch.errs, err) | ||
return ch | ||
} | ||
|
||
// Thatf checks whether cond is true, and if not, creates an error from format | ||
// and args, then records it. | ||
func (ch *check) Thatf(cond bool, format string, args ...any) *check { | ||
return ch.That(cond, fmt.Errorf(format, args...)) | ||
} | ||
|
||
// FirstError returns the error of the first failed condition. | ||
func (ch *check) FirstError() error { | ||
for i := range ch.conds { | ||
if !ch.conds[i] { | ||
return ch.errs[i] | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
// AllErrors returns the errors of all failed conditions. | ||
func (ch *check) AllErrors() []error { | ||
var errs []error | ||
for i := range ch.conds { | ||
if !ch.conds[i] { | ||
errs = append(errs, ch.errs[i]) | ||
} | ||
} | ||
return errs | ||
} |
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,42 @@ | ||
package check_test | ||
|
||
import ( | ||
"errors" | ||
"testing" | ||
|
||
"github.com/junk1tm/check" | ||
) | ||
|
||
func TestCheck(t *testing.T) { | ||
t.Run("first error", func(t *testing.T) { | ||
err12 := errors.New("1 and 2 are not equal") | ||
err34 := errors.New("3 and 4 are not equal") | ||
|
||
err := check. | ||
That(1 == 2, err12). | ||
That(3 == 4, err34). | ||
FirstError() | ||
|
||
if !errors.Is(err, err12) { | ||
t.Errorf("got %v; want %v", err, err12) | ||
} | ||
}) | ||
|
||
t.Run("all errors", func(t *testing.T) { | ||
errs := check. | ||
Thatf("foo" == "baz", "foo and bar are not equal"). | ||
Thatf(true == false, "true and false are not equal"). | ||
AllErrors() | ||
|
||
if len(errs) != 2 { | ||
t.Fatalf("want 2 errors") | ||
} | ||
|
||
if errs[0] == nil || errs[1] == nil { | ||
t.Errorf("want all errors to be not nil") | ||
} | ||
}) | ||
|
||
// TODO(jun1ktm): test That's panic case | ||
// TODO(jun1ktm): test FirstError's nil case | ||
} |
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,39 @@ | ||
package check_test | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
|
||
"github.com/junk1tm/check" | ||
) | ||
|
||
var user = struct { | ||
Name string | ||
Age int | ||
Email string | ||
}{ | ||
Name: "", | ||
Age: 10, | ||
Email: "user@email", | ||
} | ||
|
||
func isEmail(string) bool { return false } | ||
|
||
var errEmptyName = errors.New("name must not be empty") | ||
|
||
func ExampleThat() { | ||
errs := check. | ||
That(user.Name != "", errEmptyName). | ||
Thatf(user.Age >= 18, "%d y.o. is too young", user.Age). | ||
Thatf(isEmail(user.Email), "%s is invalid email", user.Email). | ||
AllErrors() // OR FirstError() to check only the first error | ||
|
||
for _, err := range errs { | ||
fmt.Println(err) | ||
} | ||
|
||
// Output: | ||
// name must not be empty | ||
// 10 y.o. is too young | ||
// user@email is invalid email | ||
} |
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,3 @@ | ||
module github.com/junk1tm/check | ||
|
||
go 1.19 |