encode_test.go 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. package wire
  2. import (
  3. "bytes"
  4. "io"
  5. "testing"
  6. "github.com/stretchr/testify/assert"
  7. )
  8. // errWriter is a writer that always returns an error.
  9. type errWriter struct{}
  10. func (errWriter) Write(p []byte) (n int, err error) {
  11. return 0, io.EOF
  12. }
  13. func TestMarshal(t *testing.T) {
  14. tests := []struct {
  15. name string
  16. w io.Writer
  17. given any
  18. want []byte
  19. wantErr error
  20. }{
  21. {
  22. name: "marshal uint8",
  23. w: &bytes.Buffer{},
  24. given: struct {
  25. Val uint8
  26. }{
  27. Val: 100,
  28. },
  29. want: []byte{0x64},
  30. },
  31. {
  32. name: "marshal uint16",
  33. w: &bytes.Buffer{},
  34. given: struct {
  35. Val uint16
  36. }{
  37. Val: 100,
  38. },
  39. want: []byte{0x0, 0x64},
  40. },
  41. {
  42. name: "marshal uint32",
  43. w: &bytes.Buffer{},
  44. given: struct {
  45. Val uint32
  46. }{
  47. Val: 100,
  48. },
  49. want: []byte{0x0, 0x0, 0x0, 0x64},
  50. },
  51. {
  52. name: "marshal uint64",
  53. w: &bytes.Buffer{},
  54. given: struct {
  55. Val uint64
  56. }{
  57. Val: 100,
  58. },
  59. want: []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x64},
  60. },
  61. {
  62. name: "unsupported type",
  63. w: &bytes.Buffer{},
  64. given: struct {
  65. Val int16
  66. }{
  67. Val: 100,
  68. },
  69. wantErr: ErrMarshalFailure,
  70. },
  71. {
  72. name: "string8",
  73. w: &bytes.Buffer{},
  74. given: struct {
  75. Val string `len_prefix:"uint8"`
  76. }{
  77. Val: "test-value",
  78. },
  79. want: append(
  80. []byte{0xa}, /* len prefix */
  81. []byte{0x74, 0x65, 0x73, 0x74, 0x2d, 0x76, 0x61, 0x6c, 0x75, 0x65}...), /* str val */
  82. },
  83. {
  84. name: "string8 write error",
  85. w: errWriter{},
  86. given: struct {
  87. Val string `len_prefix:"uint8"`
  88. }{
  89. Val: "test-value",
  90. },
  91. wantErr: io.EOF,
  92. },
  93. {
  94. name: "string16",
  95. w: &bytes.Buffer{},
  96. given: struct {
  97. Val string `len_prefix:"uint16"`
  98. }{
  99. Val: "test-value",
  100. },
  101. want: append(
  102. []byte{0x0, 0xa}, /* len prefix */
  103. []byte{0x74, 0x65, 0x73, 0x74, 0x2d, 0x76, 0x61, 0x6c, 0x75, 0x65}...), /* str val */
  104. },
  105. {
  106. name: "string16 write error",
  107. w: errWriter{},
  108. given: struct {
  109. Val string `len_prefix:"uint16"`
  110. }{
  111. Val: "test-value",
  112. },
  113. wantErr: io.EOF,
  114. },
  115. {
  116. name: "string with unknown prefix type",
  117. w: &bytes.Buffer{},
  118. given: struct {
  119. Val string `len_prefix:"uint128"`
  120. }{
  121. Val: "test-value",
  122. },
  123. wantErr: ErrMarshalFailure,
  124. },
  125. {
  126. name: "byte slice with no prefix",
  127. w: &bytes.Buffer{},
  128. given: struct {
  129. Val []byte
  130. }{
  131. Val: []byte(`hello`),
  132. },
  133. want: []byte{0x68, 0x65, 0x6c, 0x6c, 0x6f},
  134. },
  135. {
  136. name: "byte slice with no prefix with write error",
  137. w: &bytes.Buffer{},
  138. given: struct {
  139. Val []int
  140. }{
  141. Val: []int{1, 2, 3, 4},
  142. },
  143. wantErr: ErrMarshalFailure,
  144. },
  145. {
  146. name: "byte slice with no prefix with write error",
  147. w: errWriter{},
  148. given: struct {
  149. Val []byte
  150. }{
  151. Val: []byte(`hello`),
  152. },
  153. wantErr: io.EOF,
  154. },
  155. {
  156. name: "empty byte slice",
  157. w: &bytes.Buffer{},
  158. given: struct {
  159. Val []byte
  160. }{
  161. Val: []byte{},
  162. },
  163. want: []byte(nil),
  164. },
  165. {
  166. name: "byte slice with uint8 len_prefix",
  167. w: &bytes.Buffer{},
  168. given: struct {
  169. Val []byte `len_prefix:"uint8"`
  170. }{
  171. Val: []byte(`hello`),
  172. },
  173. want: append(
  174. []byte{0x05}, /* len prefix */
  175. []byte{0x68, 0x65, 0x6c, 0x6c, 0x6f}...), /* slice val */
  176. },
  177. {
  178. name: "byte slice with uint8 len_prefix with error",
  179. w: errWriter{},
  180. given: struct {
  181. Val []byte `len_prefix:"uint8"`
  182. }{
  183. Val: []byte(`hello`),
  184. },
  185. wantErr: io.EOF,
  186. },
  187. {
  188. name: "byte slice with uint16 len_prefix",
  189. w: &bytes.Buffer{},
  190. given: struct {
  191. Val []byte `len_prefix:"uint16"`
  192. }{
  193. Val: []byte(`hello`),
  194. },
  195. want: append(
  196. []byte{0x00, 0x05}, /* len prefix */
  197. []byte{0x68, 0x65, 0x6c, 0x6c, 0x6f}...), /* slice val */
  198. },
  199. {
  200. name: "byte slice with uint16 len_prefix with error",
  201. w: errWriter{},
  202. given: struct {
  203. Val []byte `len_prefix:"uint16"`
  204. }{
  205. Val: []byte(`hello`),
  206. },
  207. wantErr: io.EOF,
  208. },
  209. {
  210. name: "empty struct slice",
  211. w: &bytes.Buffer{},
  212. given: struct {
  213. Val []TLV
  214. }{
  215. Val: []TLV{},
  216. },
  217. want: []byte(nil),
  218. },
  219. {
  220. name: "struct slice with invalid type in struct",
  221. w: &bytes.Buffer{},
  222. given: struct {
  223. Val []struct {
  224. Val int16
  225. }
  226. }{
  227. Val: []struct {
  228. Val int16
  229. }{
  230. {
  231. Val: 1234,
  232. },
  233. },
  234. },
  235. wantErr: ErrMarshalFailure,
  236. },
  237. {
  238. name: "struct slice with uint8 count_prefix",
  239. w: &bytes.Buffer{},
  240. given: struct {
  241. Val []TLV `count_prefix:"uint8"`
  242. }{
  243. Val: []TLV{
  244. NewTLV(10, uint16(1234)),
  245. NewTLV(20, uint16(1234)),
  246. },
  247. },
  248. want: append(
  249. []byte{0x02}, /* count prefix */
  250. []byte{0x0, 0xa, 0x0, 0x2, 0x4, 0xd2, 0x0, 0x14, 0x0, 0x2, 0x4, 0xd2}...), /* slice val */
  251. },
  252. {
  253. name: "struct slice with uint8 count_prefix with error",
  254. w: errWriter{},
  255. given: struct {
  256. Val []TLV `count_prefix:"uint8"`
  257. }{
  258. Val: []TLV{
  259. NewTLV(10, uint16(1234)),
  260. },
  261. },
  262. wantErr: io.EOF,
  263. },
  264. {
  265. name: "struct slice with uint16 count_prefix",
  266. w: &bytes.Buffer{},
  267. given: struct {
  268. Val []TLV `count_prefix:"uint16"`
  269. }{
  270. Val: []TLV{
  271. NewTLV(10, uint16(1234)),
  272. NewTLV(20, uint16(1234)),
  273. },
  274. },
  275. want: append(
  276. []byte{0x00, 0x02}, /* count prefix */
  277. []byte{0x0, 0xa, 0x0, 0x2, 0x4, 0xd2, 0x0, 0x14, 0x0, 0x2, 0x4, 0xd2}...), /* slice val */
  278. },
  279. {
  280. name: "struct slice with uint16 count_prefix with error",
  281. w: errWriter{},
  282. given: struct {
  283. Val []TLV `count_prefix:"uint16"`
  284. }{
  285. Val: []TLV{
  286. NewTLV(10, uint16(1234)),
  287. },
  288. },
  289. wantErr: io.EOF,
  290. },
  291. {
  292. name: "byte slice with uint16 len_prefix and uint16 count_prefix",
  293. w: &bytes.Buffer{},
  294. given: struct {
  295. Val []byte `len_prefix:"uint16" count_prefix:"uint16"`
  296. }{
  297. Val: []byte(`hello`),
  298. },
  299. wantErr: ErrMarshalFailure,
  300. },
  301. {
  302. name: "byte slice with unknown len_prefix type",
  303. w: &bytes.Buffer{},
  304. given: struct {
  305. Val []byte `len_prefix:"uint128"`
  306. }{
  307. Val: []byte(`hello`),
  308. },
  309. wantErr: ErrMarshalFailure,
  310. },
  311. {
  312. name: "byte slice with unknown count_prefix type",
  313. w: &bytes.Buffer{},
  314. given: struct {
  315. Val []byte `count_prefix:"uint128"`
  316. }{
  317. Val: []byte(`hello`),
  318. },
  319. wantErr: ErrMarshalFailure,
  320. },
  321. {
  322. name: "empty snac",
  323. w: &bytes.Buffer{},
  324. given: nil,
  325. wantErr: ErrMarshalFailureNilSNAC,
  326. },
  327. }
  328. for _, tt := range tests {
  329. t.Run(tt.name, func(t *testing.T) {
  330. err := Marshal(tt.given, tt.w)
  331. assert.ErrorIs(t, err, tt.wantErr)
  332. if tt.wantErr == nil {
  333. if w, ok := tt.w.(*bytes.Buffer); ok {
  334. assert.Equal(t, tt.want, w.Bytes())
  335. }
  336. }
  337. })
  338. }
  339. }