Initial commit, valiwork as framework is ready to use.
This commit is contained in:
		
							
								
								
									
										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{} | ||||
		Reference in New Issue
	
	Block a user