Skip to content

Commit

Permalink
Merge pull request #11 from Rhyanz46/extension
Browse files Browse the repository at this point in the history
Add Extension Feature 🔥
  • Loading branch information
Rhyanz46 authored Feb 11, 2024
2 parents 0ffb153 + 2026058 commit 14f194d
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 12 deletions.
8 changes: 4 additions & 4 deletions map_validator/extra_operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"errors"
)

func (state *extraOperation) Bind(i interface{}) error {
func (state *ExtraOperationData) Bind(i interface{}) error {
var data map[string]interface{}
if state == nil || state.data == nil {
return errors.New("no data to Bind because last progress is error")
Expand Down Expand Up @@ -64,20 +64,20 @@ func (state *extraOperation) Bind(i interface{}) error {
return nil
}

func (state *extraOperation) GetFilledField() []string {
func (state *ExtraOperationData) GetFilledField() []string {
if len(state.filledFields) > 0 {
return state.filledFields
}
return []string{}
}

func (state *extraOperation) GetNullField() []string {
func (state *ExtraOperationData) GetNullField() []string {
if len(state.nullFields) > 0 {
return state.nullFields
}
return []string{}
}

func (state *extraOperation) GetData() map[string]interface{} {
func (state *ExtraOperationData) GetData() map[string]interface{} {
return *state.data
}
4 changes: 2 additions & 2 deletions map_validator/functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@ func buildMessage(msg string, meta MessageMeta) error {
}
}
if strings.Contains(msg, expectedTypeVar) {
v := *meta.ExpectedType
if meta.ExpectedType != nil {
v := *meta.ExpectedType
msg = strings.ReplaceAll(msg, expectedTypeVar, v.String())
}
}
if strings.Contains(msg, actualTypeVar) {
v := *meta.ActualType
if meta.ActualType != nil {
v := *meta.ActualType
msg = strings.ReplaceAll(msg, actualTypeVar, v.String())
}
}
Expand Down
74 changes: 71 additions & 3 deletions map_validator/implements.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,20 @@ func (state *ruleState) SetRules(validations map[string]Rules) *dataState {
if len(validations) == 0 {
panic("you need to set roles")
}

var tempExt []ExtensionType
state.rules = validations

for _, ex := range state.extension {
ex.SetRoles(&state.rules)
tempExt = append(tempExt, ex)
}
if len(tempExt) > 0 {
state.extension = tempExt
}
return &dataState{
rules: &state.rules,
extension: state.extension,
strictAllowedValue: state.strictAllowedValue,
}
}
Expand All @@ -28,6 +39,11 @@ func (state *ruleState) StrictKeys() *ruleState {
return state
}

func (state *ruleState) AddExtension(extension ExtensionType) *ruleState {
state.extension = append(state.extension, extension)
return state
}

func (state *dataState) checkStrictKeys(data map[string]interface{}) error {
var allowedKeys []string
keys := getAllKeys(data)
Expand All @@ -47,9 +63,22 @@ func (state *dataState) Load(data map[string]interface{}) (*finalOperation, erro
return nil, err
}
}
for _, ex := range state.extension {
err := ex.BeforeLoad(&data)
if err != nil {
return nil, err
}
}
for _, ex := range state.extension {
err := ex.AfterLoad(&data)
if err != nil {
return nil, err
}
}
return &finalOperation{
rules: state.rules,
loadedFrom: fromMapString,
extension: state.extension,
data: data,
}, nil
}
Expand All @@ -61,6 +90,12 @@ func (state *dataState) LoadJsonHttp(r *http.Request) (*finalOperation, error) {
if r == nil {
return nil, errors.New("no data to Load")
}
for _, ex := range state.extension {
err := ex.BeforeLoad(r)
if err != nil {
return nil, err
}
}
var mapData map[string]interface{}
err := json.NewDecoder(r.Body).Decode(&mapData)
if err != nil {
Expand All @@ -74,9 +109,16 @@ func (state *dataState) LoadJsonHttp(r *http.Request) (*finalOperation, error) {
return nil, err
}
}
for _, ex := range state.extension {
err := ex.AfterLoad(&mapData)
if err != nil {
return nil, err
}
}
return &finalOperation{
rules: state.rules,
loadedFrom: fromHttpJson,
extension: state.extension,
data: mapData,
}, nil
}
Expand All @@ -88,6 +130,12 @@ func (state *dataState) LoadFormHttp(r *http.Request) (*finalOperation, error) {
if r == nil {
return nil, errors.New("no data to Load")
}
for _, ex := range state.extension {
err := ex.BeforeLoad(r)
if err != nil {
return nil, err
}
}
mapData := map[string]interface{}{}
allowType := []reflect.Kind{reflect.String, reflect.Int, reflect.Bool}
for key, rule := range *state.rules {
Expand Down Expand Up @@ -125,19 +173,32 @@ func (state *dataState) LoadFormHttp(r *http.Request) (*finalOperation, error) {
return nil, err
}
}
for _, ex := range state.extension {
err := ex.AfterLoad(&mapData)
if err != nil {
return nil, err
}
}
return &finalOperation{
rules: state.rules,
loadedFrom: fromHttpMultipartForm,
extension: state.extension,
data: mapData,
}, nil
}

func (state *finalOperation) RunValidate() (*extraOperation, error) {
func (state *finalOperation) RunValidate() (*ExtraOperationData, error) {
if state == nil || state.data == nil {
return nil, errors.New("no data to Validate because last progress is error")
}
var filledFields []string
var nullFields []string
for _, ex := range state.extension {
err := ex.BeforeValidation(&state.data)
if err != nil {
return nil, err
}
}
for key, validationData := range *state.rules {
data, err := validate(key, state.data, validationData, state.loadedFrom)
if err != nil {
Expand All @@ -149,11 +210,18 @@ func (state *finalOperation) RunValidate() (*extraOperation, error) {
nullFields = append(nullFields, key)
}
}
return &extraOperation{
extraData := &ExtraOperationData{
rules: state.rules,
loadedFrom: &state.loadedFrom,
data: &state.data,
filledFields: filledFields,
nullFields: nullFields,
}, nil
}
for _, ex := range state.extension {
err := ex.SetExtraData(extraData).AfterValidation(&state.data)
if err != nil {
return nil, err
}
}
return extraData, nil
}
14 changes: 12 additions & 2 deletions map_validator/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type validatorType interface {
type setRoleOperationType interface {
SetRules(validations map[string]Rules) *dataState
StrictKeys() *ruleState
AddExtension(extension ExtensionType) *ruleState
}

type loadOperationType interface {
Expand All @@ -18,12 +19,21 @@ type loadOperationType interface {
}

type finalOperationType interface {
RunValidate() (*extraOperation, error)
RunValidate() (*ExtraOperationData, error)
}

type extraOperationType interface {
type ExtraOperationType interface {
Bind(i interface{}) error
GetFilledField() []string
GetNullField() []string
GetData() map[string]interface{}
}

type ExtensionType interface {
SetRoles(rules *map[string]Rules)
BeforeLoad(data interface{}) error
AfterLoad(data *map[string]interface{}) error
BeforeValidation(data *map[string]interface{}) error
AfterValidation(data *map[string]interface{}) error
SetExtraData(data *ExtraOperationData) ExtensionType
}
5 changes: 4 additions & 1 deletion map_validator/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,24 @@ type FileRequest struct {

type ruleState struct {
rules map[string]Rules
extension []ExtensionType
strictAllowedValue bool
}

type dataState struct {
rules *map[string]Rules
extension []ExtensionType
strictAllowedValue bool
}

type finalOperation struct {
rules *map[string]Rules
loadedFrom loadFromType
extension []ExtensionType
data map[string]interface{}
}

type extraOperation struct {
type ExtraOperationData struct {
rules *map[string]Rules
loadedFrom *loadFromType
data *map[string]interface{}
Expand Down
109 changes: 109 additions & 0 deletions test/extension_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package test

import (
"github.com/Rhyanz46/go-map-validator/map_validator"
"testing"
)

type ExampleExtension struct {
rules *map[string]map_validator.Rules
data interface{}
resetAfterValidation bool
extraData *map_validator.ExtraOperationData
}

func (e *ExampleExtension) SetRoles(rules *map[string]map_validator.Rules) {
e.rules = rules
}

func (e *ExampleExtension) BeforeLoad(data interface{}) error {
//TODO implement me
//panic("implement me")
return nil
}

func (e *ExampleExtension) AfterLoad(data *map[string]interface{}) error {
//TODO implement me
//panic("implement me")
return nil
}

func (e *ExampleExtension) BeforeValidation(data *map[string]interface{}) error {
//TODO implement me
//panic("implement me")
return nil
}

func (e *ExampleExtension) AfterValidation(data *map[string]interface{}) error {
//TODO implement me
//panic("implement me")
if e.resetAfterValidation {
empty := map[string]interface{}{}
*data = empty
}
return nil
}

func (e *ExampleExtension) SetExtraData(data *map_validator.ExtraOperationData) map_validator.ExtensionType {
e.extraData = data
return e
}

func (e *ExampleExtension) ResetAfterValidation() *ExampleExtension {
e.resetAfterValidation = true
return e
}

func ManipulatorExt() *ExampleExtension {
return &ExampleExtension{}
}

func TestExtension(t *testing.T) {
payload := map[string]interface{}{"hp": "+62567888", "email": "[email protected]"}
validRole := map[string]map_validator.Rules{
"hp": {RegexString: `^\+(?:\d{2}[- ]?\d{6}|\d{11})$`},
"email": {RegexString: `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`},
}
swaggerExt := ManipulatorExt().ResetAfterValidation()

check, err := map_validator.
NewValidateBuilder().
AddExtension(swaggerExt).
SetRules(validRole).
Load(payload)
if err != nil {
t.Errorf("Expected not have error, but got error : %s", err)
}
res, err := check.RunValidate()
if err != nil {
t.Errorf("Expected not have error, but got error : %s", err)
}
if len(res.GetData()) > 0 {
t.Errorf("Expected no data, but we got : %s", res.GetData())
}
}

func TestInvalidExtension(t *testing.T) {
payload := map[string]interface{}{"hp": "+62567888", "email": "[email protected]"}
validRole := map[string]map_validator.Rules{
"hp": {RegexString: `^\+(?:\d{2}[- ]?\d{6}|\d{11})$`},
"email": {RegexString: `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`},
}
swaggerExt := ManipulatorExt()

check, err := map_validator.
NewValidateBuilder().
AddExtension(swaggerExt).
SetRules(validRole).
Load(payload)
if err != nil {
t.Errorf("Expected not have error, but got error : %s", err)
}
res, err := check.RunValidate()
if err != nil {
t.Errorf("Expected not have error, but got error : %s", err)
}
if payload["hp"] != res.GetData()["hp"] {
t.Errorf("Expected %s data, but we got : %s", payload["hp"], res.GetData()["hp"])
}
}

0 comments on commit 14f194d

Please sign in to comment.