Skip to content

Commit 3740ae1

Browse files
Dean KarnDean Karn
authored andcommitted
Merge branch 'v1-development' into v1
2 parents 87fff1c + 53ffdb7 commit 3740ae1

File tree

3 files changed

+160
-17
lines changed

3 files changed

+160
-17
lines changed

baked_in.go

Lines changed: 101 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ var BakedInValidators = map[string]ValidationFunc{
1313
"len": length,
1414
"min": min,
1515
"max": max,
16+
"lt": lt,
17+
"lte": lte,
18+
"gt": gt,
19+
"gte": gte,
1620
"alpha": alpha,
1721
"alphanum": alphanum,
1822
"numeric": numeric,
@@ -183,6 +187,78 @@ func required(field interface{}, param string) bool {
183187
}
184188
}
185189

190+
func gte(field interface{}, param string) bool {
191+
192+
st := reflect.ValueOf(field)
193+
194+
switch st.Kind() {
195+
196+
case reflect.String:
197+
p := asInt(param)
198+
199+
return int64(len(st.String())) >= p
200+
201+
case reflect.Slice, reflect.Map, reflect.Array:
202+
p := asInt(param)
203+
204+
return int64(st.Len()) >= p
205+
206+
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
207+
p := asInt(param)
208+
209+
return st.Int() >= p
210+
211+
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
212+
p := asUint(param)
213+
214+
return st.Uint() >= p
215+
216+
case reflect.Float32, reflect.Float64:
217+
p := asFloat(param)
218+
219+
return st.Float() >= p
220+
221+
default:
222+
panic(fmt.Sprintf("Bad field type for Input Param %s for %s\n", param, field))
223+
}
224+
}
225+
226+
func gt(field interface{}, param string) bool {
227+
228+
st := reflect.ValueOf(field)
229+
230+
switch st.Kind() {
231+
232+
case reflect.String:
233+
p := asInt(param)
234+
235+
return int64(len(st.String())) > p
236+
237+
case reflect.Slice, reflect.Map, reflect.Array:
238+
p := asInt(param)
239+
240+
return int64(st.Len()) > p
241+
242+
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
243+
p := asInt(param)
244+
245+
return st.Int() > p
246+
247+
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
248+
p := asUint(param)
249+
250+
return st.Uint() > p
251+
252+
case reflect.Float32, reflect.Float64:
253+
p := asFloat(param)
254+
255+
return st.Float() > p
256+
257+
default:
258+
panic(fmt.Sprintf("Bad field type for Input Param %s for %s\n", param, field))
259+
}
260+
}
261+
186262
// length tests whether a variable's length is equal to a given
187263
// value. For strings it tests the number of characters whereas
188264
// for maps and slices it tests the number of items.
@@ -228,45 +304,46 @@ func length(field interface{}, param string) bool {
228304
// and slices it tests the number of items.
229305
func min(field interface{}, param string) bool {
230306

307+
return gte(field, param)
308+
}
309+
310+
func lte(field interface{}, param string) bool {
311+
231312
st := reflect.ValueOf(field)
232313

233314
switch st.Kind() {
234315

235316
case reflect.String:
236317
p := asInt(param)
237318

238-
return int64(len(st.String())) >= p
319+
return int64(len(st.String())) <= p
239320

240321
case reflect.Slice, reflect.Map, reflect.Array:
241322
p := asInt(param)
242323

243-
return int64(st.Len()) >= p
324+
return int64(st.Len()) <= p
244325

245326
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
246327
p := asInt(param)
247328

248-
return st.Int() >= p
329+
return st.Int() <= p
249330

250331
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
251332
p := asUint(param)
252333

253-
return st.Uint() >= p
334+
return st.Uint() <= p
254335

255336
case reflect.Float32, reflect.Float64:
256337
p := asFloat(param)
257338

258-
return st.Float() >= p
339+
return st.Float() <= p
259340

260341
default:
261342
panic(fmt.Sprintf("Bad field type for Input Param %s for %s\n", param, field))
262343
}
263344
}
264345

265-
// max tests whether a variable value is lesser than a given
266-
// value. For numbers, it's a simple lesser-than test; for
267-
// strings it tests the number of characters whereas for maps
268-
// and slices it tests the number of items.
269-
func max(field interface{}, param string) bool {
346+
func lt(field interface{}, param string) bool {
270347

271348
st := reflect.ValueOf(field)
272349

@@ -275,33 +352,42 @@ func max(field interface{}, param string) bool {
275352
case reflect.String:
276353
p := asInt(param)
277354

278-
return int64(len(st.String())) <= p
355+
return int64(len(st.String())) < p
279356

280357
case reflect.Slice, reflect.Map, reflect.Array:
281358
p := asInt(param)
282359

283-
return int64(st.Len()) <= p
360+
return int64(st.Len()) < p
284361

285362
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
286363
p := asInt(param)
287364

288-
return st.Int() <= p
365+
return st.Int() < p
289366

290367
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
291368
p := asUint(param)
292369

293-
return st.Uint() <= p
370+
return st.Uint() < p
294371

295372
case reflect.Float32, reflect.Float64:
296373
p := asFloat(param)
297374

298-
return st.Float() <= p
375+
return st.Float() < p
299376

300377
default:
301378
panic(fmt.Sprintf("Bad field type for Input Param %s for %s\n", param, field))
302379
}
303380
}
304381

382+
// max tests whether a variable value is lesser than a given
383+
// value. For numbers, it's a simple lesser-than test; for
384+
// strings it tests the number of characters whereas for maps
385+
// and slices it tests the number of items.
386+
func max(field interface{}, param string) bool {
387+
388+
return lte(field, param)
389+
}
390+
305391
// asInt retuns the parameter as a int64
306392
// or panics if it can't convert
307393
func asInt(param string) int64 {

doc.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,27 @@ Here is a list of the current built in validators:
163163
the string length is at least that number of characters. For slices,
164164
arrays, and maps, validates the number of items. (Usage: min=10)
165165
166+
gt
167+
For numbers, this will ensure that the value is greater than the
168+
parameter given. For strings, it checks that the string length
169+
is greater than that number of characters. For slices, arrays
170+
and maps it validates the number of items. (Usage: gt=10)
171+
172+
gte
173+
Same as 'min' above. Kept both to make terminology with 'len' easier
174+
(Usage: gte=10)
175+
176+
lt
177+
For numbers, this will ensure that the value is
178+
less than the parameter given. For strings, it checks
179+
that the string length is less than that number of characters.
180+
For slices, arrays, and maps it validates the number of items.
181+
(Usage: lt=10)
182+
183+
lte
184+
Same as 'max' above. Kept both to make terminology with 'len' easier
185+
(Usage: lte=10)
186+
166187
alpha
167188
This validates that a strings value contains alpha characters only
168189
(Usage: alpha)

validator_test.go

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ type TestString struct {
3434
Min string `validate:"min=1"`
3535
Max string `validate:"max=10"`
3636
MinMax string `validate:"min=1,max=10"`
37+
Lt string `validate:"lt=10"`
38+
Lte string `validate:"lte=10"`
39+
Gt string `validate:"gt=10"`
40+
Gte string `validate:"gte=10"`
3741
OmitEmpty string `validate:"omitempty,min=1,max=10"`
3842
Sub *SubTest
3943
SubIgnore *SubTest `validate:"-"`
@@ -49,6 +53,10 @@ type TestInt32 struct {
4953
Min int `validate:"min=1"`
5054
Max int `validate:"max=10"`
5155
MinMax int `validate:"min=1,max=10"`
56+
Lt int `validate:"lt=10"`
57+
Lte int `validate:"lte=10"`
58+
Gt int `validate:"gt=10"`
59+
Gte int `validate:"gte=10"`
5260
OmitEmpty int `validate:"omitempty,min=1,max=10"`
5361
}
5462

@@ -425,6 +433,10 @@ func (ms *MySuite) TestFlattening(c *C) {
425433
Min: "min=1",
426434
Max: "1234567890",
427435
MinMax: "12345",
436+
Lt: "012345678",
437+
Lte: "0123456789",
438+
Gt: "01234567890",
439+
Gte: "0123456789",
428440
OmitEmpty: "",
429441
Sub: &SubTest{
430442
Test: "1",
@@ -472,6 +484,8 @@ func (ms *MySuite) TestFlattening(c *C) {
472484

473485
// Assert Fields
474486
AssertMapFieldError(err2, "Len", "len", c)
487+
AssertMapFieldError(err2, "Gt", "gt", c)
488+
AssertMapFieldError(err2, "Gte", "gte", c)
475489

476490
// Assert Struct Field
477491
AssertMapFieldError(err2, "Sub.Test", "required", c)
@@ -491,6 +505,10 @@ func (ms *MySuite) TestStructStringValidation(c *C) {
491505
Min: "min=1",
492506
Max: "1234567890",
493507
MinMax: "12345",
508+
Lt: "012345678",
509+
Lte: "0123456789",
510+
Gt: "01234567890",
511+
Gte: "0123456789",
494512
OmitEmpty: "",
495513
Sub: &SubTest{
496514
Test: "1",
@@ -517,6 +535,10 @@ func (ms *MySuite) TestStructStringValidation(c *C) {
517535
Min: "",
518536
Max: "12345678901",
519537
MinMax: "",
538+
Lt: "0123456789",
539+
Lte: "01234567890",
540+
Gt: "1",
541+
Gte: "1",
520542
OmitEmpty: "12345678901",
521543
Sub: &SubTest{
522544
Test: "",
@@ -536,7 +558,7 @@ func (ms *MySuite) TestStructStringValidation(c *C) {
536558
// Assert Top Level
537559
c.Assert(err, NotNil)
538560
c.Assert(err.Struct, Equals, "TestString")
539-
c.Assert(len(err.Errors), Equals, 6)
561+
c.Assert(len(err.Errors), Equals, 10)
540562
c.Assert(len(err.StructErrors), Equals, 3)
541563

542564
// Assert Fields
@@ -545,6 +567,8 @@ func (ms *MySuite) TestStructStringValidation(c *C) {
545567
AssertFieldError(err, "Min", "min", c)
546568
AssertFieldError(err, "Max", "max", c)
547569
AssertFieldError(err, "MinMax", "min", c)
570+
AssertFieldError(err, "Gt", "gt", c)
571+
AssertFieldError(err, "Gte", "gte", c)
548572
AssertFieldError(err, "OmitEmpty", "max", c)
549573

550574
// Assert Anonymous embedded struct
@@ -566,6 +590,10 @@ func (ms *MySuite) TestStructInt32Validation(c *C) {
566590
Min: 1,
567591
Max: 10,
568592
MinMax: 5,
593+
Lt: 9,
594+
Lte: 10,
595+
Gt: 11,
596+
Gte: 10,
569597
OmitEmpty: 0,
570598
}
571599

@@ -578,6 +606,10 @@ func (ms *MySuite) TestStructInt32Validation(c *C) {
578606
Min: -1,
579607
Max: 11,
580608
MinMax: -1,
609+
Lt: 10,
610+
Lte: 11,
611+
Gt: 10,
612+
Gte: 9,
581613
OmitEmpty: 11,
582614
}
583615

@@ -586,7 +618,7 @@ func (ms *MySuite) TestStructInt32Validation(c *C) {
586618
// Assert Top Level
587619
c.Assert(err, NotNil)
588620
c.Assert(err.Struct, Equals, "TestInt32")
589-
c.Assert(len(err.Errors), Equals, 6)
621+
c.Assert(len(err.Errors), Equals, 10)
590622
c.Assert(len(err.StructErrors), Equals, 0)
591623

592624
// Assert Fields
@@ -595,6 +627,10 @@ func (ms *MySuite) TestStructInt32Validation(c *C) {
595627
AssertFieldError(err, "Min", "min", c)
596628
AssertFieldError(err, "Max", "max", c)
597629
AssertFieldError(err, "MinMax", "min", c)
630+
AssertFieldError(err, "Lt", "lt", c)
631+
AssertFieldError(err, "Lte", "lte", c)
632+
AssertFieldError(err, "Gt", "gt", c)
633+
AssertFieldError(err, "Gte", "gte", c)
598634
AssertFieldError(err, "OmitEmpty", "max", c)
599635
}
600636

0 commit comments

Comments
 (0)