marshal_test.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. package gocql
  2. import (
  3. "bytes"
  4. "math"
  5. "reflect"
  6. "speter.net/go/exp/math/dec/inf"
  7. "strings"
  8. "testing"
  9. "time"
  10. )
  11. var marshalTests = []struct {
  12. Info *TypeInfo
  13. Data []byte
  14. Value interface{}
  15. }{
  16. {
  17. &TypeInfo{Type: TypeVarchar},
  18. []byte("hello world"),
  19. []byte("hello world"),
  20. },
  21. {
  22. &TypeInfo{Type: TypeVarchar},
  23. []byte("hello world"),
  24. "hello world",
  25. },
  26. {
  27. &TypeInfo{Type: TypeVarchar},
  28. []byte(nil),
  29. []byte(nil),
  30. },
  31. {
  32. &TypeInfo{Type: TypeVarchar},
  33. []byte("hello world"),
  34. MyString("hello world"),
  35. },
  36. {
  37. &TypeInfo{Type: TypeVarchar},
  38. []byte("HELLO WORLD"),
  39. CustomString("hello world"),
  40. },
  41. {
  42. &TypeInfo{Type: TypeBlob},
  43. []byte("hello\x00"),
  44. []byte("hello\x00"),
  45. },
  46. {
  47. &TypeInfo{Type: TypeBlob},
  48. []byte(nil),
  49. []byte(nil),
  50. },
  51. {
  52. &TypeInfo{Type: TypeTimeUUID},
  53. []byte{0x3d, 0xcd, 0x98, 0x0, 0xf3, 0xd9, 0x11, 0xbf, 0x86, 0xd4, 0xb8, 0xe8, 0x56, 0x2c, 0xc, 0xd0},
  54. func() UUID {
  55. x, _ := UUIDFromBytes([]byte{0x3d, 0xcd, 0x98, 0x0, 0xf3, 0xd9, 0x11, 0xbf, 0x86, 0xd4, 0xb8, 0xe8, 0x56, 0x2c, 0xc, 0xd0})
  56. return x
  57. }(),
  58. },
  59. {
  60. &TypeInfo{Type: TypeInt},
  61. []byte("\x00\x00\x00\x00"),
  62. 0,
  63. },
  64. {
  65. &TypeInfo{Type: TypeInt},
  66. []byte("\x01\x02\x03\x04"),
  67. 16909060,
  68. },
  69. {
  70. &TypeInfo{Type: TypeInt},
  71. []byte("\x80\x00\x00\x00"),
  72. int32(math.MinInt32),
  73. },
  74. {
  75. &TypeInfo{Type: TypeInt},
  76. []byte("\x7f\xff\xff\xff"),
  77. int32(math.MaxInt32),
  78. },
  79. {
  80. &TypeInfo{Type: TypeBigInt},
  81. []byte("\x00\x00\x00\x00\x00\x00\x00\x00"),
  82. 0,
  83. },
  84. {
  85. &TypeInfo{Type: TypeBigInt},
  86. []byte("\x01\x02\x03\x04\x05\x06\x07\x08"),
  87. 72623859790382856,
  88. },
  89. {
  90. &TypeInfo{Type: TypeBigInt},
  91. []byte("\x80\x00\x00\x00\x00\x00\x00\x00"),
  92. int64(math.MinInt64),
  93. },
  94. {
  95. &TypeInfo{Type: TypeBigInt},
  96. []byte("\x7f\xff\xff\xff\xff\xff\xff\xff"),
  97. int64(math.MaxInt64),
  98. },
  99. {
  100. &TypeInfo{Type: TypeBoolean},
  101. []byte("\x00"),
  102. false,
  103. },
  104. {
  105. &TypeInfo{Type: TypeBoolean},
  106. []byte("\x01"),
  107. true,
  108. },
  109. {
  110. &TypeInfo{Type: TypeFloat},
  111. []byte("\x40\x49\x0f\xdb"),
  112. float32(3.14159265),
  113. },
  114. {
  115. &TypeInfo{Type: TypeDouble},
  116. []byte("\x40\x09\x21\xfb\x53\xc8\xd4\xf1"),
  117. float64(3.14159265),
  118. },
  119. {
  120. &TypeInfo{Type: TypeDecimal},
  121. []byte("\x00\x01\x86\xa0\xcb\xd7\x12\xbb\x6d"),
  122. inf.NewDec(875486690157, 100000),
  123. },
  124. {
  125. &TypeInfo{Type: TypeDecimal},
  126. []byte("\x00\x00\x00\x00\x00"),
  127. inf.NewDec(0, 0),
  128. },
  129. {
  130. &TypeInfo{Type: TypeTimestamp},
  131. []byte("\x00\x00\x01\x40\x77\x16\xe1\xb8"),
  132. time.Date(2013, time.August, 13, 9, 52, 3, 0, time.UTC),
  133. },
  134. {
  135. &TypeInfo{Type: TypeTimestamp},
  136. []byte("\x00\x00\x01\x40\x77\x16\xe1\xb8"),
  137. int64(1376387523000),
  138. },
  139. {
  140. &TypeInfo{Type: TypeList, Elem: &TypeInfo{Type: TypeInt}},
  141. []byte("\x00\x02\x00\x04\x00\x00\x00\x01\x00\x04\x00\x00\x00\x02"),
  142. []int{1, 2},
  143. },
  144. {
  145. &TypeInfo{Type: TypeList, Elem: &TypeInfo{Type: TypeInt}},
  146. []byte("\x00\x02\x00\x04\x00\x00\x00\x01\x00\x04\x00\x00\x00\x02"),
  147. [2]int{1, 2},
  148. },
  149. {
  150. &TypeInfo{Type: TypeSet, Elem: &TypeInfo{Type: TypeInt}},
  151. []byte("\x00\x02\x00\x04\x00\x00\x00\x01\x00\x04\x00\x00\x00\x02"),
  152. []int{1, 2},
  153. },
  154. {
  155. &TypeInfo{Type: TypeSet, Elem: &TypeInfo{Type: TypeInt}},
  156. []byte(nil),
  157. []int(nil),
  158. },
  159. {
  160. &TypeInfo{Type: TypeMap,
  161. Key: &TypeInfo{Type: TypeVarchar},
  162. Elem: &TypeInfo{Type: TypeInt},
  163. },
  164. []byte("\x00\x01\x00\x03foo\x00\x04\x00\x00\x00\x01"),
  165. map[string]int{"foo": 1},
  166. },
  167. {
  168. &TypeInfo{Type: TypeMap,
  169. Key: &TypeInfo{Type: TypeVarchar},
  170. Elem: &TypeInfo{Type: TypeInt},
  171. },
  172. []byte(nil),
  173. map[string]int(nil),
  174. },
  175. {
  176. &TypeInfo{Type: TypeList, Elem: &TypeInfo{Type: TypeVarchar}},
  177. bytes.Join([][]byte{
  178. []byte("\x00\x01\xFF\xFF"),
  179. bytes.Repeat([]byte("X"), 65535)}, []byte("")),
  180. []string{strings.Repeat("X", 65535)},
  181. },
  182. {
  183. &TypeInfo{Type: TypeMap,
  184. Key: &TypeInfo{Type: TypeVarchar},
  185. Elem: &TypeInfo{Type: TypeVarchar},
  186. },
  187. bytes.Join([][]byte{
  188. []byte("\x00\x01\xFF\xFF"),
  189. bytes.Repeat([]byte("X"), 65535),
  190. []byte("\xFF\xFF"),
  191. bytes.Repeat([]byte("Y"), 65535)}, []byte("")),
  192. map[string]string{
  193. strings.Repeat("X", 65535): strings.Repeat("Y", 65535),
  194. },
  195. },
  196. }
  197. func TestMarshal(t *testing.T) {
  198. for i, test := range marshalTests {
  199. data, err := Marshal(test.Info, test.Value)
  200. if err != nil {
  201. t.Errorf("marshalTest[%d]: %v", i, err)
  202. continue
  203. }
  204. if !bytes.Equal(data, test.Data) {
  205. t.Errorf("marshalTest[%d]: expected %q, got %q.", i, test.Data, data)
  206. }
  207. }
  208. }
  209. func TestUnmarshal(t *testing.T) {
  210. for i, test := range marshalTests {
  211. v := reflect.New(reflect.TypeOf(test.Value))
  212. err := Unmarshal(test.Info, test.Data, v.Interface())
  213. if err != nil {
  214. t.Errorf("marshalTest[%d]: %v", i, err)
  215. continue
  216. }
  217. if !reflect.DeepEqual(v.Elem().Interface(), test.Value) {
  218. t.Errorf("marshalTest[%d]: expected %#v, got %#v.", i, test.Value, v.Elem().Interface())
  219. }
  220. }
  221. }
  222. type CustomString string
  223. func (c CustomString) MarshalCQL(info *TypeInfo) ([]byte, error) {
  224. return []byte(strings.ToUpper(string(c))), nil
  225. }
  226. func (c *CustomString) UnmarshalCQL(info *TypeInfo, data []byte) error {
  227. *c = CustomString(strings.ToLower(string(data)))
  228. return nil
  229. }
  230. type MyString string
  231. type MyInt int