Merge pull request #491 from fuxiaohei/develop
add comments for testing, utils and validation packages
Showing
9 changed files
with
64 additions
and
7 deletions
| ... | @@ -8,6 +8,7 @@ import ( | ... | @@ -8,6 +8,7 @@ import ( |
| 8 | var port = "" | 8 | var port = "" |
| 9 | var baseUrl = "http://localhost:" | 9 | var baseUrl = "http://localhost:" |
| 10 | 10 | ||
| 11 | // beego test request client | ||
| 11 | type TestHttpRequest struct { | 12 | type TestHttpRequest struct { |
| 12 | httplib.BeegoHttpRequest | 13 | httplib.BeegoHttpRequest |
| 13 | } | 14 | } |
| ... | @@ -24,22 +25,27 @@ func getPort() string { | ... | @@ -24,22 +25,27 @@ func getPort() string { |
| 24 | return port | 25 | return port |
| 25 | } | 26 | } |
| 26 | 27 | ||
| 28 | // returns test client in GET method | ||
| 27 | func Get(path string) *TestHttpRequest { | 29 | func Get(path string) *TestHttpRequest { |
| 28 | return &TestHttpRequest{*httplib.Get(baseUrl + getPort() + path)} | 30 | return &TestHttpRequest{*httplib.Get(baseUrl + getPort() + path)} |
| 29 | } | 31 | } |
| 30 | 32 | ||
| 33 | // returns test client in POST method | ||
| 31 | func Post(path string) *TestHttpRequest { | 34 | func Post(path string) *TestHttpRequest { |
| 32 | return &TestHttpRequest{*httplib.Post(baseUrl + getPort() + path)} | 35 | return &TestHttpRequest{*httplib.Post(baseUrl + getPort() + path)} |
| 33 | } | 36 | } |
| 34 | 37 | ||
| 38 | // returns test client in PUT method | ||
| 35 | func Put(path string) *TestHttpRequest { | 39 | func Put(path string) *TestHttpRequest { |
| 36 | return &TestHttpRequest{*httplib.Put(baseUrl + getPort() + path)} | 40 | return &TestHttpRequest{*httplib.Put(baseUrl + getPort() + path)} |
| 37 | } | 41 | } |
| 38 | 42 | ||
| 43 | // returns test client in DELETE method | ||
| 39 | func Delete(path string) *TestHttpRequest { | 44 | func Delete(path string) *TestHttpRequest { |
| 40 | return &TestHttpRequest{*httplib.Delete(baseUrl + getPort() + path)} | 45 | return &TestHttpRequest{*httplib.Delete(baseUrl + getPort() + path)} |
| 41 | } | 46 | } |
| 42 | 47 | ||
| 48 | // returns test client in HEAD method | ||
| 43 | func Head(path string) *TestHttpRequest { | 49 | func Head(path string) *TestHttpRequest { |
| 44 | return &TestHttpRequest{*httplib.Head(baseUrl + getPort() + path)} | 50 | return &TestHttpRequest{*httplib.Head(baseUrl + getPort() + path)} |
| 45 | } | 51 | } | ... | ... |
| ... | @@ -5,6 +5,7 @@ import ( | ... | @@ -5,6 +5,7 @@ import ( |
| 5 | "runtime" | 5 | "runtime" |
| 6 | ) | 6 | ) |
| 7 | 7 | ||
| 8 | // get function name | ||
| 8 | func GetFuncName(i interface{}) string { | 9 | func GetFuncName(i interface{}) string { |
| 9 | return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name() | 10 | return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name() |
| 10 | } | 11 | } | ... | ... |
| ... | @@ -70,6 +70,7 @@ const ( | ... | @@ -70,6 +70,7 @@ const ( |
| 70 | urlPrefix = "/captcha/" | 70 | urlPrefix = "/captcha/" |
| 71 | ) | 71 | ) |
| 72 | 72 | ||
| 73 | // Captcha struct | ||
| 73 | type Captcha struct { | 74 | type Captcha struct { |
| 74 | // beego cache store | 75 | // beego cache store |
| 75 | store cache.Cache | 76 | store cache.Cache |
| ... | @@ -96,10 +97,12 @@ type Captcha struct { | ... | @@ -96,10 +97,12 @@ type Captcha struct { |
| 96 | CachePrefix string | 97 | CachePrefix string |
| 97 | } | 98 | } |
| 98 | 99 | ||
| 100 | // generate key string | ||
| 99 | func (c *Captcha) key(id string) string { | 101 | func (c *Captcha) key(id string) string { |
| 100 | return c.CachePrefix + id | 102 | return c.CachePrefix + id |
| 101 | } | 103 | } |
| 102 | 104 | ||
| 105 | // generate rand chars with default chars | ||
| 103 | func (c *Captcha) genRandChars() []byte { | 106 | func (c *Captcha) genRandChars() []byte { |
| 104 | return utils.RandomCreateBytes(c.ChallengeNums, defaultChars...) | 107 | return utils.RandomCreateBytes(c.ChallengeNums, defaultChars...) |
| 105 | } | 108 | } | ... | ... |
| ... | @@ -9,11 +9,13 @@ import ( | ... | @@ -9,11 +9,13 @@ import ( |
| 9 | "regexp" | 9 | "regexp" |
| 10 | ) | 10 | ) |
| 11 | 11 | ||
| 12 | // SelfPath gets compiled executable file absolute path | ||
| 12 | func SelfPath() string { | 13 | func SelfPath() string { |
| 13 | path, _ := filepath.Abs(os.Args[0]) | 14 | path, _ := filepath.Abs(os.Args[0]) |
| 14 | return path | 15 | return path |
| 15 | } | 16 | } |
| 16 | 17 | ||
| 18 | // SelfDir gets compiled executable file directory | ||
| 17 | func SelfDir() string { | 19 | func SelfDir() string { |
| 18 | return filepath.Dir(SelfPath()) | 20 | return filepath.Dir(SelfPath()) |
| 19 | } | 21 | } |
| ... | @@ -28,8 +30,8 @@ func FileExists(name string) bool { | ... | @@ -28,8 +30,8 @@ func FileExists(name string) bool { |
| 28 | return true | 30 | return true |
| 29 | } | 31 | } |
| 30 | 32 | ||
| 31 | // search a file in paths. | 33 | // Search a file in paths. |
| 32 | // this is offen used in search config file in /etc ~/ | 34 | // this is often used in search config file in /etc ~/ |
| 33 | func SearchFile(filename string, paths ...string) (fullpath string, err error) { | 35 | func SearchFile(filename string, paths ...string) (fullpath string, err error) { |
| 34 | for _, path := range paths { | 36 | for _, path := range paths { |
| 35 | if fullpath = filepath.Join(path, filename); FileExists(fullpath) { | 37 | if fullpath = filepath.Join(path, filename); FileExists(fullpath) { | ... | ... |
| ... | @@ -51,6 +51,8 @@ type Attachment struct { | ... | @@ -51,6 +51,8 @@ type Attachment struct { |
| 51 | Content []byte | 51 | Content []byte |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | // NewEMail create new Email struct with config json. | ||
| 55 | // config json is followed from Email struct fields. | ||
| 54 | func NewEMail(config string) *Email { | 56 | func NewEMail(config string) *Email { |
| 55 | e := new(Email) | 57 | e := new(Email) |
| 56 | e.Headers = textproto.MIMEHeader{} | 58 | e.Headers = textproto.MIMEHeader{} |
| ... | @@ -64,7 +66,7 @@ func NewEMail(config string) *Email { | ... | @@ -64,7 +66,7 @@ func NewEMail(config string) *Email { |
| 64 | return e | 66 | return e |
| 65 | } | 67 | } |
| 66 | 68 | ||
| 67 | // make all send information to byte | 69 | // Make all send information to byte |
| 68 | func (e *Email) Bytes() ([]byte, error) { | 70 | func (e *Email) Bytes() ([]byte, error) { |
| 69 | buff := &bytes.Buffer{} | 71 | buff := &bytes.Buffer{} |
| 70 | w := multipart.NewWriter(buff) | 72 | w := multipart.NewWriter(buff) |
| ... | @@ -140,7 +142,7 @@ func (e *Email) Bytes() ([]byte, error) { | ... | @@ -140,7 +142,7 @@ func (e *Email) Bytes() ([]byte, error) { |
| 140 | return buff.Bytes(), nil | 142 | return buff.Bytes(), nil |
| 141 | } | 143 | } |
| 142 | 144 | ||
| 143 | // Attach file to the send mail | 145 | // Add attach file to the send mail |
| 144 | func (e *Email) AttachFile(filename string) (a *Attachment, err error) { | 146 | func (e *Email) AttachFile(filename string) (a *Attachment, err error) { |
| 145 | f, err := os.Open(filename) | 147 | f, err := os.Open(filename) |
| 146 | if err != nil { | 148 | if err != nil { |
| ... | @@ -152,7 +154,7 @@ func (e *Email) AttachFile(filename string) (a *Attachment, err error) { | ... | @@ -152,7 +154,7 @@ func (e *Email) AttachFile(filename string) (a *Attachment, err error) { |
| 152 | } | 154 | } |
| 153 | 155 | ||
| 154 | // Attach is used to attach content from an io.Reader to the email. | 156 | // Attach is used to attach content from an io.Reader to the email. |
| 155 | // Required parameters include an io.Reader, the desired filename for the attachment, and the Content-Type | 157 | // Parameters include an io.Reader, the desired filename for the attachment, and the Content-Type. |
| 156 | func (e *Email) Attach(r io.Reader, filename string, c string) (a *Attachment, err error) { | 158 | func (e *Email) Attach(r io.Reader, filename string, c string) (a *Attachment, err error) { |
| 157 | var buffer bytes.Buffer | 159 | var buffer bytes.Buffer |
| 158 | if _, err = io.Copy(&buffer, r); err != nil { | 160 | if _, err = io.Copy(&buffer, r); err != nil { |
| ... | @@ -275,7 +277,7 @@ func headerToBytes(w io.Writer, t textproto.MIMEHeader) error { | ... | @@ -275,7 +277,7 @@ func headerToBytes(w io.Writer, t textproto.MIMEHeader) error { |
| 275 | return nil | 277 | return nil |
| 276 | } | 278 | } |
| 277 | 279 | ||
| 278 | // base64Wrap encodeds the attachment content, and wraps it according to RFC 2045 standards (every 76 chars) | 280 | // base64Wrap encodes the attachment content, and wraps it according to RFC 2045 standards (every 76 chars) |
| 279 | // The output is then written to the specified io.Writer | 281 | // The output is then written to the specified io.Writer |
| 280 | func base64Wrap(w io.Writer, b []byte) { | 282 | func base64Wrap(w io.Writer, b []byte) { |
| 281 | // 57 raw bytes per 76-byte base64 line. | 283 | // 57 raw bytes per 76-byte base64 line. | ... | ... |
| ... | @@ -9,6 +9,7 @@ type BeeMap struct { | ... | @@ -9,6 +9,7 @@ type BeeMap struct { |
| 9 | bm map[interface{}]interface{} | 9 | bm map[interface{}]interface{} |
| 10 | } | 10 | } |
| 11 | 11 | ||
| 12 | // NewBeeMap return new safemap | ||
| 12 | func NewBeeMap() *BeeMap { | 13 | func NewBeeMap() *BeeMap { |
| 13 | return &BeeMap{ | 14 | return &BeeMap{ |
| 14 | lock: new(sync.RWMutex), | 15 | lock: new(sync.RWMutex), |
| ... | @@ -16,7 +17,7 @@ func NewBeeMap() *BeeMap { | ... | @@ -16,7 +17,7 @@ func NewBeeMap() *BeeMap { |
| 16 | } | 17 | } |
| 17 | } | 18 | } |
| 18 | 19 | ||
| 19 | //Get from maps return the k's value | 20 | // Get from maps return the k's value |
| 20 | func (m *BeeMap) Get(k interface{}) interface{} { | 21 | func (m *BeeMap) Get(k interface{}) interface{} { |
| 21 | m.lock.RLock() | 22 | m.lock.RLock() |
| 22 | defer m.lock.RUnlock() | 23 | defer m.lock.RUnlock() |
| ... | @@ -51,12 +52,14 @@ func (m *BeeMap) Check(k interface{}) bool { | ... | @@ -51,12 +52,14 @@ func (m *BeeMap) Check(k interface{}) bool { |
| 51 | return true | 52 | return true |
| 52 | } | 53 | } |
| 53 | 54 | ||
| 55 | // Delete the given key and value. | ||
| 54 | func (m *BeeMap) Delete(k interface{}) { | 56 | func (m *BeeMap) Delete(k interface{}) { |
| 55 | m.lock.Lock() | 57 | m.lock.Lock() |
| 56 | defer m.lock.Unlock() | 58 | defer m.lock.Unlock() |
| 57 | delete(m.bm, k) | 59 | delete(m.bm, k) |
| 58 | } | 60 | } |
| 59 | 61 | ||
| 62 | // Items returns all items in safemap. | ||
| 60 | func (m *BeeMap) Items() map[interface{}]interface{} { | 63 | func (m *BeeMap) Items() map[interface{}]interface{} { |
| 61 | m.lock.RLock() | 64 | m.lock.RLock() |
| 62 | defer m.lock.RUnlock() | 65 | defer m.lock.RUnlock() | ... | ... |
| ... | @@ -8,6 +8,7 @@ import ( | ... | @@ -8,6 +8,7 @@ import ( |
| 8 | type reducetype func(interface{}) interface{} | 8 | type reducetype func(interface{}) interface{} |
| 9 | type filtertype func(interface{}) bool | 9 | type filtertype func(interface{}) bool |
| 10 | 10 | ||
| 11 | // InSlice checks given string in string slice or not. | ||
| 11 | func InSlice(v string, sl []string) bool { | 12 | func InSlice(v string, sl []string) bool { |
| 12 | for _, vv := range sl { | 13 | for _, vv := range sl { |
| 13 | if vv == v { | 14 | if vv == v { |
| ... | @@ -17,6 +18,7 @@ func InSlice(v string, sl []string) bool { | ... | @@ -17,6 +18,7 @@ func InSlice(v string, sl []string) bool { |
| 17 | return false | 18 | return false |
| 18 | } | 19 | } |
| 19 | 20 | ||
| 21 | // InSliceIface checks given interface in interface slice. | ||
| 20 | func InSliceIface(v interface{}, sl []interface{}) bool { | 22 | func InSliceIface(v interface{}, sl []interface{}) bool { |
| 21 | for _, vv := range sl { | 23 | for _, vv := range sl { |
| 22 | if vv == v { | 24 | if vv == v { |
| ... | @@ -26,6 +28,7 @@ func InSliceIface(v interface{}, sl []interface{}) bool { | ... | @@ -26,6 +28,7 @@ func InSliceIface(v interface{}, sl []interface{}) bool { |
| 26 | return false | 28 | return false |
| 27 | } | 29 | } |
| 28 | 30 | ||
| 31 | // SliceRandList generate an int slice from min to max. | ||
| 29 | func SliceRandList(min, max int) []int { | 32 | func SliceRandList(min, max int) []int { |
| 30 | if max < min { | 33 | if max < min { |
| 31 | min, max = max, min | 34 | min, max = max, min |
| ... | @@ -40,11 +43,13 @@ func SliceRandList(min, max int) []int { | ... | @@ -40,11 +43,13 @@ func SliceRandList(min, max int) []int { |
| 40 | return list | 43 | return list |
| 41 | } | 44 | } |
| 42 | 45 | ||
| 46 | // SliceMerge merges interface slices to one slice. | ||
| 43 | func SliceMerge(slice1, slice2 []interface{}) (c []interface{}) { | 47 | func SliceMerge(slice1, slice2 []interface{}) (c []interface{}) { |
| 44 | c = append(slice1, slice2...) | 48 | c = append(slice1, slice2...) |
| 45 | return | 49 | return |
| 46 | } | 50 | } |
| 47 | 51 | ||
| 52 | // SliceReduce generates a new slice after parsing every value by reduce function | ||
| 48 | func SliceReduce(slice []interface{}, a reducetype) (dslice []interface{}) { | 53 | func SliceReduce(slice []interface{}, a reducetype) (dslice []interface{}) { |
| 49 | for _, v := range slice { | 54 | for _, v := range slice { |
| 50 | dslice = append(dslice, a(v)) | 55 | dslice = append(dslice, a(v)) |
| ... | @@ -52,12 +57,14 @@ func SliceReduce(slice []interface{}, a reducetype) (dslice []interface{}) { | ... | @@ -52,12 +57,14 @@ func SliceReduce(slice []interface{}, a reducetype) (dslice []interface{}) { |
| 52 | return | 57 | return |
| 53 | } | 58 | } |
| 54 | 59 | ||
| 60 | // SliceRand returns random one from slice. | ||
| 55 | func SliceRand(a []interface{}) (b interface{}) { | 61 | func SliceRand(a []interface{}) (b interface{}) { |
| 56 | randnum := rand.Intn(len(a)) | 62 | randnum := rand.Intn(len(a)) |
| 57 | b = a[randnum] | 63 | b = a[randnum] |
| 58 | return | 64 | return |
| 59 | } | 65 | } |
| 60 | 66 | ||
| 67 | // SliceSum sums all values in int64 slice. | ||
| 61 | func SliceSum(intslice []int64) (sum int64) { | 68 | func SliceSum(intslice []int64) (sum int64) { |
| 62 | for _, v := range intslice { | 69 | for _, v := range intslice { |
| 63 | sum += v | 70 | sum += v |
| ... | @@ -65,6 +72,7 @@ func SliceSum(intslice []int64) (sum int64) { | ... | @@ -65,6 +72,7 @@ func SliceSum(intslice []int64) (sum int64) { |
| 65 | return | 72 | return |
| 66 | } | 73 | } |
| 67 | 74 | ||
| 75 | // SliceFilter generates a new slice after filter function. | ||
| 68 | func SliceFilter(slice []interface{}, a filtertype) (ftslice []interface{}) { | 76 | func SliceFilter(slice []interface{}, a filtertype) (ftslice []interface{}) { |
| 69 | for _, v := range slice { | 77 | for _, v := range slice { |
| 70 | if a(v) { | 78 | if a(v) { |
| ... | @@ -74,6 +82,7 @@ func SliceFilter(slice []interface{}, a filtertype) (ftslice []interface{}) { | ... | @@ -74,6 +82,7 @@ func SliceFilter(slice []interface{}, a filtertype) (ftslice []interface{}) { |
| 74 | return | 82 | return |
| 75 | } | 83 | } |
| 76 | 84 | ||
| 85 | // SliceDiff returns diff slice of slice1 - slice2. | ||
| 77 | func SliceDiff(slice1, slice2 []interface{}) (diffslice []interface{}) { | 86 | func SliceDiff(slice1, slice2 []interface{}) (diffslice []interface{}) { |
| 78 | for _, v := range slice1 { | 87 | for _, v := range slice1 { |
| 79 | if !InSliceIface(v, slice2) { | 88 | if !InSliceIface(v, slice2) { |
| ... | @@ -83,6 +92,7 @@ func SliceDiff(slice1, slice2 []interface{}) (diffslice []interface{}) { | ... | @@ -83,6 +92,7 @@ func SliceDiff(slice1, slice2 []interface{}) (diffslice []interface{}) { |
| 83 | return | 92 | return |
| 84 | } | 93 | } |
| 85 | 94 | ||
| 95 | // SliceIntersect returns diff slice of slice2 - slice1. | ||
| 86 | func SliceIntersect(slice1, slice2 []interface{}) (diffslice []interface{}) { | 96 | func SliceIntersect(slice1, slice2 []interface{}) (diffslice []interface{}) { |
| 87 | for _, v := range slice1 { | 97 | for _, v := range slice1 { |
| 88 | if !InSliceIface(v, slice2) { | 98 | if !InSliceIface(v, slice2) { |
| ... | @@ -92,6 +102,7 @@ func SliceIntersect(slice1, slice2 []interface{}) (diffslice []interface{}) { | ... | @@ -92,6 +102,7 @@ func SliceIntersect(slice1, slice2 []interface{}) (diffslice []interface{}) { |
| 92 | return | 102 | return |
| 93 | } | 103 | } |
| 94 | 104 | ||
| 105 | // SliceChuck separates one slice to some sized slice. | ||
| 95 | func SliceChunk(slice []interface{}, size int) (chunkslice [][]interface{}) { | 106 | func SliceChunk(slice []interface{}, size int) (chunkslice [][]interface{}) { |
| 96 | if size >= len(slice) { | 107 | if size >= len(slice) { |
| 97 | chunkslice = append(chunkslice, slice) | 108 | chunkslice = append(chunkslice, slice) |
| ... | @@ -105,6 +116,7 @@ func SliceChunk(slice []interface{}, size int) (chunkslice [][]interface{}) { | ... | @@ -105,6 +116,7 @@ func SliceChunk(slice []interface{}, size int) (chunkslice [][]interface{}) { |
| 105 | return | 116 | return |
| 106 | } | 117 | } |
| 107 | 118 | ||
| 119 | // SliceRange generates a new slice from begin to end with step duration of int64 number. | ||
| 108 | func SliceRange(start, end, step int64) (intslice []int64) { | 120 | func SliceRange(start, end, step int64) (intslice []int64) { |
| 109 | for i := start; i <= end; i += step { | 121 | for i := start; i <= end; i += step { |
| 110 | intslice = append(intslice, i) | 122 | intslice = append(intslice, i) |
| ... | @@ -112,6 +124,7 @@ func SliceRange(start, end, step int64) (intslice []int64) { | ... | @@ -112,6 +124,7 @@ func SliceRange(start, end, step int64) (intslice []int64) { |
| 112 | return | 124 | return |
| 113 | } | 125 | } |
| 114 | 126 | ||
| 127 | // SlicePad prepends size number of val into slice. | ||
| 115 | func SlicePad(slice []interface{}, size int, val interface{}) []interface{} { | 128 | func SlicePad(slice []interface{}, size int, val interface{}) []interface{} { |
| 116 | if size <= len(slice) { | 129 | if size <= len(slice) { |
| 117 | return slice | 130 | return slice |
| ... | @@ -122,6 +135,7 @@ func SlicePad(slice []interface{}, size int, val interface{}) []interface{} { | ... | @@ -122,6 +135,7 @@ func SlicePad(slice []interface{}, size int, val interface{}) []interface{} { |
| 122 | return slice | 135 | return slice |
| 123 | } | 136 | } |
| 124 | 137 | ||
| 138 | // SliceUnique cleans repeated values in slice. | ||
| 125 | func SliceUnique(slice []interface{}) (uniqueslice []interface{}) { | 139 | func SliceUnique(slice []interface{}) (uniqueslice []interface{}) { |
| 126 | for _, v := range slice { | 140 | for _, v := range slice { |
| 127 | if !InSliceIface(v, uniqueslice) { | 141 | if !InSliceIface(v, uniqueslice) { |
| ... | @@ -131,6 +145,7 @@ func SliceUnique(slice []interface{}) (uniqueslice []interface{}) { | ... | @@ -131,6 +145,7 @@ func SliceUnique(slice []interface{}) (uniqueslice []interface{}) { |
| 131 | return | 145 | return |
| 132 | } | 146 | } |
| 133 | 147 | ||
| 148 | // SliceShuffle shuffles a slice. | ||
| 134 | func SliceShuffle(slice []interface{}) []interface{} { | 149 | func SliceShuffle(slice []interface{}) []interface{} { |
| 135 | for i := 0; i < len(slice); i++ { | 150 | for i := 0; i < len(slice); i++ { |
| 136 | a := rand.Intn(len(slice)) | 151 | a := rand.Intn(len(slice)) | ... | ... |
| ... | @@ -41,13 +41,16 @@ func init() { | ... | @@ -41,13 +41,16 @@ func init() { |
| 41 | } | 41 | } |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | // Valid function type | ||
| 44 | type ValidFunc struct { | 45 | type ValidFunc struct { |
| 45 | Name string | 46 | Name string |
| 46 | Params []interface{} | 47 | Params []interface{} |
| 47 | } | 48 | } |
| 48 | 49 | ||
| 50 | // Validate function map | ||
| 49 | type Funcs map[string]reflect.Value | 51 | type Funcs map[string]reflect.Value |
| 50 | 52 | ||
| 53 | // validate values with named type string | ||
| 51 | func (f Funcs) Call(name string, params ...interface{}) (result []reflect.Value, err error) { | 54 | func (f Funcs) Call(name string, params ...interface{}) (result []reflect.Value, err error) { |
| 52 | defer func() { | 55 | defer func() { |
| 53 | if r := recover(); r != nil { | 56 | if r := recover(); r != nil { | ... | ... |
| ... | @@ -32,6 +32,7 @@ type ValidationResult struct { | ... | @@ -32,6 +32,7 @@ type ValidationResult struct { |
| 32 | Ok bool | 32 | Ok bool |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | // Get ValidationResult by given key string. | ||
| 35 | func (r *ValidationResult) Key(key string) *ValidationResult { | 36 | func (r *ValidationResult) Key(key string) *ValidationResult { |
| 36 | if r.Error != nil { | 37 | if r.Error != nil { |
| 37 | r.Error.Key = key | 38 | r.Error.Key = key |
| ... | @@ -39,6 +40,7 @@ func (r *ValidationResult) Key(key string) *ValidationResult { | ... | @@ -39,6 +40,7 @@ func (r *ValidationResult) Key(key string) *ValidationResult { |
| 39 | return r | 40 | return r |
| 40 | } | 41 | } |
| 41 | 42 | ||
| 43 | // Set ValidationResult message by string or format string with args | ||
| 42 | func (r *ValidationResult) Message(message string, args ...interface{}) *ValidationResult { | 44 | func (r *ValidationResult) Message(message string, args ...interface{}) *ValidationResult { |
| 43 | if r.Error != nil { | 45 | if r.Error != nil { |
| 44 | if len(args) == 0 { | 46 | if len(args) == 0 { |
| ... | @@ -56,10 +58,12 @@ type Validation struct { | ... | @@ -56,10 +58,12 @@ type Validation struct { |
| 56 | ErrorsMap map[string]*ValidationError | 58 | ErrorsMap map[string]*ValidationError |
| 57 | } | 59 | } |
| 58 | 60 | ||
| 61 | // Clean all ValidationError. | ||
| 59 | func (v *Validation) Clear() { | 62 | func (v *Validation) Clear() { |
| 60 | v.Errors = []*ValidationError{} | 63 | v.Errors = []*ValidationError{} |
| 61 | } | 64 | } |
| 62 | 65 | ||
| 66 | // Has ValidationError nor not. | ||
| 63 | func (v *Validation) HasErrors() bool { | 67 | func (v *Validation) HasErrors() bool { |
| 64 | return len(v.Errors) > 0 | 68 | return len(v.Errors) > 0 |
| 65 | } | 69 | } |
| ... | @@ -101,67 +105,83 @@ func (v *Validation) Range(obj interface{}, min, max int, key string) *Validatio | ... | @@ -101,67 +105,83 @@ func (v *Validation) Range(obj interface{}, min, max int, key string) *Validatio |
| 101 | return v.apply(Range{Min{Min: min}, Max{Max: max}, key}, obj) | 105 | return v.apply(Range{Min{Min: min}, Max{Max: max}, key}, obj) |
| 102 | } | 106 | } |
| 103 | 107 | ||
| 108 | // Test that the obj is longer than min size if type is string or slice | ||
| 104 | func (v *Validation) MinSize(obj interface{}, min int, key string) *ValidationResult { | 109 | func (v *Validation) MinSize(obj interface{}, min int, key string) *ValidationResult { |
| 105 | return v.apply(MinSize{min, key}, obj) | 110 | return v.apply(MinSize{min, key}, obj) |
| 106 | } | 111 | } |
| 107 | 112 | ||
| 113 | // Test that the obj is shorter than max size if type is string or slice | ||
| 108 | func (v *Validation) MaxSize(obj interface{}, max int, key string) *ValidationResult { | 114 | func (v *Validation) MaxSize(obj interface{}, max int, key string) *ValidationResult { |
| 109 | return v.apply(MaxSize{max, key}, obj) | 115 | return v.apply(MaxSize{max, key}, obj) |
| 110 | } | 116 | } |
| 111 | 117 | ||
| 118 | // Test that the obj is same length to n if type is string or slice | ||
| 112 | func (v *Validation) Length(obj interface{}, n int, key string) *ValidationResult { | 119 | func (v *Validation) Length(obj interface{}, n int, key string) *ValidationResult { |
| 113 | return v.apply(Length{n, key}, obj) | 120 | return v.apply(Length{n, key}, obj) |
| 114 | } | 121 | } |
| 115 | 122 | ||
| 123 | // Test that the obj is [a-zA-Z] if type is string | ||
| 116 | func (v *Validation) Alpha(obj interface{}, key string) *ValidationResult { | 124 | func (v *Validation) Alpha(obj interface{}, key string) *ValidationResult { |
| 117 | return v.apply(Alpha{key}, obj) | 125 | return v.apply(Alpha{key}, obj) |
| 118 | } | 126 | } |
| 119 | 127 | ||
| 128 | // Test that the obj is [0-9] if type is string | ||
| 120 | func (v *Validation) Numeric(obj interface{}, key string) *ValidationResult { | 129 | func (v *Validation) Numeric(obj interface{}, key string) *ValidationResult { |
| 121 | return v.apply(Numeric{key}, obj) | 130 | return v.apply(Numeric{key}, obj) |
| 122 | } | 131 | } |
| 123 | 132 | ||
| 133 | // Test that the obj is [0-9a-zA-Z] if type is string | ||
| 124 | func (v *Validation) AlphaNumeric(obj interface{}, key string) *ValidationResult { | 134 | func (v *Validation) AlphaNumeric(obj interface{}, key string) *ValidationResult { |
| 125 | return v.apply(AlphaNumeric{key}, obj) | 135 | return v.apply(AlphaNumeric{key}, obj) |
| 126 | } | 136 | } |
| 127 | 137 | ||
| 138 | // Test that the obj matches regexp if type is string | ||
| 128 | func (v *Validation) Match(obj interface{}, regex *regexp.Regexp, key string) *ValidationResult { | 139 | func (v *Validation) Match(obj interface{}, regex *regexp.Regexp, key string) *ValidationResult { |
| 129 | return v.apply(Match{regex, key}, obj) | 140 | return v.apply(Match{regex, key}, obj) |
| 130 | } | 141 | } |
| 131 | 142 | ||
| 143 | // Test that the obj doesn't match regexp if type is string | ||
| 132 | func (v *Validation) NoMatch(obj interface{}, regex *regexp.Regexp, key string) *ValidationResult { | 144 | func (v *Validation) NoMatch(obj interface{}, regex *regexp.Regexp, key string) *ValidationResult { |
| 133 | return v.apply(NoMatch{Match{Regexp: regex}, key}, obj) | 145 | return v.apply(NoMatch{Match{Regexp: regex}, key}, obj) |
| 134 | } | 146 | } |
| 135 | 147 | ||
| 148 | // Test that the obj is [0-9a-zA-Z_-] if type is string | ||
| 136 | func (v *Validation) AlphaDash(obj interface{}, key string) *ValidationResult { | 149 | func (v *Validation) AlphaDash(obj interface{}, key string) *ValidationResult { |
| 137 | return v.apply(AlphaDash{NoMatch{Match: Match{Regexp: alphaDashPattern}}, key}, obj) | 150 | return v.apply(AlphaDash{NoMatch{Match: Match{Regexp: alphaDashPattern}}, key}, obj) |
| 138 | } | 151 | } |
| 139 | 152 | ||
| 153 | // Test that the obj is email address if type is string | ||
| 140 | func (v *Validation) Email(obj interface{}, key string) *ValidationResult { | 154 | func (v *Validation) Email(obj interface{}, key string) *ValidationResult { |
| 141 | return v.apply(Email{Match{Regexp: emailPattern}, key}, obj) | 155 | return v.apply(Email{Match{Regexp: emailPattern}, key}, obj) |
| 142 | } | 156 | } |
| 143 | 157 | ||
| 158 | // Test that the obj is IP address if type is string | ||
| 144 | func (v *Validation) IP(obj interface{}, key string) *ValidationResult { | 159 | func (v *Validation) IP(obj interface{}, key string) *ValidationResult { |
| 145 | return v.apply(IP{Match{Regexp: ipPattern}, key}, obj) | 160 | return v.apply(IP{Match{Regexp: ipPattern}, key}, obj) |
| 146 | } | 161 | } |
| 147 | 162 | ||
| 163 | // Test that the obj is base64 encoded if type is string | ||
| 148 | func (v *Validation) Base64(obj interface{}, key string) *ValidationResult { | 164 | func (v *Validation) Base64(obj interface{}, key string) *ValidationResult { |
| 149 | return v.apply(Base64{Match{Regexp: base64Pattern}, key}, obj) | 165 | return v.apply(Base64{Match{Regexp: base64Pattern}, key}, obj) |
| 150 | } | 166 | } |
| 151 | 167 | ||
| 168 | // Test that the obj is chinese mobile number if type is string | ||
| 152 | func (v *Validation) Mobile(obj interface{}, key string) *ValidationResult { | 169 | func (v *Validation) Mobile(obj interface{}, key string) *ValidationResult { |
| 153 | return v.apply(Mobile{Match{Regexp: mobilePattern}, key}, obj) | 170 | return v.apply(Mobile{Match{Regexp: mobilePattern}, key}, obj) |
| 154 | } | 171 | } |
| 155 | 172 | ||
| 173 | // Test that the obj is chinese telephone number if type is string | ||
| 156 | func (v *Validation) Tel(obj interface{}, key string) *ValidationResult { | 174 | func (v *Validation) Tel(obj interface{}, key string) *ValidationResult { |
| 157 | return v.apply(Tel{Match{Regexp: telPattern}, key}, obj) | 175 | return v.apply(Tel{Match{Regexp: telPattern}, key}, obj) |
| 158 | } | 176 | } |
| 159 | 177 | ||
| 178 | // Test that the obj is chinese mobile or telephone number if type is string | ||
| 160 | func (v *Validation) Phone(obj interface{}, key string) *ValidationResult { | 179 | func (v *Validation) Phone(obj interface{}, key string) *ValidationResult { |
| 161 | return v.apply(Phone{Mobile{Match: Match{Regexp: mobilePattern}}, | 180 | return v.apply(Phone{Mobile{Match: Match{Regexp: mobilePattern}}, |
| 162 | Tel{Match: Match{Regexp: telPattern}}, key}, obj) | 181 | Tel{Match: Match{Regexp: telPattern}}, key}, obj) |
| 163 | } | 182 | } |
| 164 | 183 | ||
| 184 | // Test that the obj is chinese zip code if type is string | ||
| 165 | func (v *Validation) ZipCode(obj interface{}, key string) *ValidationResult { | 185 | func (v *Validation) ZipCode(obj interface{}, key string) *ValidationResult { |
| 166 | return v.apply(ZipCode{Match{Regexp: zipCodePattern}, key}, obj) | 186 | return v.apply(ZipCode{Match{Regexp: zipCodePattern}, key}, obj) |
| 167 | } | 187 | } |
| ... | @@ -210,6 +230,7 @@ func (v *Validation) setError(err *ValidationError) { | ... | @@ -210,6 +230,7 @@ func (v *Validation) setError(err *ValidationError) { |
| 210 | } | 230 | } |
| 211 | } | 231 | } |
| 212 | 232 | ||
| 233 | // Set error message for one field in ValidationError | ||
| 213 | func (v *Validation) SetError(fieldName string, errMsg string) *ValidationError { | 234 | func (v *Validation) SetError(fieldName string, errMsg string) *ValidationError { |
| 214 | err := &ValidationError{Key: fieldName, Field: fieldName, Tmpl: errMsg, Message: errMsg} | 235 | err := &ValidationError{Key: fieldName, Field: fieldName, Tmpl: errMsg, Message: errMsg} |
| 215 | v.setError(err) | 236 | v.setError(err) |
| ... | @@ -230,6 +251,7 @@ func (v *Validation) Check(obj interface{}, checks ...Validator) *ValidationResu | ... | @@ -230,6 +251,7 @@ func (v *Validation) Check(obj interface{}, checks ...Validator) *ValidationResu |
| 230 | return result | 251 | return result |
| 231 | } | 252 | } |
| 232 | 253 | ||
| 254 | // Validate a struct. | ||
| 233 | // the obj parameter must be a struct or a struct pointer | 255 | // the obj parameter must be a struct or a struct pointer |
| 234 | func (v *Validation) Valid(obj interface{}) (b bool, err error) { | 256 | func (v *Validation) Valid(obj interface{}) (b bool, err error) { |
| 235 | objT := reflect.TypeOf(obj) | 257 | objT := reflect.TypeOf(obj) | ... | ... |
-
Please register or sign in to post a comment