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.

373 lines
8.1 KiB

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