Skip to content

Commit

Permalink
Feature: specify time formats we wish to validate
Browse files Browse the repository at this point in the history
- specify an exact list of time formats we wish to validate via
  TimeLayouts member.
- update unit tests to Compile before using instance
  • Loading branch information
Yan-Fa Li committed Aug 2, 2016
1 parent ce3f699 commit 2890f65
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 4 deletions.
18 changes: 17 additions & 1 deletion schema/time.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,28 @@ var (

// Time validates time based values
type Time struct {
TimeLayouts []string // TimeLayouts is set of time layouts we want to validate
layouts []string
}

// Compile the time formats
func (v *Time) Compile() (err error) {
if len(v.TimeLayouts) == 0 {
// default layouts to all formats
v.layouts = formats
return nil
}
// User specified list of time layouts
for _, layout := range v.TimeLayouts {
v.layouts = append(v.layouts, string(layout))
}
return nil
}

// Validate validates and normalize time based value
func (v Time) Validate(value interface{}) (interface{}, error) {
if s, ok := value.(string); ok {
for _, layout := range formats {
for _, layout := range v.layouts {
if t, err := time.Parse(layout, s); err == nil {
value = t
break
Expand Down
39 changes: 36 additions & 3 deletions schema/time_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,50 @@ import (

func TestTimeValidate(t *testing.T) {
now := time.Now().Truncate(time.Minute).UTC()
timeT := Time{}
err := timeT.Compile()
assert.NoError(t, err)
for _, f := range formats {
v, err := Time{}.Validate(now.Format(f))
v, err := timeT.Validate(now.Format(f))
assert.NoError(t, err)
if assert.IsType(t, v, now) {
assert.True(t, now.Equal(v.(time.Time)), f)
}
}
v, err := Time{}.Validate(now)
v, err := timeT.Validate(now)
assert.NoError(t, err)
assert.Equal(t, now, v)
v, err = Time{}.Validate("invalid date")
v, err = timeT.Validate("invalid date")
assert.EqualError(t, err, "not a time")
assert.Nil(t, v)
}

func TestTimeSpecificLayoutList(t *testing.T) {
now := time.Now().Truncate(time.Minute).UTC()
// list to test for
testList := []string{time.RFC1123Z, time.RFC822Z, time.RFC3339}
// test for same list in reverse
timeT := Time{TimeLayouts: []string{time.RFC3339, time.RFC822Z, time.RFC1123Z}}
err := timeT.Compile()
assert.NoError(t, err)
// expect no errors
for _, f := range testList {
_, err := timeT.Validate(now.Format(f))
assert.NoError(t, err)
}
}

func TestTimeForTimeLayoutFailure(t *testing.T) {
now := time.Now().Truncate(time.Minute).UTC()
// test for ANSIC time
testList := []string{time.ANSIC}
// configure for RFC3339 time
timeT := Time{TimeLayouts: []string{time.RFC3339}}
err := timeT.Compile()
assert.NoError(t, err)
// expect an error
for _, f := range testList {
_, err := timeT.Validate(now.Format(f))
assert.EqualError(t, err, "not a time")
}
}

0 comments on commit 2890f65

Please sign in to comment.