diff --git a/converter_test.go b/converter_test.go index 1f6c065..c9d67ef 100644 --- a/converter_test.go +++ b/converter_test.go @@ -5,6 +5,7 @@ import ( "fmt" "net/url" "testing" + "time" ) var ( @@ -133,3 +134,41 @@ func TestConvertersFloat64Converter(t *testing.T) { t.Fatalf("Expected %v. Got %v", 3.14159, ex) } } + +func TestConvertersTimeConverter(t *testing.T) { + f := &Form{ + Fields: []Field{ + {Name: "foo", Converter: TimeConverter}, + }, + } + res := f.Load(create_req(url.Values{ + "foo": {"1978-07-10"}, + })) + if ex, ok := res.Errors["foo"]; ok || ex != nil { + t.Fatalf("Expected %v. Got %v", nil, ex) + } + rval := res.Value.(map[string]interface{}) + tm := time.Date(1978, 7, 10, 0, 0, 0, 0, time.UTC) + if ex, ok := rval["foo"].(time.Time); !ok || ex != tm { + t.Fatalf("Expected %v. Got %v", tm, ex) + } +} + +func TestConvertersBoolConverter(t *testing.T) { + f := &Form{ + Fields: []Field{ + {Name: "foo", Converter: BoolConverter}, + }, + } + res := f.Load(create_req(url.Values{ + "foo": {"on"}, + })) + if ex, ok := res.Errors["foo"]; ok || ex != nil { + t.Fatalf("Expected %v. Got %v", nil, ex) + } + rval := res.Value.(map[string]interface{}) + b := true + if ex, ok := rval["foo"].(bool); !ok || ex != b { + t.Fatalf("Expected %v. Got %v", b, ex) + } +} diff --git a/converters.go b/converters.go index 9ac5466..e61468f 100644 --- a/converters.go +++ b/converters.go @@ -3,6 +3,11 @@ package forms import ( "errors" "strconv" + "time" +) + +const ( + time_format = "2006-01-02" ) var ( @@ -10,6 +15,8 @@ var ( IntConverter ConverterFunc = int_converter Float64Converter ConverterFunc = float64_converter Float32Converter ConverterFunc = float32_converter + TimeConverter ConverterFunc = time_converter + BoolConverter ConverterFunc = bool_converter ) func make_human_readable(numerr *strconv.NumError) (err error) { @@ -57,3 +64,23 @@ func float32_converter(in string) (out interface{}, err error) { out = float32(f) return } + +func time_converter(in string) (out interface{}, err error) { + //parse the input + t, err := time.Parse(time_format, in) + + if err != nil { + return nil, errors.New("Invalid time: YYYY-MM-DD") + } + + //set our output + out = t + return +} + +func bool_converter(in string) (out interface{}, err error) { + if in == "on" { + return true, nil + } + return false, nil +} diff --git a/validator_test.go b/validator_test.go index fe8126f..e11151e 100644 --- a/validator_test.go +++ b/validator_test.go @@ -164,3 +164,55 @@ func TestValidatorsNonemptyValidator(t *testing.T) { t.Fatalf("Expected %v. Got %v", "not nil", ex) } } + +func TestValidatorsTimeValidator(t *testing.T) { + f := &Form{ + Fields: []Field{ + {Name: "foo", Validators: []Validator{DateValidator}}, + }, + } + res := f.Load(create_req(url.Values{ + "foo": {"2010-10-26"}, + })) + if ex, ok := res.Errors["foo"]; ok || ex != nil { + t.Fatalf("Expected %v. Got %v", nil, ex) + } + + res = f.Load(create_req(url.Values{ + "foo": {""}, + })) + if ex, ok := res.Errors["foo"]; !ok || ex == nil { + t.Fatalf("Expected %v. Got %v", "not nil", ex) + } + + res = f.Load(create_req(nil)) + if ex, ok := res.Errors["foo"]; !ok || ex == nil { + t.Fatalf("Expected %v. Got %v", "not nil", ex) + } +} + +func TestValidatorsEmailValidator(t *testing.T) { + f := &Form{ + Fields: []Field{ + {Name: "foo", Validators: []Validator{EmailValidator}}, + }, + } + res := f.Load(create_req(url.Values{ + "foo": {"test@test.te"}, + })) + if ex, ok := res.Errors["foo"]; ok || ex != nil { + t.Fatalf("Expected %v. Got %v", nil, ex) + } + + res = f.Load(create_req(url.Values{ + "foo": {""}, + })) + if ex, ok := res.Errors["foo"]; !ok || ex == nil { + t.Fatalf("Expected %v. Got %v", "not nil", ex) + } + + res = f.Load(create_req(nil)) + if ex, ok := res.Errors["foo"]; !ok || ex == nil { + t.Fatalf("Expected %v. Got %v", "not nil", ex) + } +} diff --git a/validators.go b/validators.go index 3b4c917..df7430f 100644 --- a/validators.go +++ b/validators.go @@ -1,10 +1,16 @@ package forms -import "errors" +import ( + "errors" + "regexp" + "time" +) var ( //Some built in validators that do what you would expect. NonemptyValidator ValidatorFunc = nonempty_validator + DateValidator ValidatorFunc = date_validator + EmailValidator ValidatorFunc = email_validator ) func nonempty_validator(in string) (out string, err error) { @@ -14,3 +20,24 @@ func nonempty_validator(in string) (out string, err error) { } return } + +func date_validator(in string) (string, error) { + _, err := time.Parse(time_format, in) + if err != nil { + return in, errors.New("Invalid date") + } + return in, nil +} + +// vague email validator (better then nothing) +func email_validator(in string) (string, error) { + ok, err := regexp.MatchString(`^[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,4}$`, in) + + if err != nil { + return in, err + } + if !ok { + return in, errors.New("Invalid e-mail address") + } + return in, nil +}