Initial commit, valiwork as framework is ready to use.
This commit is contained in:
commit
169b9499fe
83
.drone.yml
Normal file
83
.drone.yml
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
type: docker
|
||||||
|
name: build
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: notify-start
|
||||||
|
image: pztrn/discordrone
|
||||||
|
settings:
|
||||||
|
webhook_id:
|
||||||
|
from_secret: discord_webhook_id
|
||||||
|
webhook_token:
|
||||||
|
from_secret: discord_webhook_secret
|
||||||
|
message: 'Starting testing, benchmarking and linting for **{{repo.name}}#{{build.number}}@{{commit.sha}}** @ {{datetime build.started "02-Jan-2006 15:04:05 MST" "Asia/Yekaterinburg"}} (See {{build.link}} for logs).'
|
||||||
|
|
||||||
|
- name: lint
|
||||||
|
image: golangci/golangci-lint:latest
|
||||||
|
environment:
|
||||||
|
CGO_ENABLED: 0
|
||||||
|
commands:
|
||||||
|
- golangci-lint run
|
||||||
|
depends_on:
|
||||||
|
- notify-start
|
||||||
|
|
||||||
|
- name: test
|
||||||
|
image: golang:1.13.4-alpine
|
||||||
|
environment:
|
||||||
|
CGO_ENABLED: 0
|
||||||
|
commands:
|
||||||
|
- go test -test.v ./...
|
||||||
|
depends_on:
|
||||||
|
- notify-start
|
||||||
|
|
||||||
|
- name: test-race
|
||||||
|
image: golang:1.13.4-alpine
|
||||||
|
environment:
|
||||||
|
CGO_ENABLED: 0
|
||||||
|
commands:
|
||||||
|
- go test -race -test.v ./...
|
||||||
|
depends_on:
|
||||||
|
- notify-start
|
||||||
|
|
||||||
|
- name: benchmark
|
||||||
|
image: golang:1.13.4-alpine
|
||||||
|
environment:
|
||||||
|
CGO_ENABLED: 0
|
||||||
|
commands:
|
||||||
|
- go test -benchmem -run=^$ go.dev.pztrn.name/valiwork -bench .
|
||||||
|
depends_on:
|
||||||
|
- notify-start
|
||||||
|
|
||||||
|
- name: benchmark-race
|
||||||
|
image: golang:1.13.4-alpine
|
||||||
|
environment:
|
||||||
|
CGO_ENABLED: 0
|
||||||
|
commands:
|
||||||
|
- go test -benchmem -run=^$ go.dev.pztrn.name/valiwork -race -bench .
|
||||||
|
depends_on:
|
||||||
|
- notify-start
|
||||||
|
|
||||||
|
- name: notify-end
|
||||||
|
when:
|
||||||
|
status:
|
||||||
|
- success
|
||||||
|
- failure
|
||||||
|
image: pztrn/discordrone
|
||||||
|
settings:
|
||||||
|
webhook_id:
|
||||||
|
from_secret: discord_webhook_id
|
||||||
|
webhook_token:
|
||||||
|
from_secret: discord_webhook_secret
|
||||||
|
message: "
|
||||||
|
{{#success build.status}}
|
||||||
|
**{{repo.name}}#{{build.number}}@{{commit.sha}}** tested, benchmarked and linted successfully.
|
||||||
|
{{ else }}
|
||||||
|
**{{repo.name}}#{{build.number}}@{{commit.sha}}** failed. See {{build.link}}.
|
||||||
|
{{/success}}"
|
||||||
|
depends_on:
|
||||||
|
- benchmark
|
||||||
|
- benchmark-race
|
||||||
|
- lint
|
||||||
|
- test
|
||||||
|
- test-race
|
17
.golangci.yml
Normal file
17
.golangci.yml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
run:
|
||||||
|
deadline: 5m
|
||||||
|
linters:
|
||||||
|
enable-all: true
|
||||||
|
disable:
|
||||||
|
# Because globals might exist, but according to our codestyle they
|
||||||
|
# should be lowercased and considered as unexported.
|
||||||
|
- gochecknoglobals
|
||||||
|
# While it might be useful it'll create more problems that will solve.
|
||||||
|
- gocritic
|
||||||
|
# This linter goes crazy for nothing (almost).
|
||||||
|
- funlen
|
||||||
|
linters-settings:
|
||||||
|
lll:
|
||||||
|
line-length: 420
|
||||||
|
gocyclo:
|
||||||
|
min-complexity: 40
|
27
README.md
Normal file
27
README.md
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# ValiWork - validation framework
|
||||||
|
|
||||||
|
ValiWork is a validation framework that provides sane API and ability to write own validators that returns arbitrary things. It is goroutine-safe and fast.
|
||||||
|
|
||||||
|
## Default validators
|
||||||
|
|
||||||
|
There are no necessity to enable default validators at all. But if you want to - call:
|
||||||
|
|
||||||
|
```go
|
||||||
|
valiwork.InitializeDefaultValidators()
|
||||||
|
```
|
||||||
|
|
||||||
|
Default validators will return ``error``.
|
||||||
|
|
||||||
|
## Validators registering and namespacing
|
||||||
|
|
||||||
|
Default validators using "T_N" scheme, where ``T`` is data type (string, int, int64, etc.) and ``N`` is a validator name (which can be a generic string). Please, use same naming scheme. Example good validators names:
|
||||||
|
|
||||||
|
* ``string_check_for_very_rare_symbol_that_is_not_allowed``
|
||||||
|
* ``int64_check_if_in_bad_range``
|
||||||
|
* ``interface_check_if_able_to_be_TheVeryGoodStruct``
|
||||||
|
|
||||||
|
Key idea is to help you debugging this thing (see [debug section](#Debug) below).
|
||||||
|
|
||||||
|
## Debug
|
||||||
|
|
||||||
|
Define ``VALIWORK_DEBUG`` environment variable and set it to ``true`` to get debug output. Default ``log`` module will be used for that.
|
25
debug.go
Normal file
25
debug.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package valiwork
|
||||||
|
|
||||||
|
import (
|
||||||
|
// stdlib
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
DEBUG bool
|
||||||
|
)
|
||||||
|
|
||||||
|
// Initializes debug output.
|
||||||
|
// nolint
|
||||||
|
func init() {
|
||||||
|
debug, found := os.LookupEnv("VALIWORK_DEBUG")
|
||||||
|
if found {
|
||||||
|
debugBool, err := strconv.ParseBool(debug)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG = debugBool
|
||||||
|
}
|
||||||
|
}
|
17
errors.go
Normal file
17
errors.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package valiwork
|
||||||
|
|
||||||
|
import (
|
||||||
|
// stdlib
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrValidatorAlreadyRegistered appears when validator's name
|
||||||
|
// passed to RegisterValidator function already used for other
|
||||||
|
// validator function.
|
||||||
|
ErrValidatorAlreadyRegistered = errors.New("validator with such name already registered")
|
||||||
|
|
||||||
|
// ErrValidatorNotRegistered appears when trying to unregister
|
||||||
|
// not registered validator function.
|
||||||
|
ErrValidatorNotRegistered = errors.New("validator with such name wasn't registered")
|
||||||
|
)
|
43
example/main.go
Normal file
43
example/main.go
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
// stdlib
|
||||||
|
"errors"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
// other
|
||||||
|
"go.dev.pztrn.name/valiwork"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
stringValidatorName = "string_validate_things"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
log.Println("Starting validation example...")
|
||||||
|
log.Println("WARN: to see additional valiwork output define 'VALIWORK_DEBUG' environment variable and set it to 'true'!")
|
||||||
|
|
||||||
|
//stringToValidate := " I am pretty b@d $tring"
|
||||||
|
|
||||||
|
valiwork.RegisterValidator(stringValidatorName, stringValidator)
|
||||||
|
}
|
||||||
|
|
||||||
|
func stringValidator(thing interface{}, optional ...interface{}) []interface{} {
|
||||||
|
var errs []interface{}
|
||||||
|
|
||||||
|
stringToValidate, ok := thing.(string)
|
||||||
|
if !ok {
|
||||||
|
errs = append(errs, errors.New("passed value is not a string"))
|
||||||
|
return errs
|
||||||
|
}
|
||||||
|
|
||||||
|
// Are string begins with spaces?
|
||||||
|
if strings.HasPrefix(stringToValidate, " ") {
|
||||||
|
errs = append(errs, errors.New("string begins with space"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Does string contains any special characters?
|
||||||
|
|
||||||
|
return errs
|
||||||
|
}
|
5
go.mod
Normal file
5
go.mod
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
module go.dev.pztrn.name/valiwork
|
||||||
|
|
||||||
|
go 1.13
|
||||||
|
|
||||||
|
require github.com/stretchr/testify v1.4.0
|
12
go.sum
Normal file
12
go.sum
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||||
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
97
validations.go
Normal file
97
validations.go
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
package valiwork
|
||||||
|
|
||||||
|
import (
|
||||||
|
// stdlib
|
||||||
|
"log"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
// local
|
||||||
|
"go.dev.pztrn.name/valiwork/validators"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
registeredValidators map[string]validators.ValidatorFunc
|
||||||
|
rvMutex sync.RWMutex
|
||||||
|
)
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
func init() {
|
||||||
|
initializeValidatorsStorage()
|
||||||
|
}
|
||||||
|
|
||||||
|
func initializeValidatorsStorage() {
|
||||||
|
registeredValidators = make(map[string]validators.ValidatorFunc)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterValidator registers validation function for later calling.
|
||||||
|
func RegisterValidator(validatorName string, validator validators.ValidatorFunc) error {
|
||||||
|
if DEBUG {
|
||||||
|
log.Println("Trying to register validator: '" + validatorName + "'...")
|
||||||
|
}
|
||||||
|
|
||||||
|
//rvMutex.RLock()
|
||||||
|
_, found := registeredValidators[validatorName]
|
||||||
|
//rvMutex.RUnlock()
|
||||||
|
|
||||||
|
if found {
|
||||||
|
if DEBUG {
|
||||||
|
log.Println("Validator already registered!")
|
||||||
|
}
|
||||||
|
|
||||||
|
return ErrValidatorAlreadyRegistered
|
||||||
|
}
|
||||||
|
|
||||||
|
//rvMutex.Lock()
|
||||||
|
registeredValidators[validatorName] = validator
|
||||||
|
//rvMutex.Unlock()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnregisterValidator removes registered validator from list of known
|
||||||
|
// validators.
|
||||||
|
func UnregisterValidator(validatorName string) error {
|
||||||
|
if DEBUG {
|
||||||
|
log.Println("Trying to unregister validator '" + validatorName + "'...")
|
||||||
|
}
|
||||||
|
|
||||||
|
//rvMutex.RLock()
|
||||||
|
_, found := registeredValidators[validatorName]
|
||||||
|
//rvMutex.RUnlock()
|
||||||
|
|
||||||
|
if !found {
|
||||||
|
if DEBUG {
|
||||||
|
log.Println("Validator wasn't registered!")
|
||||||
|
}
|
||||||
|
|
||||||
|
return ErrValidatorNotRegistered
|
||||||
|
}
|
||||||
|
|
||||||
|
//rvMutex.Lock()
|
||||||
|
delete(registeredValidators, validatorName)
|
||||||
|
//rvMutex.Unlock()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate launches validation function and returns it's result to
|
||||||
|
// caller.
|
||||||
|
func Validate(validatorName string, thing interface{}, optional ...interface{}) []interface{} {
|
||||||
|
var errs []interface{}
|
||||||
|
|
||||||
|
//rvMutex.RLock()
|
||||||
|
validator, found := registeredValidators[validatorName]
|
||||||
|
//rvMutex.RUnlock()
|
||||||
|
|
||||||
|
if !found {
|
||||||
|
errs = append(errs, ErrValidatorNotRegistered)
|
||||||
|
return errs
|
||||||
|
}
|
||||||
|
|
||||||
|
errs1 := validator(thing, optional...)
|
||||||
|
if len(errs1) > 0 {
|
||||||
|
errs = append(errs, errs1...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return errs
|
||||||
|
}
|
266
validations_test.go
Normal file
266
validations_test.go
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
package valiwork
|
||||||
|
|
||||||
|
import (
|
||||||
|
// stdlib
|
||||||
|
"errors"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
// local
|
||||||
|
"go.dev.pztrn.name/valiwork/validators"
|
||||||
|
|
||||||
|
// other
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRegisterValidator(t *testing.T) {
|
||||||
|
initializeValidatorsStorage()
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
ValidatorName string
|
||||||
|
ValidatorFunc validators.ValidatorFunc
|
||||||
|
ShouldFail bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
ValidatorName: "string_test_validator",
|
||||||
|
ValidatorFunc: func(thing interface{}, optional ...interface{}) []interface{} {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
ShouldFail: false,
|
||||||
|
},
|
||||||
|
// This case is about registering same validator function again.
|
||||||
|
{
|
||||||
|
ValidatorName: "string_test_validator",
|
||||||
|
ValidatorFunc: func(thing interface{}, optional ...interface{}) []interface{} {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
ShouldFail: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
err := RegisterValidator(testCase.ValidatorName, testCase.ValidatorFunc)
|
||||||
|
if !testCase.ShouldFail {
|
||||||
|
require.Nil(t, err)
|
||||||
|
} else {
|
||||||
|
require.NotNil(t, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkRegisterValidator(b *testing.B) {
|
||||||
|
initializeValidatorsStorage()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = RegisterValidator("string_test_validator_"+strconv.Itoa(i),
|
||||||
|
func(thing interface{}, optional ...interface{}) []interface{} {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkRegisterValidatorAsync(b *testing.B) {
|
||||||
|
initializeValidatorsStorage()
|
||||||
|
|
||||||
|
var w sync.WaitGroup
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
w.Add(1)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
_ = RegisterValidator("string_test_validator_"+strconv.Itoa(i),
|
||||||
|
func(thing interface{}, optional ...interface{}) []interface{} {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
w.Done()
|
||||||
|
}()
|
||||||
|
|
||||||
|
w.Wait()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValidate(t *testing.T) {
|
||||||
|
initializeValidatorsStorage()
|
||||||
|
|
||||||
|
testString := " I am test string"
|
||||||
|
|
||||||
|
RegisterValidator("string_test1", func(thing interface{}, optional ...interface{}) []interface{} {
|
||||||
|
var errs []interface{}
|
||||||
|
|
||||||
|
stringToValidate, ok := thing.(string)
|
||||||
|
if !ok {
|
||||||
|
errs = append(errs, errors.New("not a string"))
|
||||||
|
return errs
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(stringToValidate, " ") {
|
||||||
|
errs = append(errs, errors.New("string starts with whitespace, invalid!"))
|
||||||
|
}
|
||||||
|
|
||||||
|
return errs
|
||||||
|
})
|
||||||
|
|
||||||
|
errs := Validate("string_test1", testString, nil)
|
||||||
|
require.NotNil(t, errs)
|
||||||
|
require.Len(t, errs, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkValidate(b *testing.B) {
|
||||||
|
b.StopTimer()
|
||||||
|
|
||||||
|
initializeValidatorsStorage()
|
||||||
|
|
||||||
|
testString := " I am test $tring"
|
||||||
|
|
||||||
|
RegisterValidator("string_test1", func(thing interface{}, optional ...interface{}) []interface{} {
|
||||||
|
var errs []interface{}
|
||||||
|
|
||||||
|
stringToValidate, ok := thing.(string)
|
||||||
|
if !ok {
|
||||||
|
errs = append(errs, errors.New("not a string"))
|
||||||
|
return errs
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(stringToValidate, " ") {
|
||||||
|
errs = append(errs, errors.New("string starts with whitespace, invalid!"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Contains(stringToValidate, "$") {
|
||||||
|
errs = append(errs, errors.New("string starts with whitespace, invalid!"))
|
||||||
|
}
|
||||||
|
|
||||||
|
return errs
|
||||||
|
})
|
||||||
|
|
||||||
|
b.StartTimer()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = Validate("string_test1", testString)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkValidateAsync(b *testing.B) {
|
||||||
|
b.StopTimer()
|
||||||
|
|
||||||
|
initializeValidatorsStorage()
|
||||||
|
|
||||||
|
testString := " I am test $tring"
|
||||||
|
|
||||||
|
RegisterValidator("string_test1", func(thing interface{}, optional ...interface{}) []interface{} {
|
||||||
|
var errs []interface{}
|
||||||
|
|
||||||
|
stringToValidate, ok := thing.(string)
|
||||||
|
if !ok {
|
||||||
|
errs = append(errs, errors.New("not a string"))
|
||||||
|
return errs
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(stringToValidate, " ") {
|
||||||
|
errs = append(errs, errors.New("string starts with whitespace, invalid!"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Contains(stringToValidate, "$") {
|
||||||
|
errs = append(errs, errors.New("string starts with whitespace, invalid!"))
|
||||||
|
}
|
||||||
|
|
||||||
|
return errs
|
||||||
|
})
|
||||||
|
|
||||||
|
b.StartTimer()
|
||||||
|
|
||||||
|
var w sync.WaitGroup
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
w.Add(1)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
_ = Validate("string_test1", testString)
|
||||||
|
|
||||||
|
w.Done()
|
||||||
|
}()
|
||||||
|
|
||||||
|
w.Wait()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnregisterValidator(t *testing.T) {
|
||||||
|
initializeValidatorsStorage()
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
ValidatorName string
|
||||||
|
ValidatorFunc validators.ValidatorFunc
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
ValidatorName: "string_test_validator",
|
||||||
|
ValidatorFunc: func(thing interface{}, optional ...interface{}) []interface{} {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
err := RegisterValidator(testCase.ValidatorName, testCase.ValidatorFunc)
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
err1 := UnregisterValidator(testCase.ValidatorName)
|
||||||
|
require.Nil(t, err1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnregisterValidatorNotRegisteredValidator(t *testing.T) {
|
||||||
|
initializeValidatorsStorage()
|
||||||
|
|
||||||
|
err := UnregisterValidator("this is definetely not registered thing")
|
||||||
|
require.NotNil(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkUnregisterValidator(b *testing.B) {
|
||||||
|
b.StopTimer()
|
||||||
|
|
||||||
|
initializeValidatorsStorage()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = RegisterValidator("string_test_validator_"+strconv.Itoa(i),
|
||||||
|
func(thing interface{}, optional ...interface{}) []interface{} {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
b.StartTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = UnregisterValidator("string_test_validator_" + strconv.Itoa(i))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkUnregisterValidatorAsync(b *testing.B) {
|
||||||
|
b.StopTimer()
|
||||||
|
|
||||||
|
initializeValidatorsStorage()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = RegisterValidator("string_test_validator_"+strconv.Itoa(i),
|
||||||
|
func(thing interface{}, optional ...interface{}) []interface{} {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
var w sync.WaitGroup
|
||||||
|
|
||||||
|
b.StartTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
w.Add(1)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
_ = UnregisterValidator("string_test_validator_" + strconv.Itoa(i))
|
||||||
|
w.Done()
|
||||||
|
}()
|
||||||
|
|
||||||
|
w.Wait()
|
||||||
|
}
|
||||||
|
}
|
4
validators/validator_signature.go
Normal file
4
validators/validator_signature.go
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
package validators
|
||||||
|
|
||||||
|
// ValidatorFunc represents signature for data validation function.
|
||||||
|
type ValidatorFunc func(thing interface{}, optional ...interface{}) []interface{}
|
Loading…
Reference in New Issue
Block a user