Skip to content

Commit

Permalink
ASCII checker is added. (#36)
Browse files Browse the repository at this point in the history
Fixes #19
  • Loading branch information
cinar committed Jun 16, 2023
1 parent 312945f commit 3687719
Show file tree
Hide file tree
Showing 13 changed files with 159 additions and 45 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ type Person struct {

This package currently provides the following checkers:

- [ascii](doc/checkers/ascii.md) checks if the given string consists of only ASCII characters.
- [max](doc/checkers/max.md) checks if the given value is less than the given maximum.
- [max-length](doc/checkers/maxlength.md) checks if the length of the given value is less than the given maximum length.
- [min](doc/checkers/min.md) checks if the given value is greather than the given minimum.
Expand Down
37 changes: 37 additions & 0 deletions ascii.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package checker

import (
"reflect"
"unicode"
)

// CheckerAscii is the name of the checker.
const CheckerAscii = "ascii"

// ResultNotAscii indicates that the given string contains non-ASCII characters.
const ResultNotAscii = "NOT_ASCII"

// IsAscii checks if the given string consists of only ASCII characters.
func IsAscii(value string) Result {
for i := 0; i < len(value); i++ {
if value[i] > unicode.MaxASCII {
return ResultNotAscii
}
}

return ResultValid
}

// makeAscii makes a checker function for the ascii checker.
func makeAscii(_ string) CheckFunc {
return checkAscii
}

// checkAscii checks if the given string consists of only ASCII characters.
func checkAscii(value, _ reflect.Value) Result {
if value.Kind() != reflect.String {
panic("string expected")
}

return IsAscii(value.String())
}
57 changes: 57 additions & 0 deletions ascii_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package checker

import "testing"

func TestIsAsciiInvalid(t *testing.T) {
if IsAscii("𝄞 Music!") == ResultValid {
t.Fail()
}
}

func TestIsAsciiValid(t *testing.T) {
if IsAscii("Checker") != ResultValid {
t.Fail()
}
}

func TestCheckAsciiNonString(t *testing.T) {
defer FailIfNoPanic(t)

type User struct {
Age int `checkers:"ascii"`
}

user := &User{}

Check(user)
}

func TestCheckAsciiInvalid(t *testing.T) {
type User struct {
Username string `checkers:"ascii"`
}

user := &User{
Username: "𝄞 Music!",
}

_, valid := Check(user)
if valid {
t.Fail()
}
}

func TestCheckAsciiValid(t *testing.T) {
type User struct {
Username string `checkers:"ascii"`
}

user := &User{
Username: "checker",
}

_, valid := Check(user)
if !valid {
t.Fail()
}
}
1 change: 1 addition & 0 deletions checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const ResultValid Result = "VALID"

// makers provides mapping to maker function for the checkers.
var makers = map[string]MakeFunc{
CheckerAscii: makeAscii,
CheckerMax: makeMax,
CheckerMaxLength: makeMaxLength,
CheckerMin: makeMin,
Expand Down
18 changes: 3 additions & 15 deletions checker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,7 @@ import (
)

func TestInitCheckersUnknown(t *testing.T) {
defer func() {
if r := recover(); r == nil {
t.Fail()
}
}()
defer FailIfNoPanic(t)

initCheckers("unknown")
}
Expand Down Expand Up @@ -92,11 +88,7 @@ func TestCheckValid(t *testing.T) {
}

func TestCheckNoStruct(t *testing.T) {
defer func() {
if r := recover(); r == nil {
t.Fail()
}
}()
defer FailIfNoPanic(t)

s := "unknown"
Check(s)
Expand Down Expand Up @@ -133,11 +125,7 @@ func TestCheckNestedStruct(t *testing.T) {
}

func TestNumberOfInvalid(t *testing.T) {
defer func() {
if r := recover(); r == nil {
t.Fail()
}
}()
defer FailIfNoPanic(t)

s := "invalid"

Expand Down
28 changes: 28 additions & 0 deletions doc/checkers/ascii.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# ASCII Checker

The ```ascii``` checkr checks if the given string consists of only ASCII characters. If the string contains non-ASCII characters, the checker will return the ```NOT_ASCII``` result. Here is an example:

```golang
type User struct {
Username string `checkers:"ascii"`
}

user := &User{
Username: "checker",
}

_, valid := Check(user)
if !valid {
// Send the mistakes back to the user
}
```

In your custom checkers, you can call the ```ascii``` checker function ```IsAscii``` to validate the user input. Here is an example:

```golang
result := IsAscii("Checker")

if result != ResultValid {
// Send the mistakes back to the user
}
```
6 changes: 1 addition & 5 deletions max_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@ func TestIsMaxValid(t *testing.T) {
}

func TestCheckMaxInvalidConfig(t *testing.T) {
defer func() {
if r := recover(); r == nil {
t.Fail()
}
}()
defer FailIfNoPanic(t)

type Order struct {
Quantity int `checkers:"max:AB"`
Expand Down
6 changes: 1 addition & 5 deletions maxlength_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@ func TestIsMaxLengthValid(t *testing.T) {
}

func TestCheckMaxLengthInvalidConfig(t *testing.T) {
defer func() {
if r := recover(); r == nil {
t.Fail()
}
}()
defer FailIfNoPanic(t)

type User struct {
Password string `checkers:"max-length:AB"`
Expand Down
6 changes: 1 addition & 5 deletions min_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@ func TestIsMinValid(t *testing.T) {
}

func TestCheckMinInvalidConfig(t *testing.T) {
defer func() {
if r := recover(); r == nil {
t.Fail()
}
}()
defer FailIfNoPanic(t)

type User struct {
Age int `checkers:"min:AB"`
Expand Down
6 changes: 1 addition & 5 deletions minlength_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@ func TestIsMinLengthValid(t *testing.T) {
}

func TestCheckMinLengthInvalidConfig(t *testing.T) {
defer func() {
if r := recover(); r == nil {
t.Fail()
}
}()
defer FailIfNoPanic(t)

type User struct {
Password string `checkers:"min-length:AB"`
Expand Down
12 changes: 2 additions & 10 deletions same_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,7 @@ func TestSameInvalid(t *testing.T) {
}

func TestSameWithoutParent(t *testing.T) {
defer func() {
if r := recover(); r == nil {
t.Fail()
}
}()
defer FailIfNoPanic(t)

type User struct {
Password string
Expand All @@ -60,11 +56,7 @@ func TestSameWithoutParent(t *testing.T) {
}

func TestSameInvalidName(t *testing.T) {
defer func() {
if r := recover(); r == nil {
t.Fail()
}
}()
defer FailIfNoPanic(t)

type User struct {
Password string
Expand Down
13 changes: 13 additions & 0 deletions test_helper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//go:build !test

Check failure on line 1 in test_helper.go

View workflow job for this annotation

GitHub Actions / build

fixed buildtag
// +build !test

package checker

import "testing"

// FailIfNoPanic fails if test didn't panic. Use this function with the defer.
func FailIfNoPanic(t *testing.T) {
if r := recover(); r == nil {
t.Fail()
}
}
13 changes: 13 additions & 0 deletions test_helper_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package checker

import "testing"

func TestFailIfNoPanicValid(t *testing.T) {
defer FailIfNoPanic(t)
panic("")
}

func TestFailIfNoPanicInvalid(t *testing.T) {
defer FailIfNoPanic(t)
defer FailIfNoPanic(nil)
}

0 comments on commit 3687719

Please sign in to comment.