marshal_test.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. package gocql
  2. import (
  3. "bytes"
  4. "math"
  5. "reflect"
  6. "strings"
  7. "testing"
  8. "time"
  9. "tux21b.org/v1/gocql/uuid"
  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. uuid.FromBytes([]byte{0x3d, 0xcd, 0x98, 0x0, 0xf3, 0xd9, 0x11, 0xbf, 0x86, 0xd4, 0xb8, 0xe8, 0x56, 0x2c, 0xc, 0xd0}),
  55. },
  56. {
  57. &TypeInfo{Type: TypeInt},
  58. []byte("\x00\x00\x00\x00"),
  59. 0,
  60. },
  61. {
  62. &TypeInfo{Type: TypeInt},
  63. []byte("\x01\x02\x03\x04"),
  64. 16909060,
  65. },
  66. {
  67. &TypeInfo{Type: TypeInt},
  68. []byte("\x80\x00\x00\x00"),
  69. int32(math.MinInt32),
  70. },
  71. {
  72. &TypeInfo{Type: TypeInt},
  73. []byte("\x7f\xff\xff\xff"),
  74. int32(math.MaxInt32),
  75. },
  76. {
  77. &TypeInfo{Type: TypeBigInt},
  78. []byte("\x00\x00\x00\x00\x00\x00\x00\x00"),
  79. 0,
  80. },
  81. {
  82. &TypeInfo{Type: TypeBigInt},
  83. []byte("\x01\x02\x03\x04\x05\x06\x07\x08"),
  84. 72623859790382856,
  85. },
  86. {
  87. &TypeInfo{Type: TypeBigInt},
  88. []byte("\x80\x00\x00\x00\x00\x00\x00\x00"),
  89. int64(math.MinInt64),
  90. },
  91. {
  92. &TypeInfo{Type: TypeBigInt},
  93. []byte("\x7f\xff\xff\xff\xff\xff\xff\xff"),
  94. int64(math.MaxInt64),
  95. },
  96. {
  97. &TypeInfo{Type: TypeBoolean},
  98. []byte("\x00"),
  99. false,
  100. },
  101. {
  102. &TypeInfo{Type: TypeBoolean},
  103. []byte("\x01"),
  104. true,
  105. },
  106. {
  107. &TypeInfo{Type: TypeFloat},
  108. []byte("\x40\x49\x0f\xdb"),
  109. float32(3.14159265),
  110. },
  111. {
  112. &TypeInfo{Type: TypeDouble},
  113. []byte("\x40\x09\x21\xfb\x53\xc8\xd4\xf1"),
  114. float64(3.14159265),
  115. },
  116. {
  117. &TypeInfo{Type: TypeTimestamp},
  118. []byte("\x00\x00\x01\x40\x77\x16\xe1\xb8"),
  119. time.Date(2013, time.August, 13, 9, 52, 3, 0, time.UTC),
  120. },
  121. {
  122. &TypeInfo{Type: TypeTimestamp},
  123. []byte("\x00\x00\x01\x40\x77\x16\xe1\xb8"),
  124. int64(1376387523000),
  125. },
  126. {
  127. &TypeInfo{Type: TypeList, Elem: &TypeInfo{Type: TypeInt}},
  128. []byte("\x00\x02\x00\x04\x00\x00\x00\x01\x00\x04\x00\x00\x00\x02"),
  129. []int{1, 2},
  130. },
  131. {
  132. &TypeInfo{Type: TypeList, Elem: &TypeInfo{Type: TypeInt}},
  133. []byte("\x00\x02\x00\x04\x00\x00\x00\x01\x00\x04\x00\x00\x00\x02"),
  134. [2]int{1, 2},
  135. },
  136. {
  137. &TypeInfo{Type: TypeSet, Elem: &TypeInfo{Type: TypeInt}},
  138. []byte("\x00\x02\x00\x04\x00\x00\x00\x01\x00\x04\x00\x00\x00\x02"),
  139. []int{1, 2},
  140. },
  141. {
  142. &TypeInfo{Type: TypeSet, Elem: &TypeInfo{Type: TypeInt}},
  143. []byte(nil),
  144. []int(nil),
  145. },
  146. {
  147. &TypeInfo{Type: TypeMap,
  148. Key: &TypeInfo{Type: TypeVarchar},
  149. Elem: &TypeInfo{Type: TypeInt},
  150. },
  151. []byte("\x00\x01\x00\x03foo\x00\x04\x00\x00\x00\x01"),
  152. map[string]int{"foo": 1},
  153. },
  154. {
  155. &TypeInfo{Type: TypeMap,
  156. Key: &TypeInfo{Type: TypeVarchar},
  157. Elem: &TypeInfo{Type: TypeInt},
  158. },
  159. []byte(nil),
  160. map[string]int(nil),
  161. },
  162. {
  163. &TypeInfo{Type: TypeList, Elem: &TypeInfo{Type: TypeVarchar}},
  164. bytes.Join([][]byte{
  165. []byte("\x00\x01\xFF\xFF"),
  166. bytes.Repeat([]byte("X"), 65535)}, []byte("")),
  167. []string{strings.Repeat("X", 65535)},
  168. },
  169. {
  170. &TypeInfo{Type: TypeMap,
  171. Key: &TypeInfo{Type: TypeVarchar},
  172. Elem: &TypeInfo{Type: TypeVarchar},
  173. },
  174. bytes.Join([][]byte{
  175. []byte("\x00\x01\xFF\xFF"),
  176. bytes.Repeat([]byte("X"), 65535),
  177. []byte("\xFF\xFF"),
  178. bytes.Repeat([]byte("Y"), 65535)}, []byte("")),
  179. map[string]string{
  180. strings.Repeat("X", 65535): strings.Repeat("Y", 65535),
  181. },
  182. },
  183. }
  184. func TestMarshal(t *testing.T) {
  185. for i, test := range marshalTests {
  186. data, err := Marshal(test.Info, test.Value)
  187. if err != nil {
  188. t.Errorf("marshalTest[%d]: %v", i, err)
  189. continue
  190. }
  191. if !bytes.Equal(data, test.Data) {
  192. t.Errorf("marshalTest[%d]: expected %q, got %q.", i, test.Data, data)
  193. }
  194. }
  195. }
  196. func TestUnmarshal(t *testing.T) {
  197. for i, test := range marshalTests {
  198. v := reflect.New(reflect.TypeOf(test.Value))
  199. err := Unmarshal(test.Info, test.Data, v.Interface())
  200. if err != nil {
  201. t.Errorf("marshalTest[%d]: %v", i, err)
  202. continue
  203. }
  204. if !reflect.DeepEqual(v.Elem().Interface(), test.Value) {
  205. t.Errorf("marshalTest[%d]: expected %#v, got %#v.", i, test.Value, v.Elem().Interface())
  206. }
  207. }
  208. }
  209. type CustomString string
  210. func (c CustomString) MarshalCQL(info *TypeInfo) ([]byte, error) {
  211. return []byte(strings.ToUpper(string(c))), nil
  212. }
  213. func (c *CustomString) UnmarshalCQL(info *TypeInfo, data []byte) error {
  214. *c = CustomString(strings.ToLower(string(data)))
  215. return nil
  216. }
  217. type MyString string
  218. type MyInt int