validate_test.go 5.7 KB

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