validate_test.go 4.9 KB

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