forked from go-ozzo/ozzo-validation
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes go-ozzo#11: Added date validation rule
- Loading branch information
Showing
5 changed files
with
160 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
// Copyright 2016 Qiang Xue. All rights reserved. | ||
// Use of this source code is governed by a MIT-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package validation | ||
|
||
import ( | ||
"errors" | ||
"time" | ||
) | ||
|
||
type dateRule struct { | ||
layout string | ||
min, max time.Time | ||
message string | ||
rangeMessage string | ||
} | ||
|
||
// Date returns a validation rule that checks if a string value is in a format that can be parsed into a date. | ||
// The format of the date should be specified as the layout parameter which accepts the same value as that for time.Parse. | ||
// For example, | ||
// validation.Date(time.ANSIC) | ||
// validation.Date("02 Jan 06 15:04 MST") | ||
// validation.Date("2006-01-02") | ||
// | ||
// By calling Min() and/or Max(), you can let the Date rule to check if a parsed date value is within | ||
// the specified date range. | ||
// | ||
// An empty value is considered valid. Use the Required rule to make sure a value is not empty. | ||
func Date(layout string) *dateRule { | ||
return &dateRule{ | ||
layout: layout, | ||
message: "must be a valid date", | ||
rangeMessage: "the data is out of range", | ||
} | ||
} | ||
|
||
// Error sets the error message that is used when the value being validated is not a valid date. | ||
func (r *dateRule) Error(message string) *dateRule { | ||
r.message = message | ||
return r | ||
} | ||
|
||
// RangeError sets the error message that is used when the value being validated is out of the specified Min/Max date range. | ||
func (r *dateRule) RangeError(message string) *dateRule { | ||
r.rangeMessage = message | ||
return r | ||
} | ||
|
||
// Min sets the minimum date range. A zero value means skipping the minimum range validation. | ||
func (r *dateRule) Min(min time.Time) *dateRule { | ||
r.min = min | ||
return r | ||
} | ||
|
||
// Max sets the maximum date range. A zero value means skipping the maximum range validation. | ||
func (r *dateRule) Max(max time.Time) *dateRule { | ||
r.max = max | ||
return r | ||
} | ||
|
||
// Validate checks if the given value is a valid date. | ||
func (r *dateRule) Validate(value interface{}) error { | ||
value, isNil := Indirect(value) | ||
if isNil || IsEmpty(value) { | ||
return nil | ||
} | ||
|
||
str, err := EnsureString(value) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
date, err := time.Parse(r.layout, str) | ||
if err != nil { | ||
return errors.New(r.message) | ||
} | ||
|
||
if !r.min.IsZero() && r.min.After(date) || !r.max.IsZero() && date.After(r.max) { | ||
return errors.New(r.rangeMessage) | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// Copyright 2016 Qiang Xue. All rights reserved. | ||
// Use of this source code is governed by a MIT-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package validation | ||
|
||
import ( | ||
"testing" | ||
"time" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestDate(t *testing.T) { | ||
tests := []struct { | ||
tag string | ||
layout string | ||
value interface{} | ||
err string | ||
}{ | ||
{"t1", time.ANSIC, "", ""}, | ||
{"t2", time.ANSIC, "Wed Feb 4 21:00:57 2009", ""}, | ||
{"t3", time.ANSIC, "Wed Feb 29 21:00:57 2009", "must be a valid date"}, | ||
{"t4", "2006-01-02", "2009-11-12", ""}, | ||
{"t5", "2006-01-02", "2009-11-12 21:00:57", "must be a valid date"}, | ||
{"t6", "2006-01-02", "2009-1-12", "must be a valid date"}, | ||
{"t7", "2006-01-02", "2009-01-12", ""}, | ||
{"t8", "2006-01-02", "2009-01-32", "must be a valid date"}, | ||
{"t9", "2006-01-02", 1, "must be either a string or byte slice"}, | ||
} | ||
|
||
for _, test := range tests { | ||
r := Date(test.layout) | ||
err := r.Validate(test.value) | ||
assertError(t, test.err, err, test.tag) | ||
} | ||
} | ||
|
||
func TestDateRule_Error(t *testing.T) { | ||
r := Date(time.ANSIC) | ||
assert.Equal(t, "must be a valid date", r.message) | ||
assert.Equal(t, "the data is out of range", r.rangeMessage) | ||
r.Error("123") | ||
r.RangeError("456") | ||
assert.Equal(t, "123", r.message) | ||
assert.Equal(t, "456", r.rangeMessage) | ||
} | ||
|
||
func TestDateRule_MinMax(t *testing.T) { | ||
r := Date(time.ANSIC) | ||
assert.True(t, r.min.IsZero()) | ||
assert.True(t, r.max.IsZero()) | ||
r.Min(time.Now()) | ||
assert.False(t, r.min.IsZero()) | ||
assert.True(t, r.max.IsZero()) | ||
r.Max(time.Now()) | ||
assert.False(t, r.max.IsZero()) | ||
|
||
r2 := Date("2006-01-02").Min(time.Date(2000, 12, 1, 0, 0, 0, 0, time.UTC)).Max(time.Date(2020, 2, 1, 0, 0, 0, 0, time.UTC)) | ||
assert.Nil(t, r2.Validate("2010-01-02")) | ||
err := r2.Validate("1999-01-02") | ||
if assert.NotNil(t, err) { | ||
assert.Equal(t, "the data is out of range", err.Error()) | ||
} | ||
err2 := r2.Validate("2021-01-02") | ||
if assert.NotNil(t, err) { | ||
assert.Equal(t, "the data is out of range", err2.Error()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,6 @@ package validation | |
|
||
import ( | ||
"testing" | ||
|
||
"database/sql" | ||
|
||
"github.com/stretchr/testify/assert" | ||
|