You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

423 lines
9.6 KiB

  1. package binary
  2. import (
  3. "bytes"
  4. "fmt"
  5. "reflect"
  6. "testing"
  7. "time"
  8. )
  9. type SimpleStruct struct {
  10. String string
  11. Bytes []byte
  12. Time time.Time
  13. }
  14. //-------------------------------------
  15. type Animal interface{}
  16. const (
  17. AnimalTypeCat = byte(0x01)
  18. AnimalTypeDog = byte(0x02)
  19. AnimalTypeSnake = byte(0x03)
  20. AnimalTypeViper = byte(0x04)
  21. )
  22. // Implements Animal
  23. type Cat struct {
  24. SimpleStruct
  25. }
  26. func (cat Cat) TypeByte() byte { return AnimalTypeCat }
  27. // Implements Animal
  28. type Dog struct {
  29. SimpleStruct
  30. }
  31. func (dog Dog) TypeByte() byte { return AnimalTypeDog }
  32. // Implements Animal
  33. type Snake []byte
  34. func (snake Snake) TypeByte() byte { return AnimalTypeSnake }
  35. // Implements Animal
  36. type Viper struct {
  37. Bytes []byte
  38. }
  39. func (viper *Viper) TypeByte() byte { return AnimalTypeViper }
  40. var _ = RegisterInterface(
  41. struct{ Animal }{},
  42. ConcreteType{Cat{}},
  43. ConcreteType{Dog{}},
  44. ConcreteType{Snake{}},
  45. ConcreteType{&Viper{}},
  46. )
  47. func TestAnimalInterface(t *testing.T) {
  48. var foo Animal
  49. // Type of pointer to Animal
  50. rt := reflect.TypeOf(&foo)
  51. fmt.Printf("rt: %v\n", rt)
  52. // Type of Animal itself.
  53. // NOTE: normally this is acquired through other means
  54. // like introspecting on method signatures, or struct fields.
  55. rte := rt.Elem()
  56. fmt.Printf("rte: %v\n", rte)
  57. // Get a new pointer to the interface
  58. // NOTE: calling .Interface() is to get the actual value,
  59. // instead of reflection values.
  60. ptr := reflect.New(rte).Interface()
  61. fmt.Printf("ptr: %v", ptr)
  62. // Make a binary byteslice that represents a snake.
  63. snakeBytes := BinaryBytes(Snake([]byte("snake")))
  64. snakeReader := bytes.NewReader(snakeBytes)
  65. // Now you can read it.
  66. n, err := new(int64), new(error)
  67. it := *ReadBinary(ptr, snakeReader, n, err).(*Animal)
  68. fmt.Println(it, reflect.TypeOf(it))
  69. }
  70. //-------------------------------------
  71. type Constructor func() interface{}
  72. type Instantiator func() (o interface{}, ptr interface{})
  73. type Validator func(o interface{}, t *testing.T)
  74. type TestCase struct {
  75. Constructor
  76. Instantiator
  77. Validator
  78. }
  79. //-------------------------------------
  80. func constructBasic() interface{} {
  81. cat := Cat{
  82. SimpleStruct{
  83. String: "String",
  84. Bytes: []byte("Bytes"),
  85. Time: time.Unix(123, 0),
  86. },
  87. }
  88. return cat
  89. }
  90. func instantiateBasic() (interface{}, interface{}) {
  91. return Cat{}, &Cat{}
  92. }
  93. func validateBasic(o interface{}, t *testing.T) {
  94. cat := o.(Cat)
  95. if cat.String != "String" {
  96. t.Errorf("Expected cat2.String == 'String', got %v", cat.String)
  97. }
  98. if string(cat.Bytes) != "Bytes" {
  99. t.Errorf("Expected cat2.Bytes == 'Bytes', got %X", cat.Bytes)
  100. }
  101. if cat.Time.Unix() != 123 {
  102. t.Errorf("Expected cat2.Time == 'Unix(123)', got %v", cat.Time)
  103. }
  104. }
  105. //-------------------------------------
  106. type ComplexStruct struct {
  107. Name string
  108. Animal Animal
  109. }
  110. func constructComplex() interface{} {
  111. c := ComplexStruct{
  112. Name: "Complex",
  113. Animal: constructBasic(),
  114. }
  115. return c
  116. }
  117. func instantiateComplex() (interface{}, interface{}) {
  118. return ComplexStruct{}, &ComplexStruct{}
  119. }
  120. func validateComplex(o interface{}, t *testing.T) {
  121. c2 := o.(ComplexStruct)
  122. if cat, ok := c2.Animal.(Cat); ok {
  123. validateBasic(cat, t)
  124. } else {
  125. t.Errorf("Expected c2.Animal to be of type cat, got %v", reflect.ValueOf(c2.Animal).Elem().Type())
  126. }
  127. }
  128. //-------------------------------------
  129. type ComplexStruct2 struct {
  130. Cat Cat
  131. Dog *Dog
  132. Snake Snake
  133. Snake2 *Snake
  134. Viper Viper
  135. Viper2 *Viper
  136. }
  137. func constructComplex2() interface{} {
  138. snake_ := Snake([]byte("hiss"))
  139. snakePtr_ := &snake_
  140. c := ComplexStruct2{
  141. Cat: Cat{
  142. SimpleStruct{
  143. String: "String",
  144. Bytes: []byte("Bytes"),
  145. },
  146. },
  147. Dog: &Dog{
  148. SimpleStruct{
  149. String: "Woof",
  150. Bytes: []byte("Bark"),
  151. },
  152. },
  153. Snake: Snake([]byte("hiss")),
  154. Snake2: snakePtr_,
  155. Viper: Viper{Bytes: []byte("hizz")},
  156. Viper2: &Viper{Bytes: []byte("hizz")},
  157. }
  158. return c
  159. }
  160. func instantiateComplex2() (interface{}, interface{}) {
  161. return ComplexStruct2{}, &ComplexStruct2{}
  162. }
  163. func validateComplex2(o interface{}, t *testing.T) {
  164. c2 := o.(ComplexStruct2)
  165. cat := c2.Cat
  166. if cat.String != "String" {
  167. t.Errorf("Expected cat.String == 'String', got %v", cat.String)
  168. }
  169. if string(cat.Bytes) != "Bytes" {
  170. t.Errorf("Expected cat.Bytes == 'Bytes', got %X", cat.Bytes)
  171. }
  172. dog := c2.Dog
  173. if dog.String != "Woof" {
  174. t.Errorf("Expected dog.String == 'Woof', got %v", dog.String)
  175. }
  176. if string(dog.Bytes) != "Bark" {
  177. t.Errorf("Expected dog.Bytes == 'Bark', got %X", dog.Bytes)
  178. }
  179. snake := c2.Snake
  180. if string(snake) != "hiss" {
  181. t.Errorf("Expected string(snake) == 'hiss', got %v", string(snake))
  182. }
  183. snake2 := c2.Snake2
  184. if string(*snake2) != "hiss" {
  185. t.Errorf("Expected string(snake2) == 'hiss', got %v", string(*snake2))
  186. }
  187. viper := c2.Viper
  188. if string(viper.Bytes) != "hizz" {
  189. t.Errorf("Expected string(viper.Bytes) == 'hizz', got %v", string(viper.Bytes))
  190. }
  191. viper2 := c2.Viper2
  192. if string(viper2.Bytes) != "hizz" {
  193. t.Errorf("Expected string(viper2.Bytes) == 'hizz', got %v", string(viper2.Bytes))
  194. }
  195. }
  196. //-------------------------------------
  197. type ComplexStructArray struct {
  198. Animals []Animal
  199. }
  200. func constructComplexArray() interface{} {
  201. c := ComplexStructArray{
  202. Animals: []Animal{
  203. Cat{
  204. SimpleStruct{
  205. String: "String",
  206. Bytes: []byte("Bytes"),
  207. },
  208. },
  209. &Dog{ // Even though it's a *Dog, we'll get a Dog{} back.
  210. SimpleStruct{
  211. String: "Woof",
  212. Bytes: []byte("Bark"),
  213. },
  214. },
  215. Snake([]byte("hiss")),
  216. &Viper{
  217. Bytes: []byte("hizz"),
  218. },
  219. },
  220. }
  221. return c
  222. }
  223. func instantiateComplexArray() (interface{}, interface{}) {
  224. return ComplexStructArray{}, &ComplexStructArray{}
  225. }
  226. func validateComplexArray(o interface{}, t *testing.T) {
  227. c2 := o.(ComplexStructArray)
  228. if cat, ok := c2.Animals[0].(Cat); ok {
  229. if cat.String != "String" {
  230. t.Errorf("Expected cat.String == 'String', got %v", cat.String)
  231. }
  232. if string(cat.Bytes) != "Bytes" {
  233. t.Errorf("Expected cat.Bytes == 'Bytes', got %X", cat.Bytes)
  234. }
  235. } else {
  236. t.Errorf("Expected c2.Animals[0] to be of type cat, got %v", reflect.ValueOf(c2.Animals[0]).Elem().Type())
  237. }
  238. if dog, ok := c2.Animals[1].(Dog); ok {
  239. if dog.String != "Woof" {
  240. t.Errorf("Expected dog.String == 'Woof', got %v", dog.String)
  241. }
  242. if string(dog.Bytes) != "Bark" {
  243. t.Errorf("Expected dog.Bytes == 'Bark', got %X", dog.Bytes)
  244. }
  245. } else {
  246. t.Errorf("Expected c2.Animals[1] to be of type dog, got %v", reflect.ValueOf(c2.Animals[1]).Elem().Type())
  247. }
  248. if snake, ok := c2.Animals[2].(Snake); ok {
  249. if string(snake) != "hiss" {
  250. t.Errorf("Expected string(snake) == 'hiss', got %v", string(snake))
  251. }
  252. } else {
  253. t.Errorf("Expected c2.Animals[2] to be of type Snake, got %v", reflect.ValueOf(c2.Animals[2]).Elem().Type())
  254. }
  255. if viper, ok := c2.Animals[3].(*Viper); ok {
  256. if string(viper.Bytes) != "hizz" {
  257. t.Errorf("Expected string(viper.Bytes) == 'hizz', got %v", string(viper.Bytes))
  258. }
  259. } else {
  260. t.Errorf("Expected c2.Animals[3] to be of type *Viper, got %v", reflect.ValueOf(c2.Animals[3]).Elem().Type())
  261. }
  262. }
  263. //-----------------------------------------------------------------------------
  264. var testCases = []TestCase{}
  265. func init() {
  266. testCases = append(testCases, TestCase{constructBasic, instantiateBasic, validateBasic})
  267. testCases = append(testCases, TestCase{constructComplex, instantiateComplex, validateComplex})
  268. testCases = append(testCases, TestCase{constructComplex2, instantiateComplex2, validateComplex2})
  269. testCases = append(testCases, TestCase{constructComplexArray, instantiateComplexArray, validateComplexArray})
  270. }
  271. func TestBinary(t *testing.T) {
  272. for _, testCase := range testCases {
  273. // Construct an object
  274. o := testCase.Constructor()
  275. // Write the object
  276. data := BinaryBytes(o)
  277. t.Logf("Binary: %X", data)
  278. instance, instancePtr := testCase.Instantiator()
  279. // Read onto a struct
  280. n, err := new(int64), new(error)
  281. res := ReadBinary(instance, bytes.NewReader(data), n, err)
  282. if *err != nil {
  283. t.Fatalf("Failed to read cat: %v", *err)
  284. }
  285. // Validate object
  286. testCase.Validator(res, t)
  287. // Read onto a pointer
  288. n, err = new(int64), new(error)
  289. res = ReadBinary(instancePtr, bytes.NewReader(data), n, err)
  290. if *err != nil {
  291. t.Fatalf("Failed to read cat: %v", *err)
  292. }
  293. if res != instancePtr {
  294. t.Errorf("Expected pointer to pass through")
  295. }
  296. // Validate object
  297. testCase.Validator(reflect.ValueOf(res).Elem().Interface(), t)
  298. }
  299. }
  300. func TestJSON(t *testing.T) {
  301. for _, testCase := range testCases {
  302. // Construct an object
  303. o := testCase.Constructor()
  304. // Write the object
  305. data := JSONBytes(o)
  306. t.Logf("JSON: %v", string(data))
  307. instance, instancePtr := testCase.Instantiator()
  308. // Read onto a struct
  309. err := new(error)
  310. res := ReadJSON(instance, data, err)
  311. if *err != nil {
  312. t.Fatalf("Failed to read cat: %v", *err)
  313. }
  314. // Validate object
  315. testCase.Validator(res, t)
  316. // Read onto a pointer
  317. res = ReadJSON(instancePtr, data, err)
  318. if *err != nil {
  319. t.Fatalf("Failed to read cat: %v", *err)
  320. }
  321. if res != instancePtr {
  322. t.Errorf("Expected pointer to pass through")
  323. }
  324. // Validate object
  325. testCase.Validator(reflect.ValueOf(res).Elem().Interface(), t)
  326. }
  327. }
  328. //------------------------------------------------------------------------------
  329. type Foo struct {
  330. FieldA string `json:"fieldA"` // json field name is "fieldA"
  331. FieldB string // json field name is "FieldB"
  332. fieldC string // not exported, not serialized.
  333. }
  334. func TestJSONFieldNames(t *testing.T) {
  335. for i := 0; i < 20; i++ { // Try to ensure deterministic success.
  336. foo := Foo{"a", "b", "c"}
  337. stringified := string(JSONBytes(foo))
  338. expected := `{"fieldA":"a","FieldB":"b"}`
  339. if stringified != expected {
  340. t.Fatalf("JSONFieldNames error: expected %v, got %v",
  341. expected, stringified)
  342. }
  343. }
  344. }