113 lines
2.7 KiB
Go
113 lines
2.7 KiB
Go
|
package random
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"reflect"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/mitchellh/mapstructure"
|
||
|
)
|
||
|
|
||
|
type testCharsetRule struct {
|
||
|
String string `mapstructure:"string" json:"string"`
|
||
|
Integer int `mapstructure:"int" json:"int"`
|
||
|
|
||
|
// Default to passing
|
||
|
fail bool
|
||
|
}
|
||
|
|
||
|
func newTestRule(data map[string]interface{}) (rule Rule, err error) {
|
||
|
tr := &testCharsetRule{}
|
||
|
err = mapstructure.Decode(data, tr)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("unable to decode test rule")
|
||
|
}
|
||
|
return *tr, nil
|
||
|
}
|
||
|
|
||
|
func (tr testCharsetRule) Pass([]rune) bool { return !tr.fail }
|
||
|
func (tr testCharsetRule) Type() string { return "testrule" }
|
||
|
func (tr testCharsetRule) Chars() []rune { return []rune(tr.String) }
|
||
|
|
||
|
func TestParseRule(t *testing.T) {
|
||
|
type testCase struct {
|
||
|
rules map[string]ruleConstructor
|
||
|
|
||
|
ruleType string
|
||
|
ruleData map[string]interface{}
|
||
|
|
||
|
expectedRule Rule
|
||
|
expectErr bool
|
||
|
}
|
||
|
|
||
|
tests := map[string]testCase{
|
||
|
"missing rule": {
|
||
|
rules: map[string]ruleConstructor{},
|
||
|
ruleType: "testrule",
|
||
|
ruleData: map[string]interface{}{
|
||
|
"string": "teststring",
|
||
|
"int": 123,
|
||
|
},
|
||
|
expectedRule: nil,
|
||
|
expectErr: true,
|
||
|
},
|
||
|
"nil data": {
|
||
|
rules: map[string]ruleConstructor{
|
||
|
"testrule": newTestRule,
|
||
|
},
|
||
|
ruleType: "testrule",
|
||
|
ruleData: nil,
|
||
|
expectedRule: testCharsetRule{},
|
||
|
expectErr: false,
|
||
|
},
|
||
|
"good rule": {
|
||
|
rules: map[string]ruleConstructor{
|
||
|
"testrule": newTestRule,
|
||
|
},
|
||
|
ruleType: "testrule",
|
||
|
ruleData: map[string]interface{}{
|
||
|
"string": "teststring",
|
||
|
"int": 123,
|
||
|
},
|
||
|
expectedRule: testCharsetRule{
|
||
|
String: "teststring",
|
||
|
Integer: 123,
|
||
|
},
|
||
|
expectErr: false,
|
||
|
},
|
||
|
}
|
||
|
|
||
|
for name, test := range tests {
|
||
|
t.Run(name, func(t *testing.T) {
|
||
|
reg := Registry{
|
||
|
Rules: test.rules,
|
||
|
}
|
||
|
|
||
|
actualRule, err := reg.parseRule(test.ruleType, test.ruleData)
|
||
|
if test.expectErr && err == nil {
|
||
|
t.Fatalf("err expected, got nil")
|
||
|
}
|
||
|
if !test.expectErr && err != nil {
|
||
|
t.Fatalf("no error expected, got: %s", err)
|
||
|
}
|
||
|
|
||
|
if !reflect.DeepEqual(actualRule, test.expectedRule) {
|
||
|
t.Fatalf("Actual: %#v\nExpected:%#v", actualRule, test.expectedRule)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Ensure the mappings in the defaultRuleNameMapping are consistent between the keys
|
||
|
// in the map and the Type() calls on the Rule values
|
||
|
func TestDefaultRuleNameMapping(t *testing.T) {
|
||
|
for expectedType, constructor := range defaultRuleNameMapping {
|
||
|
// In this case, we don't care about the error since we're checking the types, not the contents
|
||
|
instance, _ := constructor(map[string]interface{}{})
|
||
|
actualType := instance.Type()
|
||
|
if actualType != expectedType {
|
||
|
t.Fatalf("Default registry mismatched types: Actual: %s Expected: %s", actualType, expectedType)
|
||
|
}
|
||
|
}
|
||
|
}
|