github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/common/hexutil/json_test.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 12:09:32</date>
    10  //</624342609304752128>
    11  
    12  
    13  package hexutil
    14  
    15  import (
    16  	"bytes"
    17  	"encoding/hex"
    18  	"encoding/json"
    19  	"errors"
    20  	"math/big"
    21  	"testing"
    22  )
    23  
    24  func checkError(t *testing.T, input string, got, want error) bool {
    25  	if got == nil {
    26  		if want != nil {
    27  			t.Errorf("input %s: got no error, want %q", input, want)
    28  			return false
    29  		}
    30  		return true
    31  	}
    32  	if want == nil {
    33  		t.Errorf("input %s: unexpected error %q", input, got)
    34  	} else if got.Error() != want.Error() {
    35  		t.Errorf("input %s: got error %q, want %q", input, got, want)
    36  	}
    37  	return false
    38  }
    39  
    40  func referenceBig(s string) *big.Int {
    41  	b, ok := new(big.Int).SetString(s, 16)
    42  	if !ok {
    43  		panic("invalid")
    44  	}
    45  	return b
    46  }
    47  
    48  func referenceBytes(s string) []byte {
    49  	b, err := hex.DecodeString(s)
    50  	if err != nil {
    51  		panic(err)
    52  	}
    53  	return b
    54  }
    55  
    56  var errJSONEOF = errors.New("unexpected end of JSON input")
    57  
    58  var unmarshalBytesTests = []unmarshalTest{
    59  //无效的编码
    60  	{input: "", wantErr: errJSONEOF},
    61  	{input: "null", wantErr: errNonString(bytesT)},
    62  	{input: "10", wantErr: errNonString(bytesT)},
    63  	{input: `"0"`, wantErr: wrapTypeError(ErrMissingPrefix, bytesT)},
    64  	{input: `"0x0"`, wantErr: wrapTypeError(ErrOddLength, bytesT)},
    65  	{input: `"0xxx"`, wantErr: wrapTypeError(ErrSyntax, bytesT)},
    66  	{input: `"0x01zz01"`, wantErr: wrapTypeError(ErrSyntax, bytesT)},
    67  
    68  //有效编码
    69  	{input: `""`, want: referenceBytes("")},
    70  	{input: `"0x"`, want: referenceBytes("")},
    71  	{input: `"0x02"`, want: referenceBytes("02")},
    72  	{input: `"0X02"`, want: referenceBytes("02")},
    73  	{input: `"0xffffffffff"`, want: referenceBytes("ffffffffff")},
    74  	{
    75  		input: `"0xffffffffffffffffffffffffffffffffffff"`,
    76  		want:  referenceBytes("ffffffffffffffffffffffffffffffffffff"),
    77  	},
    78  }
    79  
    80  func TestUnmarshalBytes(t *testing.T) {
    81  	for _, test := range unmarshalBytesTests {
    82  		var v Bytes
    83  		err := json.Unmarshal([]byte(test.input), &v)
    84  		if !checkError(t, test.input, err, test.wantErr) {
    85  			continue
    86  		}
    87  		if !bytes.Equal(test.want.([]byte), []byte(v)) {
    88  			t.Errorf("input %s: value mismatch: got %x, want %x", test.input, &v, test.want)
    89  			continue
    90  		}
    91  	}
    92  }
    93  
    94  func BenchmarkUnmarshalBytes(b *testing.B) {
    95  	input := []byte(`"0x123456789abcdef123456789abcdef"`)
    96  	for i := 0; i < b.N; i++ {
    97  		var v Bytes
    98  		if err := v.UnmarshalJSON(input); err != nil {
    99  			b.Fatal(err)
   100  		}
   101  	}
   102  }
   103  
   104  func TestMarshalBytes(t *testing.T) {
   105  	for _, test := range encodeBytesTests {
   106  		in := test.input.([]byte)
   107  		out, err := json.Marshal(Bytes(in))
   108  		if err != nil {
   109  			t.Errorf("%x: %v", in, err)
   110  			continue
   111  		}
   112  		if want := `"` + test.want + `"`; string(out) != want {
   113  			t.Errorf("%x: MarshalJSON output mismatch: got %q, want %q", in, out, want)
   114  			continue
   115  		}
   116  		if out := Bytes(in).String(); out != test.want {
   117  			t.Errorf("%x: String mismatch: got %q, want %q", in, out, test.want)
   118  			continue
   119  		}
   120  	}
   121  }
   122  
   123  var unmarshalBigTests = []unmarshalTest{
   124  //无效的编码
   125  	{input: "", wantErr: errJSONEOF},
   126  	{input: "null", wantErr: errNonString(bigT)},
   127  	{input: "10", wantErr: errNonString(bigT)},
   128  	{input: `"0"`, wantErr: wrapTypeError(ErrMissingPrefix, bigT)},
   129  	{input: `"0x"`, wantErr: wrapTypeError(ErrEmptyNumber, bigT)},
   130  	{input: `"0x01"`, wantErr: wrapTypeError(ErrLeadingZero, bigT)},
   131  	{input: `"0xx"`, wantErr: wrapTypeError(ErrSyntax, bigT)},
   132  	{input: `"0x1zz01"`, wantErr: wrapTypeError(ErrSyntax, bigT)},
   133  	{
   134  		input:   `"0x10000000000000000000000000000000000000000000000000000000000000000"`,
   135  		wantErr: wrapTypeError(ErrBig256Range, bigT),
   136  	},
   137  
   138  //有效编码
   139  	{input: `""`, want: big.NewInt(0)},
   140  	{input: `"0x0"`, want: big.NewInt(0)},
   141  	{input: `"0x2"`, want: big.NewInt(0x2)},
   142  	{input: `"0x2F2"`, want: big.NewInt(0x2f2)},
   143  	{input: `"0X2F2"`, want: big.NewInt(0x2f2)},
   144  	{input: `"0x1122aaff"`, want: big.NewInt(0x1122aaff)},
   145  	{input: `"0xbBb"`, want: big.NewInt(0xbbb)},
   146  	{input: `"0xfffffffff"`, want: big.NewInt(0xfffffffff)},
   147  	{
   148  		input: `"0x112233445566778899aabbccddeeff"`,
   149  		want:  referenceBig("112233445566778899aabbccddeeff"),
   150  	},
   151  	{
   152  		input: `"0xffffffffffffffffffffffffffffffffffff"`,
   153  		want:  referenceBig("ffffffffffffffffffffffffffffffffffff"),
   154  	},
   155  	{
   156  		input: `"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"`,
   157  		want:  referenceBig("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
   158  	},
   159  }
   160  
   161  func TestUnmarshalBig(t *testing.T) {
   162  	for _, test := range unmarshalBigTests {
   163  		var v Big
   164  		err := json.Unmarshal([]byte(test.input), &v)
   165  		if !checkError(t, test.input, err, test.wantErr) {
   166  			continue
   167  		}
   168  		if test.want != nil && test.want.(*big.Int).Cmp((*big.Int)(&v)) != 0 {
   169  			t.Errorf("input %s: value mismatch: got %x, want %x", test.input, (*big.Int)(&v), test.want)
   170  			continue
   171  		}
   172  	}
   173  }
   174  
   175  func BenchmarkUnmarshalBig(b *testing.B) {
   176  	input := []byte(`"0x123456789abcdef123456789abcdef"`)
   177  	for i := 0; i < b.N; i++ {
   178  		var v Big
   179  		if err := v.UnmarshalJSON(input); err != nil {
   180  			b.Fatal(err)
   181  		}
   182  	}
   183  }
   184  
   185  func TestMarshalBig(t *testing.T) {
   186  	for _, test := range encodeBigTests {
   187  		in := test.input.(*big.Int)
   188  		out, err := json.Marshal((*Big)(in))
   189  		if err != nil {
   190  			t.Errorf("%d: %v", in, err)
   191  			continue
   192  		}
   193  		if want := `"` + test.want + `"`; string(out) != want {
   194  			t.Errorf("%d: MarshalJSON output mismatch: got %q, want %q", in, out, want)
   195  			continue
   196  		}
   197  		if out := (*Big)(in).String(); out != test.want {
   198  			t.Errorf("%x: String mismatch: got %q, want %q", in, out, test.want)
   199  			continue
   200  		}
   201  	}
   202  }
   203  
   204  var unmarshalUint64Tests = []unmarshalTest{
   205  //无效的编码
   206  	{input: "", wantErr: errJSONEOF},
   207  	{input: "null", wantErr: errNonString(uint64T)},
   208  	{input: "10", wantErr: errNonString(uint64T)},
   209  	{input: `"0"`, wantErr: wrapTypeError(ErrMissingPrefix, uint64T)},
   210  	{input: `"0x"`, wantErr: wrapTypeError(ErrEmptyNumber, uint64T)},
   211  	{input: `"0x01"`, wantErr: wrapTypeError(ErrLeadingZero, uint64T)},
   212  	{input: `"0xfffffffffffffffff"`, wantErr: wrapTypeError(ErrUint64Range, uint64T)},
   213  	{input: `"0xx"`, wantErr: wrapTypeError(ErrSyntax, uint64T)},
   214  	{input: `"0x1zz01"`, wantErr: wrapTypeError(ErrSyntax, uint64T)},
   215  
   216  //有效编码
   217  	{input: `""`, want: uint64(0)},
   218  	{input: `"0x0"`, want: uint64(0)},
   219  	{input: `"0x2"`, want: uint64(0x2)},
   220  	{input: `"0x2F2"`, want: uint64(0x2f2)},
   221  	{input: `"0X2F2"`, want: uint64(0x2f2)},
   222  	{input: `"0x1122aaff"`, want: uint64(0x1122aaff)},
   223  	{input: `"0xbbb"`, want: uint64(0xbbb)},
   224  	{input: `"0xffffffffffffffff"`, want: uint64(0xffffffffffffffff)},
   225  }
   226  
   227  func TestUnmarshalUint64(t *testing.T) {
   228  	for _, test := range unmarshalUint64Tests {
   229  		var v Uint64
   230  		err := json.Unmarshal([]byte(test.input), &v)
   231  		if !checkError(t, test.input, err, test.wantErr) {
   232  			continue
   233  		}
   234  		if uint64(v) != test.want.(uint64) {
   235  			t.Errorf("input %s: value mismatch: got %d, want %d", test.input, v, test.want)
   236  			continue
   237  		}
   238  	}
   239  }
   240  
   241  func BenchmarkUnmarshalUint64(b *testing.B) {
   242  	input := []byte(`"0x123456789abcdf"`)
   243  	for i := 0; i < b.N; i++ {
   244  		var v Uint64
   245  		v.UnmarshalJSON(input)
   246  	}
   247  }
   248  
   249  func TestMarshalUint64(t *testing.T) {
   250  	for _, test := range encodeUint64Tests {
   251  		in := test.input.(uint64)
   252  		out, err := json.Marshal(Uint64(in))
   253  		if err != nil {
   254  			t.Errorf("%d: %v", in, err)
   255  			continue
   256  		}
   257  		if want := `"` + test.want + `"`; string(out) != want {
   258  			t.Errorf("%d: MarshalJSON output mismatch: got %q, want %q", in, out, want)
   259  			continue
   260  		}
   261  		if out := (Uint64)(in).String(); out != test.want {
   262  			t.Errorf("%x: String mismatch: got %q, want %q", in, out, test.want)
   263  			continue
   264  		}
   265  	}
   266  }
   267  
   268  func TestMarshalUint(t *testing.T) {
   269  	for _, test := range encodeUintTests {
   270  		in := test.input.(uint)
   271  		out, err := json.Marshal(Uint(in))
   272  		if err != nil {
   273  			t.Errorf("%d: %v", in, err)
   274  			continue
   275  		}
   276  		if want := `"` + test.want + `"`; string(out) != want {
   277  			t.Errorf("%d: MarshalJSON output mismatch: got %q, want %q", in, out, want)
   278  			continue
   279  		}
   280  		if out := (Uint)(in).String(); out != test.want {
   281  			t.Errorf("%x: String mismatch: got %q, want %q", in, out, test.want)
   282  			continue
   283  		}
   284  	}
   285  }
   286  
   287  var (
   288  //这些是变量(不是常量),以避免常量溢出
   289  //在32位平台上签入编译器。
   290  	maxUint33bits = uint64(^uint32(0)) + 1
   291  	maxUint64bits = ^uint64(0)
   292  )
   293  
   294  var unmarshalUintTests = []unmarshalTest{
   295  //无效的编码
   296  	{input: "", wantErr: errJSONEOF},
   297  	{input: "null", wantErr: errNonString(uintT)},
   298  	{input: "10", wantErr: errNonString(uintT)},
   299  	{input: `"0"`, wantErr: wrapTypeError(ErrMissingPrefix, uintT)},
   300  	{input: `"0x"`, wantErr: wrapTypeError(ErrEmptyNumber, uintT)},
   301  	{input: `"0x01"`, wantErr: wrapTypeError(ErrLeadingZero, uintT)},
   302  	{input: `"0x100000000"`, want: uint(maxUint33bits), wantErr32bit: wrapTypeError(ErrUintRange, uintT)},
   303  	{input: `"0xfffffffffffffffff"`, wantErr: wrapTypeError(ErrUintRange, uintT)},
   304  	{input: `"0xx"`, wantErr: wrapTypeError(ErrSyntax, uintT)},
   305  	{input: `"0x1zz01"`, wantErr: wrapTypeError(ErrSyntax, uintT)},
   306  
   307  //有效编码
   308  	{input: `""`, want: uint(0)},
   309  	{input: `"0x0"`, want: uint(0)},
   310  	{input: `"0x2"`, want: uint(0x2)},
   311  	{input: `"0x2F2"`, want: uint(0x2f2)},
   312  	{input: `"0X2F2"`, want: uint(0x2f2)},
   313  	{input: `"0x1122aaff"`, want: uint(0x1122aaff)},
   314  	{input: `"0xbbb"`, want: uint(0xbbb)},
   315  	{input: `"0xffffffff"`, want: uint(0xffffffff)},
   316  	{input: `"0xffffffffffffffff"`, want: uint(maxUint64bits), wantErr32bit: wrapTypeError(ErrUintRange, uintT)},
   317  }
   318  
   319  func TestUnmarshalUint(t *testing.T) {
   320  	for _, test := range unmarshalUintTests {
   321  		var v Uint
   322  		err := json.Unmarshal([]byte(test.input), &v)
   323  		if uintBits == 32 && test.wantErr32bit != nil {
   324  			checkError(t, test.input, err, test.wantErr32bit)
   325  			continue
   326  		}
   327  		if !checkError(t, test.input, err, test.wantErr) {
   328  			continue
   329  		}
   330  		if uint(v) != test.want.(uint) {
   331  			t.Errorf("input %s: value mismatch: got %d, want %d", test.input, v, test.want)
   332  			continue
   333  		}
   334  	}
   335  }
   336  
   337  func TestUnmarshalFixedUnprefixedText(t *testing.T) {
   338  	tests := []struct {
   339  		input   string
   340  		want    []byte
   341  		wantErr error
   342  	}{
   343  		{input: "0x2", wantErr: ErrOddLength},
   344  		{input: "2", wantErr: ErrOddLength},
   345  		{input: "4444", wantErr: errors.New("hex string has length 4, want 8 for x")},
   346  		{input: "4444", wantErr: errors.New("hex string has length 4, want 8 for x")},
   347  //检查输出是否为部分正确输入而未修改
   348  		{input: "444444gg", wantErr: ErrSyntax, want: []byte{0, 0, 0, 0}},
   349  		{input: "0x444444gg", wantErr: ErrSyntax, want: []byte{0, 0, 0, 0}},
   350  //有效输入
   351  		{input: "44444444", want: []byte{0x44, 0x44, 0x44, 0x44}},
   352  		{input: "0x44444444", want: []byte{0x44, 0x44, 0x44, 0x44}},
   353  	}
   354  
   355  	for _, test := range tests {
   356  		out := make([]byte, 4)
   357  		err := UnmarshalFixedUnprefixedText("x", []byte(test.input), out)
   358  		switch {
   359  		case err == nil && test.wantErr != nil:
   360  			t.Errorf("%q: got no error, expected %q", test.input, test.wantErr)
   361  		case err != nil && test.wantErr == nil:
   362  			t.Errorf("%q: unexpected error %q", test.input, err)
   363  		case err != nil && err.Error() != test.wantErr.Error():
   364  			t.Errorf("%q: error mismatch: got %q, want %q", test.input, err, test.wantErr)
   365  		}
   366  		if test.want != nil && !bytes.Equal(out, test.want) {
   367  			t.Errorf("%q: output mismatch: got %x, want %x", test.input, out, test.want)
   368  		}
   369  	}
   370  }
   371