json_test.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. // Copyright 2016 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. package hexutil
  17. import (
  18. "bytes"
  19. "encoding/hex"
  20. "math/big"
  21. "testing"
  22. )
  23. func checkError(t *testing.T, input string, got, want error) bool {
  24. if got == nil {
  25. if want != nil {
  26. t.Errorf("input %s: got no error, want %q", input, want)
  27. return false
  28. }
  29. return true
  30. }
  31. if want == nil {
  32. t.Errorf("input %s: unexpected error %q", input, got)
  33. } else if got.Error() != want.Error() {
  34. t.Errorf("input %s: got error %q, want %q", input, got, want)
  35. }
  36. return false
  37. }
  38. func referenceBig(s string) *big.Int {
  39. b, ok := new(big.Int).SetString(s, 16)
  40. if !ok {
  41. panic("invalid")
  42. }
  43. return b
  44. }
  45. func referenceBytes(s string) []byte {
  46. b, err := hex.DecodeString(s)
  47. if err != nil {
  48. panic(err)
  49. }
  50. return b
  51. }
  52. var unmarshalBytesTests = []unmarshalTest{
  53. // invalid encoding
  54. {input: "", wantErr: errNonString},
  55. {input: "null", wantErr: errNonString},
  56. {input: "10", wantErr: errNonString},
  57. {input: `""`, wantErr: ErrEmptyString},
  58. {input: `"0"`, wantErr: ErrMissingPrefix},
  59. {input: `"0x0"`, wantErr: ErrOddLength},
  60. {input: `"0xxx"`, wantErr: ErrSyntax},
  61. {input: `"0x01zz01"`, wantErr: ErrSyntax},
  62. // valid encoding
  63. {input: `"0x"`, want: referenceBytes("")},
  64. {input: `"0x02"`, want: referenceBytes("02")},
  65. {input: `"0X02"`, want: referenceBytes("02")},
  66. {input: `"0xffffffffff"`, want: referenceBytes("ffffffffff")},
  67. {
  68. input: `"0xffffffffffffffffffffffffffffffffffff"`,
  69. want: referenceBytes("ffffffffffffffffffffffffffffffffffff"),
  70. },
  71. }
  72. func TestUnmarshalBytes(t *testing.T) {
  73. for _, test := range unmarshalBytesTests {
  74. var v Bytes
  75. err := v.UnmarshalJSON([]byte(test.input))
  76. if !checkError(t, test.input, err, test.wantErr) {
  77. continue
  78. }
  79. if !bytes.Equal(test.want.([]byte), []byte(v)) {
  80. t.Errorf("input %s: value mismatch: got %x, want %x", test.input, &v, test.want)
  81. continue
  82. }
  83. }
  84. }
  85. func BenchmarkUnmarshalBytes(b *testing.B) {
  86. input := []byte(`"0x123456789abcdef123456789abcdef"`)
  87. for i := 0; i < b.N; i++ {
  88. var v Bytes
  89. if err := v.UnmarshalJSON(input); err != nil {
  90. b.Fatal(err)
  91. }
  92. }
  93. }
  94. func TestMarshalBytes(t *testing.T) {
  95. for _, test := range encodeBytesTests {
  96. in := test.input.([]byte)
  97. out, err := Bytes(in).MarshalJSON()
  98. if err != nil {
  99. t.Errorf("%x: %v", in, err)
  100. continue
  101. }
  102. if want := `"` + test.want + `"`; string(out) != want {
  103. t.Errorf("%x: MarshalJSON output mismatch: got %q, want %q", in, out, want)
  104. continue
  105. }
  106. if out := Bytes(in).String(); out != test.want {
  107. t.Errorf("%x: String mismatch: got %q, want %q", in, out, test.want)
  108. continue
  109. }
  110. }
  111. }
  112. var unmarshalBigTests = []unmarshalTest{
  113. // invalid encoding
  114. {input: "", wantErr: errNonString},
  115. {input: "null", wantErr: errNonString},
  116. {input: "10", wantErr: errNonString},
  117. {input: `""`, wantErr: ErrEmptyString},
  118. {input: `"0"`, wantErr: ErrMissingPrefix},
  119. {input: `"0x"`, wantErr: ErrEmptyNumber},
  120. {input: `"0x01"`, wantErr: ErrLeadingZero},
  121. {input: `"0xx"`, wantErr: ErrSyntax},
  122. {input: `"0x1zz01"`, wantErr: ErrSyntax},
  123. // valid encoding
  124. {input: `"0x0"`, want: big.NewInt(0)},
  125. {input: `"0x2"`, want: big.NewInt(0x2)},
  126. {input: `"0x2F2"`, want: big.NewInt(0x2f2)},
  127. {input: `"0X2F2"`, want: big.NewInt(0x2f2)},
  128. {input: `"0x1122aaff"`, want: big.NewInt(0x1122aaff)},
  129. {input: `"0xbBb"`, want: big.NewInt(0xbbb)},
  130. {input: `"0xfffffffff"`, want: big.NewInt(0xfffffffff)},
  131. {
  132. input: `"0x112233445566778899aabbccddeeff"`,
  133. want: referenceBig("112233445566778899aabbccddeeff"),
  134. },
  135. {
  136. input: `"0xffffffffffffffffffffffffffffffffffff"`,
  137. want: referenceBig("ffffffffffffffffffffffffffffffffffff"),
  138. },
  139. }
  140. func TestUnmarshalBig(t *testing.T) {
  141. for _, test := range unmarshalBigTests {
  142. var v Big
  143. err := v.UnmarshalJSON([]byte(test.input))
  144. if !checkError(t, test.input, err, test.wantErr) {
  145. continue
  146. }
  147. if test.want != nil && test.want.(*big.Int).Cmp((*big.Int)(&v)) != 0 {
  148. t.Errorf("input %s: value mismatch: got %x, want %x", test.input, (*big.Int)(&v), test.want)
  149. continue
  150. }
  151. }
  152. }
  153. func BenchmarkUnmarshalBig(b *testing.B) {
  154. input := []byte(`"0x123456789abcdef123456789abcdef"`)
  155. for i := 0; i < b.N; i++ {
  156. var v Big
  157. if err := v.UnmarshalJSON(input); err != nil {
  158. b.Fatal(err)
  159. }
  160. }
  161. }
  162. func TestMarshalBig(t *testing.T) {
  163. for _, test := range encodeBigTests {
  164. in := test.input.(*big.Int)
  165. out, err := (*Big)(in).MarshalJSON()
  166. if err != nil {
  167. t.Errorf("%d: %v", in, err)
  168. continue
  169. }
  170. if want := `"` + test.want + `"`; string(out) != want {
  171. t.Errorf("%d: MarshalJSON output mismatch: got %q, want %q", in, out, want)
  172. continue
  173. }
  174. if out := (*Big)(in).String(); out != test.want {
  175. t.Errorf("%x: String mismatch: got %q, want %q", in, out, test.want)
  176. continue
  177. }
  178. }
  179. }
  180. var unmarshalUint64Tests = []unmarshalTest{
  181. // invalid encoding
  182. {input: "", wantErr: errNonString},
  183. {input: "null", wantErr: errNonString},
  184. {input: "10", wantErr: errNonString},
  185. {input: `""`, wantErr: ErrEmptyString},
  186. {input: `"0"`, wantErr: ErrMissingPrefix},
  187. {input: `"0x"`, wantErr: ErrEmptyNumber},
  188. {input: `"0x01"`, wantErr: ErrLeadingZero},
  189. {input: `"0xfffffffffffffffff"`, wantErr: ErrUint64Range},
  190. {input: `"0xx"`, wantErr: ErrSyntax},
  191. {input: `"0x1zz01"`, wantErr: ErrSyntax},
  192. // valid encoding
  193. {input: `"0x0"`, want: uint64(0)},
  194. {input: `"0x2"`, want: uint64(0x2)},
  195. {input: `"0x2F2"`, want: uint64(0x2f2)},
  196. {input: `"0X2F2"`, want: uint64(0x2f2)},
  197. {input: `"0x1122aaff"`, want: uint64(0x1122aaff)},
  198. {input: `"0xbbb"`, want: uint64(0xbbb)},
  199. {input: `"0xffffffffffffffff"`, want: uint64(0xffffffffffffffff)},
  200. }
  201. func TestUnmarshalUint64(t *testing.T) {
  202. for _, test := range unmarshalUint64Tests {
  203. var v Uint64
  204. err := v.UnmarshalJSON([]byte(test.input))
  205. if !checkError(t, test.input, err, test.wantErr) {
  206. continue
  207. }
  208. if uint64(v) != test.want.(uint64) {
  209. t.Errorf("input %s: value mismatch: got %d, want %d", test.input, v, test.want)
  210. continue
  211. }
  212. }
  213. }
  214. func BenchmarkUnmarshalUint64(b *testing.B) {
  215. input := []byte(`"0x123456789abcdf"`)
  216. for i := 0; i < b.N; i++ {
  217. var v Uint64
  218. v.UnmarshalJSON(input)
  219. }
  220. }
  221. func TestMarshalUint64(t *testing.T) {
  222. for _, test := range encodeUint64Tests {
  223. in := test.input.(uint64)
  224. out, err := Uint64(in).MarshalJSON()
  225. if err != nil {
  226. t.Errorf("%d: %v", in, err)
  227. continue
  228. }
  229. if want := `"` + test.want + `"`; string(out) != want {
  230. t.Errorf("%d: MarshalJSON output mismatch: got %q, want %q", in, out, want)
  231. continue
  232. }
  233. if out := (Uint64)(in).String(); out != test.want {
  234. t.Errorf("%x: String mismatch: got %q, want %q", in, out, test.want)
  235. continue
  236. }
  237. }
  238. }