github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/common/hexutil/json_test.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //版权所有2016 Go Ethereum作者
    10  //此文件是Go以太坊库的一部分。
    11  //
    12  //Go-Ethereum库是免费软件:您可以重新分发它和/或修改
    13  //根据GNU发布的较低通用公共许可证的条款
    14  //自由软件基金会,或者许可证的第3版,或者
    15  //(由您选择)任何更高版本。
    16  //
    17  //Go以太坊图书馆的发行目的是希望它会有用,
    18  //但没有任何保证;甚至没有
    19  //适销性或特定用途的适用性。见
    20  //GNU较低的通用公共许可证,了解更多详细信息。
    21  //
    22  //你应该收到一份GNU较低级别的公共许可证副本
    23  //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。
    24  
    25  package hexutil
    26  
    27  import (
    28  	"bytes"
    29  	"encoding/hex"
    30  	"encoding/json"
    31  	"errors"
    32  	"math/big"
    33  	"testing"
    34  )
    35  
    36  func checkError(t *testing.T, input string, got, want error) bool {
    37  	if got == nil {
    38  		if want != nil {
    39  			t.Errorf("input %s: got no error, want %q", input, want)
    40  			return false
    41  		}
    42  		return true
    43  	}
    44  	if want == nil {
    45  		t.Errorf("input %s: unexpected error %q", input, got)
    46  	} else if got.Error() != want.Error() {
    47  		t.Errorf("input %s: got error %q, want %q", input, got, want)
    48  	}
    49  	return false
    50  }
    51  
    52  func referenceBig(s string) *big.Int {
    53  	b, ok := new(big.Int).SetString(s, 16)
    54  	if !ok {
    55  		panic("invalid")
    56  	}
    57  	return b
    58  }
    59  
    60  func referenceBytes(s string) []byte {
    61  	b, err := hex.DecodeString(s)
    62  	if err != nil {
    63  		panic(err)
    64  	}
    65  	return b
    66  }
    67  
    68  var errJSONEOF = errors.New("unexpected end of JSON input")
    69  
    70  var unmarshalBytesTests = []unmarshalTest{
    71  //无效的编码
    72  	{input: "", wantErr: errJSONEOF},
    73  	{input: "null", wantErr: errNonString(bytesT)},
    74  	{input: "10", wantErr: errNonString(bytesT)},
    75  	{input: `"0"`, wantErr: wrapTypeError(ErrMissingPrefix, bytesT)},
    76  	{input: `"0x0"`, wantErr: wrapTypeError(ErrOddLength, bytesT)},
    77  	{input: `"0xxx"`, wantErr: wrapTypeError(ErrSyntax, bytesT)},
    78  	{input: `"0x01zz01"`, wantErr: wrapTypeError(ErrSyntax, bytesT)},
    79  
    80  //有效编码
    81  	{input: `""`, want: referenceBytes("")},
    82  	{input: `"0x"`, want: referenceBytes("")},
    83  	{input: `"0x02"`, want: referenceBytes("02")},
    84  	{input: `"0X02"`, want: referenceBytes("02")},
    85  	{input: `"0xffffffffff"`, want: referenceBytes("ffffffffff")},
    86  	{
    87  		input: `"0xffffffffffffffffffffffffffffffffffff"`,
    88  		want:  referenceBytes("ffffffffffffffffffffffffffffffffffff"),
    89  	},
    90  }
    91  
    92  func TestUnmarshalBytes(t *testing.T) {
    93  	for _, test := range unmarshalBytesTests {
    94  		var v Bytes
    95  		err := json.Unmarshal([]byte(test.input), &v)
    96  		if !checkError(t, test.input, err, test.wantErr) {
    97  			continue
    98  		}
    99  		if !bytes.Equal(test.want.([]byte), []byte(v)) {
   100  			t.Errorf("input %s: value mismatch: got %x, want %x", test.input, &v, test.want)
   101  			continue
   102  		}
   103  	}
   104  }
   105  
   106  func BenchmarkUnmarshalBytes(b *testing.B) {
   107  	input := []byte(`"0x123456789abcdef123456789abcdef"`)
   108  	for i := 0; i < b.N; i++ {
   109  		var v Bytes
   110  		if err := v.UnmarshalJSON(input); err != nil {
   111  			b.Fatal(err)
   112  		}
   113  	}
   114  }
   115  
   116  func TestMarshalBytes(t *testing.T) {
   117  	for _, test := range encodeBytesTests {
   118  		in := test.input.([]byte)
   119  		out, err := json.Marshal(Bytes(in))
   120  		if err != nil {
   121  			t.Errorf("%x: %v", in, err)
   122  			continue
   123  		}
   124  		if want := `"` + test.want + `"`; string(out) != want {
   125  			t.Errorf("%x: MarshalJSON output mismatch: got %q, want %q", in, out, want)
   126  			continue
   127  		}
   128  		if out := Bytes(in).String(); out != test.want {
   129  			t.Errorf("%x: String mismatch: got %q, want %q", in, out, test.want)
   130  			continue
   131  		}
   132  	}
   133  }
   134  
   135  var unmarshalBigTests = []unmarshalTest{
   136  //无效的编码
   137  	{input: "", wantErr: errJSONEOF},
   138  	{input: "null", wantErr: errNonString(bigT)},
   139  	{input: "10", wantErr: errNonString(bigT)},
   140  	{input: `"0"`, wantErr: wrapTypeError(ErrMissingPrefix, bigT)},
   141  	{input: `"0x"`, wantErr: wrapTypeError(ErrEmptyNumber, bigT)},
   142  	{input: `"0x01"`, wantErr: wrapTypeError(ErrLeadingZero, bigT)},
   143  	{input: `"0xx"`, wantErr: wrapTypeError(ErrSyntax, bigT)},
   144  	{input: `"0x1zz01"`, wantErr: wrapTypeError(ErrSyntax, bigT)},
   145  	{
   146  		input:   `"0x10000000000000000000000000000000000000000000000000000000000000000"`,
   147  		wantErr: wrapTypeError(ErrBig256Range, bigT),
   148  	},
   149  
   150  //有效编码
   151  	{input: `""`, want: big.NewInt(0)},
   152  	{input: `"0x0"`, want: big.NewInt(0)},
   153  	{input: `"0x2"`, want: big.NewInt(0x2)},
   154  	{input: `"0x2F2"`, want: big.NewInt(0x2f2)},
   155  	{input: `"0X2F2"`, want: big.NewInt(0x2f2)},
   156  	{input: `"0x1122aaff"`, want: big.NewInt(0x1122aaff)},
   157  	{input: `"0xbBb"`, want: big.NewInt(0xbbb)},
   158  	{input: `"0xfffffffff"`, want: big.NewInt(0xfffffffff)},
   159  	{
   160  		input: `"0x112233445566778899aabbccddeeff"`,
   161  		want:  referenceBig("112233445566778899aabbccddeeff"),
   162  	},
   163  	{
   164  		input: `"0xffffffffffffffffffffffffffffffffffff"`,
   165  		want:  referenceBig("ffffffffffffffffffffffffffffffffffff"),
   166  	},
   167  	{
   168  		input: `"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"`,
   169  		want:  referenceBig("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
   170  	},
   171  }
   172  
   173  func TestUnmarshalBig(t *testing.T) {
   174  	for _, test := range unmarshalBigTests {
   175  		var v Big
   176  		err := json.Unmarshal([]byte(test.input), &v)
   177  		if !checkError(t, test.input, err, test.wantErr) {
   178  			continue
   179  		}
   180  		if test.want != nil && test.want.(*big.Int).Cmp((*big.Int)(&v)) != 0 {
   181  			t.Errorf("input %s: value mismatch: got %x, want %x", test.input, (*big.Int)(&v), test.want)
   182  			continue
   183  		}
   184  	}
   185  }
   186  
   187  func BenchmarkUnmarshalBig(b *testing.B) {
   188  	input := []byte(`"0x123456789abcdef123456789abcdef"`)
   189  	for i := 0; i < b.N; i++ {
   190  		var v Big
   191  		if err := v.UnmarshalJSON(input); err != nil {
   192  			b.Fatal(err)
   193  		}
   194  	}
   195  }
   196  
   197  func TestMarshalBig(t *testing.T) {
   198  	for _, test := range encodeBigTests {
   199  		in := test.input.(*big.Int)
   200  		out, err := json.Marshal((*Big)(in))
   201  		if err != nil {
   202  			t.Errorf("%d: %v", in, err)
   203  			continue
   204  		}
   205  		if want := `"` + test.want + `"`; string(out) != want {
   206  			t.Errorf("%d: MarshalJSON output mismatch: got %q, want %q", in, out, want)
   207  			continue
   208  		}
   209  		if out := (*Big)(in).String(); out != test.want {
   210  			t.Errorf("%x: String mismatch: got %q, want %q", in, out, test.want)
   211  			continue
   212  		}
   213  	}
   214  }
   215  
   216  var unmarshalUint64Tests = []unmarshalTest{
   217  //无效的编码
   218  	{input: "", wantErr: errJSONEOF},
   219  	{input: "null", wantErr: errNonString(uint64T)},
   220  	{input: "10", wantErr: errNonString(uint64T)},
   221  	{input: `"0"`, wantErr: wrapTypeError(ErrMissingPrefix, uint64T)},
   222  	{input: `"0x"`, wantErr: wrapTypeError(ErrEmptyNumber, uint64T)},
   223  	{input: `"0x01"`, wantErr: wrapTypeError(ErrLeadingZero, uint64T)},
   224  	{input: `"0xfffffffffffffffff"`, wantErr: wrapTypeError(ErrUint64Range, uint64T)},
   225  	{input: `"0xx"`, wantErr: wrapTypeError(ErrSyntax, uint64T)},
   226  	{input: `"0x1zz01"`, wantErr: wrapTypeError(ErrSyntax, uint64T)},
   227  
   228  //有效编码
   229  	{input: `""`, want: uint64(0)},
   230  	{input: `"0x0"`, want: uint64(0)},
   231  	{input: `"0x2"`, want: uint64(0x2)},
   232  	{input: `"0x2F2"`, want: uint64(0x2f2)},
   233  	{input: `"0X2F2"`, want: uint64(0x2f2)},
   234  	{input: `"0x1122aaff"`, want: uint64(0x1122aaff)},
   235  	{input: `"0xbbb"`, want: uint64(0xbbb)},
   236  	{input: `"0xffffffffffffffff"`, want: uint64(0xffffffffffffffff)},
   237  }
   238  
   239  func TestUnmarshalUint64(t *testing.T) {
   240  	for _, test := range unmarshalUint64Tests {
   241  		var v Uint64
   242  		err := json.Unmarshal([]byte(test.input), &v)
   243  		if !checkError(t, test.input, err, test.wantErr) {
   244  			continue
   245  		}
   246  		if uint64(v) != test.want.(uint64) {
   247  			t.Errorf("input %s: value mismatch: got %d, want %d", test.input, v, test.want)
   248  			continue
   249  		}
   250  	}
   251  }
   252  
   253  func BenchmarkUnmarshalUint64(b *testing.B) {
   254  	input := []byte(`"0x123456789abcdf"`)
   255  	for i := 0; i < b.N; i++ {
   256  		var v Uint64
   257  		v.UnmarshalJSON(input)
   258  	}
   259  }
   260  
   261  func TestMarshalUint64(t *testing.T) {
   262  	for _, test := range encodeUint64Tests {
   263  		in := test.input.(uint64)
   264  		out, err := json.Marshal(Uint64(in))
   265  		if err != nil {
   266  			t.Errorf("%d: %v", in, err)
   267  			continue
   268  		}
   269  		if want := `"` + test.want + `"`; string(out) != want {
   270  			t.Errorf("%d: MarshalJSON output mismatch: got %q, want %q", in, out, want)
   271  			continue
   272  		}
   273  		if out := (Uint64)(in).String(); out != test.want {
   274  			t.Errorf("%x: String mismatch: got %q, want %q", in, out, test.want)
   275  			continue
   276  		}
   277  	}
   278  }
   279  
   280  func TestMarshalUint(t *testing.T) {
   281  	for _, test := range encodeUintTests {
   282  		in := test.input.(uint)
   283  		out, err := json.Marshal(Uint(in))
   284  		if err != nil {
   285  			t.Errorf("%d: %v", in, err)
   286  			continue
   287  		}
   288  		if want := `"` + test.want + `"`; string(out) != want {
   289  			t.Errorf("%d: MarshalJSON output mismatch: got %q, want %q", in, out, want)
   290  			continue
   291  		}
   292  		if out := (Uint)(in).String(); out != test.want {
   293  			t.Errorf("%x: String mismatch: got %q, want %q", in, out, test.want)
   294  			continue
   295  		}
   296  	}
   297  }
   298  
   299  var (
   300  //这些是变量(不是常量),以避免常量溢出
   301  //在32位平台上签入编译器。
   302  	maxUint33bits = uint64(^uint32(0)) + 1
   303  	maxUint64bits = ^uint64(0)
   304  )
   305  
   306  var unmarshalUintTests = []unmarshalTest{
   307  //无效的编码
   308  	{input: "", wantErr: errJSONEOF},
   309  	{input: "null", wantErr: errNonString(uintT)},
   310  	{input: "10", wantErr: errNonString(uintT)},
   311  	{input: `"0"`, wantErr: wrapTypeError(ErrMissingPrefix, uintT)},
   312  	{input: `"0x"`, wantErr: wrapTypeError(ErrEmptyNumber, uintT)},
   313  	{input: `"0x01"`, wantErr: wrapTypeError(ErrLeadingZero, uintT)},
   314  	{input: `"0x100000000"`, want: uint(maxUint33bits), wantErr32bit: wrapTypeError(ErrUintRange, uintT)},
   315  	{input: `"0xfffffffffffffffff"`, wantErr: wrapTypeError(ErrUintRange, uintT)},
   316  	{input: `"0xx"`, wantErr: wrapTypeError(ErrSyntax, uintT)},
   317  	{input: `"0x1zz01"`, wantErr: wrapTypeError(ErrSyntax, uintT)},
   318  
   319  //有效编码
   320  	{input: `""`, want: uint(0)},
   321  	{input: `"0x0"`, want: uint(0)},
   322  	{input: `"0x2"`, want: uint(0x2)},
   323  	{input: `"0x2F2"`, want: uint(0x2f2)},
   324  	{input: `"0X2F2"`, want: uint(0x2f2)},
   325  	{input: `"0x1122aaff"`, want: uint(0x1122aaff)},
   326  	{input: `"0xbbb"`, want: uint(0xbbb)},
   327  	{input: `"0xffffffff"`, want: uint(0xffffffff)},
   328  	{input: `"0xffffffffffffffff"`, want: uint(maxUint64bits), wantErr32bit: wrapTypeError(ErrUintRange, uintT)},
   329  }
   330  
   331  func TestUnmarshalUint(t *testing.T) {
   332  	for _, test := range unmarshalUintTests {
   333  		var v Uint
   334  		err := json.Unmarshal([]byte(test.input), &v)
   335  		if uintBits == 32 && test.wantErr32bit != nil {
   336  			checkError(t, test.input, err, test.wantErr32bit)
   337  			continue
   338  		}
   339  		if !checkError(t, test.input, err, test.wantErr) {
   340  			continue
   341  		}
   342  		if uint(v) != test.want.(uint) {
   343  			t.Errorf("input %s: value mismatch: got %d, want %d", test.input, v, test.want)
   344  			continue
   345  		}
   346  	}
   347  }
   348  
   349  func TestUnmarshalFixedUnprefixedText(t *testing.T) {
   350  	tests := []struct {
   351  		input   string
   352  		want    []byte
   353  		wantErr error
   354  	}{
   355  		{input: "0x2", wantErr: ErrOddLength},
   356  		{input: "2", wantErr: ErrOddLength},
   357  		{input: "4444", wantErr: errors.New("hex string has length 4, want 8 for x")},
   358  		{input: "4444", wantErr: errors.New("hex string has length 4, want 8 for x")},
   359  //检查输出是否为部分正确输入而未修改
   360  		{input: "444444gg", wantErr: ErrSyntax, want: []byte{0, 0, 0, 0}},
   361  		{input: "0x444444gg", wantErr: ErrSyntax, want: []byte{0, 0, 0, 0}},
   362  //有效输入
   363  		{input: "44444444", want: []byte{0x44, 0x44, 0x44, 0x44}},
   364  		{input: "0x44444444", want: []byte{0x44, 0x44, 0x44, 0x44}},
   365  	}
   366  
   367  	for _, test := range tests {
   368  		out := make([]byte, 4)
   369  		err := UnmarshalFixedUnprefixedText("x", []byte(test.input), out)
   370  		switch {
   371  		case err == nil && test.wantErr != nil:
   372  			t.Errorf("%q: got no error, expected %q", test.input, test.wantErr)
   373  		case err != nil && test.wantErr == nil:
   374  			t.Errorf("%q: unexpected error %q", test.input, err)
   375  		case err != nil && err.Error() != test.wantErr.Error():
   376  			t.Errorf("%q: error mismatch: got %q, want %q", test.input, err, test.wantErr)
   377  		}
   378  		if test.want != nil && !bytes.Equal(out, test.want) {
   379  			t.Errorf("%q: output mismatch: got %x, want %x", test.input, out, test.want)
   380  		}
   381  	}
   382  }