validate_test.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. // Copyright 2014 Manu Martinez-Almeida. All rights reserved.
  2. // Use of this source code is governed by a MIT style
  3. // license that can be found in the LICENSE file.
  4. package binding
  5. import (
  6. "bytes"
  7. "reflect"
  8. "testing"
  9. "time"
  10. "github.com/stretchr/testify/assert"
  11. "gopkg.in/go-playground/validator.v8"
  12. )
  13. type testInterface interface {
  14. String() string
  15. }
  16. type substructNoValidation struct {
  17. IString string
  18. IInt int
  19. }
  20. type mapNoValidationSub map[string]substructNoValidation
  21. type structNoValidationValues struct {
  22. substructNoValidation
  23. Boolean bool
  24. Uinteger uint
  25. Integer int
  26. Integer8 int8
  27. Integer16 int16
  28. Integer32 int32
  29. Integer64 int64
  30. Uinteger8 uint8
  31. Uinteger16 uint16
  32. Uinteger32 uint32
  33. Uinteger64 uint64
  34. Float32 float32
  35. Float64 float64
  36. String string
  37. Date time.Time
  38. Struct substructNoValidation
  39. InlinedStruct struct {
  40. String []string
  41. Integer int
  42. }
  43. IntSlice []int
  44. IntPointerSlice []*int
  45. StructPointerSlice []*substructNoValidation
  46. StructSlice []substructNoValidation
  47. InterfaceSlice []testInterface
  48. UniversalInterface interface{}
  49. CustomInterface testInterface
  50. FloatMap map[string]float32
  51. StructMap mapNoValidationSub
  52. }
  53. func createNoValidationValues() structNoValidationValues {
  54. integer := 1
  55. s := structNoValidationValues{
  56. Boolean: true,
  57. Uinteger: 1 << 29,
  58. Integer: -10000,
  59. Integer8: 120,
  60. Integer16: -20000,
  61. Integer32: 1 << 29,
  62. Integer64: 1 << 61,
  63. Uinteger8: 250,
  64. Uinteger16: 50000,
  65. Uinteger32: 1 << 31,
  66. Uinteger64: 1 << 62,
  67. Float32: 123.456,
  68. Float64: 123.456789,
  69. String: "text",
  70. Date: time.Time{},
  71. CustomInterface: &bytes.Buffer{},
  72. Struct: substructNoValidation{},
  73. IntSlice: []int{-3, -2, 1, 0, 1, 2, 3},
  74. IntPointerSlice: []*int{&integer},
  75. StructSlice: []substructNoValidation{},
  76. UniversalInterface: 1.2,
  77. FloatMap: map[string]float32{
  78. "foo": 1.23,
  79. "bar": 232.323,
  80. },
  81. StructMap: mapNoValidationSub{
  82. "foo": substructNoValidation{},
  83. "bar": substructNoValidation{},
  84. },
  85. // StructPointerSlice []noValidationSub
  86. // InterfaceSlice []testInterface
  87. }
  88. s.InlinedStruct.Integer = 1000
  89. s.InlinedStruct.String = []string{"first", "second"}
  90. s.IString = "substring"
  91. s.IInt = 987654
  92. return s
  93. }
  94. func TestValidateNoValidationValues(t *testing.T) {
  95. origin := createNoValidationValues()
  96. test := createNoValidationValues()
  97. empty := structNoValidationValues{}
  98. assert.Nil(t, validate(test))
  99. assert.Nil(t, validate(&test))
  100. assert.Nil(t, validate(empty))
  101. assert.Nil(t, validate(&empty))
  102. assert.Equal(t, origin, test)
  103. }
  104. type structNoValidationPointer struct {
  105. substructNoValidation
  106. Boolean bool
  107. Uinteger *uint
  108. Integer *int
  109. Integer8 *int8
  110. Integer16 *int16
  111. Integer32 *int32
  112. Integer64 *int64
  113. Uinteger8 *uint8
  114. Uinteger16 *uint16
  115. Uinteger32 *uint32
  116. Uinteger64 *uint64
  117. Float32 *float32
  118. Float64 *float64
  119. String *string
  120. Date *time.Time
  121. Struct *substructNoValidation
  122. IntSlice *[]int
  123. IntPointerSlice *[]*int
  124. StructPointerSlice *[]*substructNoValidation
  125. StructSlice *[]substructNoValidation
  126. InterfaceSlice *[]testInterface
  127. FloatMap *map[string]float32
  128. StructMap *mapNoValidationSub
  129. }
  130. func TestValidateNoValidationPointers(t *testing.T) {
  131. //origin := createNoValidation_values()
  132. //test := createNoValidation_values()
  133. empty := structNoValidationPointer{}
  134. //assert.Nil(t, validate(test))
  135. //assert.Nil(t, validate(&test))
  136. assert.Nil(t, validate(empty))
  137. assert.Nil(t, validate(&empty))
  138. //assert.Equal(t, origin, test)
  139. }
  140. type Object map[string]interface{}
  141. func TestValidatePrimitives(t *testing.T) {
  142. obj := Object{"foo": "bar", "bar": 1}
  143. assert.NoError(t, validate(obj))
  144. assert.NoError(t, validate(&obj))
  145. assert.Equal(t, obj, Object{"foo": "bar", "bar": 1})
  146. obj2 := []Object{{"foo": "bar", "bar": 1}, {"foo": "bar", "bar": 1}}
  147. assert.NoError(t, validate(obj2))
  148. assert.NoError(t, validate(&obj2))
  149. nu := 10
  150. assert.NoError(t, validate(nu))
  151. assert.NoError(t, validate(&nu))
  152. assert.Equal(t, nu, 10)
  153. str := "value"
  154. assert.NoError(t, validate(str))
  155. assert.NoError(t, validate(&str))
  156. assert.Equal(t, str, "value")
  157. }
  158. // structCustomValidation is a helper struct we use to check that
  159. // custom validation can be registered on it.
  160. // The `notone` binding directive is for custom validation and registered later.
  161. type structCustomValidation struct {
  162. Integer int `binding:"notone"`
  163. }
  164. // notOne is a custom validator meant to be used with `validator.v8` library.
  165. // The method signature for `v9` is significantly different and this function
  166. // would need to be changed for tests to pass after upgrade.
  167. // See https://github.com/gin-gonic/gin/pull/1015.
  168. func notOne(
  169. v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value,
  170. field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string,
  171. ) bool {
  172. if val, ok := field.Interface().(int); ok {
  173. return val != 1
  174. }
  175. return false
  176. }
  177. func TestValidatorEngine(t *testing.T) {
  178. // This validates that the function `notOne` matches
  179. // the expected function signature by `defaultValidator`
  180. // and by extension the validator library.
  181. engine, ok := Validator.Engine().(*validator.Validate)
  182. assert.True(t, ok)
  183. err := engine.RegisterValidation("notone", notOne)
  184. // Check that we can register custom validation without error
  185. assert.Nil(t, err)
  186. // Create an instance which will fail validation
  187. withOne := structCustomValidation{Integer: 1}
  188. errs := validate(withOne)
  189. // Check that we got back non-nil errs
  190. assert.NotNil(t, errs)
  191. // Check that the error matches expectation
  192. assert.Error(t, errs, "", "", "notone")
  193. }