github.com/qiniu/dyn@v1.3.0/jsonext/decode_test.go (about)

     1  // Copyright 2010 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package jsonext
     6  
     7  import (
     8  	"bytes"
     9  	"encoding"
    10  	"fmt"
    11  	"image"
    12  	"reflect"
    13  	"strings"
    14  	"testing"
    15  	"time"
    16  )
    17  
    18  type T struct {
    19  	X string
    20  	Y int
    21  	Z int `json:"-"`
    22  }
    23  
    24  type U struct {
    25  	Alphabet string `json:"alpha"`
    26  }
    27  
    28  type V struct {
    29  	F1 interface{}
    30  	F2 int32
    31  	F3 Number
    32  }
    33  
    34  // ifaceNumAsFloat64/ifaceNumAsNumber are used to test unmarshaling with and
    35  // without UseNumber
    36  var ifaceNumAsFloat64 = map[string]interface{}{
    37  	"k1": float64(1),
    38  	"k2": "s",
    39  	"k3": []interface{}{float64(1), float64(2.0), float64(3e-3)},
    40  	"k4": map[string]interface{}{"kk1": "s", "kk2": float64(2)},
    41  }
    42  
    43  var ifaceNumAsNumber = map[string]interface{}{
    44  	"k1": Number("1"),
    45  	"k2": "s",
    46  	"k3": []interface{}{Number("1"), Number("2.0"), Number("3e-3")},
    47  	"k4": map[string]interface{}{"kk1": "s", "kk2": Number("2")},
    48  }
    49  
    50  type tx struct {
    51  	x int
    52  }
    53  
    54  // A type that can unmarshal itself.
    55  
    56  type unmarshaler struct {
    57  	T bool
    58  }
    59  
    60  func (u *unmarshaler) UnmarshalJSON(b []byte) error {
    61  	*u = unmarshaler{true} // All we need to see that UnmarshalJSON is called.
    62  	return nil
    63  }
    64  
    65  type ustruct struct {
    66  	M unmarshaler
    67  }
    68  
    69  type unmarshalerText struct {
    70  	T bool
    71  }
    72  
    73  // needed for re-marshaling tests
    74  func (u *unmarshalerText) MarshalText() ([]byte, error) {
    75  	return []byte(""), nil
    76  }
    77  
    78  func (u *unmarshalerText) UnmarshalText(b []byte) error {
    79  	*u = unmarshalerText{true} // All we need to see that UnmarshalText is called.
    80  	return nil
    81  }
    82  
    83  var _ encoding.TextUnmarshaler = (*unmarshalerText)(nil)
    84  
    85  type ustructText struct {
    86  	M unmarshalerText
    87  }
    88  
    89  var (
    90  	um0, um1 unmarshaler // target2 of unmarshaling
    91  	ump      = &um1
    92  	umtrue   = unmarshaler{true}
    93  	umslice  = []unmarshaler{{true}}
    94  	umslicep = new([]unmarshaler)
    95  	umstruct = ustruct{unmarshaler{true}}
    96  
    97  	um0T, um1T unmarshalerText // target2 of unmarshaling
    98  	umpT       = &um1T
    99  	umtrueT    = unmarshalerText{true}
   100  	umsliceT   = []unmarshalerText{{true}}
   101  	umslicepT  = new([]unmarshalerText)
   102  	umstructT  = ustructText{unmarshalerText{true}}
   103  )
   104  
   105  // Test data structures for anonymous fields.
   106  
   107  type Point struct {
   108  	Z int
   109  }
   110  
   111  type Top struct {
   112  	Level0 int
   113  	Embed0
   114  	*Embed0a
   115  	*Embed0b `json:"e,omitempty"` // treated as named
   116  	Embed0c  `json:"-"`           // ignored
   117  	Loop
   118  	Embed0p // has Point with X, Y, used
   119  	Embed0q // has Point with Z, used
   120  }
   121  
   122  type Embed0 struct {
   123  	Level1a int // overridden by Embed0a's Level1a with json tag
   124  	Level1b int // used because Embed0a's Level1b is renamed
   125  	Level1c int // used because Embed0a's Level1c is ignored
   126  	Level1d int // annihilated by Embed0a's Level1d
   127  	Level1e int `json:"x"` // annihilated by Embed0a.Level1e
   128  }
   129  
   130  type Embed0a struct {
   131  	Level1a int `json:"Level1a,omitempty"`
   132  	Level1b int `json:"LEVEL1B,omitempty"`
   133  	Level1c int `json:"-"`
   134  	Level1d int // annihilated by Embed0's Level1d
   135  	Level1f int `json:"x"` // annihilated by Embed0's Level1e
   136  }
   137  
   138  type Embed0b Embed0
   139  
   140  type Embed0c Embed0
   141  
   142  type Embed0p struct {
   143  	image.Point
   144  }
   145  
   146  type Embed0q struct {
   147  	Point
   148  }
   149  
   150  type Loop struct {
   151  	Loop1 int `json:",omitempty"`
   152  	Loop2 int `json:",omitempty"`
   153  	*Loop
   154  }
   155  
   156  // From reflect test:
   157  // The X in S6 and S7 annihilate, but they also block the X in S8.S9.
   158  type S5 struct {
   159  	S6
   160  	S7
   161  	S8
   162  }
   163  
   164  type S6 struct {
   165  	X int
   166  }
   167  
   168  type S7 S6
   169  
   170  type S8 struct {
   171  	S9
   172  }
   173  
   174  type S9 struct {
   175  	X int
   176  	Y int
   177  }
   178  
   179  // From reflect test:
   180  // The X in S11.S6 and S12.S6 annihilate, but they also block the X in S13.S8.S9.
   181  type S10 struct {
   182  	S11
   183  	S12
   184  	S13
   185  }
   186  
   187  type S11 struct {
   188  	S6
   189  }
   190  
   191  type S12 struct {
   192  	S6
   193  }
   194  
   195  type S13 struct {
   196  	S8
   197  }
   198  
   199  type unmarshalTest struct {
   200  	in        string
   201  	ptr       interface{}
   202  	out       interface{}
   203  	err       error
   204  	useNumber bool
   205  }
   206  
   207  type Ambig struct {
   208  	// Given "hello", the first match should win.
   209  	First  int `json:"HELLO"`
   210  	Second int `json:"Hello"`
   211  }
   212  
   213  type XYZ struct {
   214  	X interface{}
   215  	Y interface{}
   216  	Z interface{}
   217  }
   218  
   219  var unmarshalTests = []unmarshalTest{
   220  	// basic types
   221  	{in: `true`, ptr: new(bool), out: true},
   222  	{in: `1`, ptr: new(int), out: 1},
   223  	{in: `1.2`, ptr: new(float64), out: 1.2},
   224  	{in: `-5`, ptr: new(int16), out: int16(-5)},
   225  	{in: `2`, ptr: new(Number), out: Number("2"), useNumber: true},
   226  	{in: `2`, ptr: new(Number), out: Number("2")},
   227  	{in: `2`, ptr: new(interface{}), out: float64(2.0)},
   228  	{in: `2`, ptr: new(interface{}), out: Number("2"), useNumber: true},
   229  	{in: `"a\u1234"`, ptr: new(string), out: "a\u1234"},
   230  	{in: `"http:\/\/"`, ptr: new(string), out: "http://"},
   231  	{in: `"g-clef: \uD834\uDD1E"`, ptr: new(string), out: "g-clef: \U0001D11E"},
   232  	{in: `"invalid: \uD834x\uDD1E"`, ptr: new(string), out: "invalid: \uFFFDx\uFFFD"},
   233  	{in: "null", ptr: new(interface{}), out: nil},
   234  	{in: `{"X": [1,2,3], "Y": 4}`, ptr: new(T), out: T{Y: 4}, err: &UnmarshalTypeError{"array", reflect.TypeOf("")}},
   235  	{in: `{"x": 1}`, ptr: new(tx), out: tx{}},
   236  	{in: `{"F1":1,"F2":2,"F3":3}`, ptr: new(V), out: V{F1: float64(1), F2: int32(2), F3: Number("3")}},
   237  	{in: `{"F1":1,"F2":2,"F3":3}`, ptr: new(V), out: V{F1: Number("1"), F2: int32(2), F3: Number("3")}, useNumber: true},
   238  	{in: `{"k1":1,"k2":"s","k3":[1,2.0,3e-3],"k4":{"kk1":"s","kk2":2}}`, ptr: new(interface{}), out: ifaceNumAsFloat64},
   239  	{in: `{"k1":1,"k2":"s","k3":[1,2.0,3e-3],"k4":{"kk1":"s","kk2":2}}`, ptr: new(interface{}), out: ifaceNumAsNumber, useNumber: true},
   240  
   241  	// raw values with whitespace
   242  	{in: "\n true ", ptr: new(bool), out: true},
   243  	{in: "\t 1 ", ptr: new(int), out: 1},
   244  	{in: "\r 1.2 ", ptr: new(float64), out: 1.2},
   245  	{in: "\t -5 \n", ptr: new(int16), out: int16(-5)},
   246  	{in: "\t \"a\\u1234\" \n", ptr: new(string), out: "a\u1234"},
   247  
   248  	// Z has a "-" tag.
   249  	{in: `{"Y": 1, "Z": 2}`, ptr: new(T), out: T{Y: 1}},
   250  
   251  	{in: `{"alpha": "abc", "alphabet": "xyz"}`, ptr: new(U), out: U{Alphabet: "abc"}},
   252  	{in: `{"alpha": "abc"}`, ptr: new(U), out: U{Alphabet: "abc"}},
   253  	{in: `{"alphabet": "xyz"}`, ptr: new(U), out: U{}},
   254  
   255  	// syntax errors
   256  	{in: `{"X": "foo", "Y"}`, err: &SyntaxError{"invalid character '}' after object key", 17}},
   257  	{in: `[1, 2, 3+]`, err: &SyntaxError{"invalid character '+' after array element", 9}},
   258  	{in: `{"X":12x}`, err: &SyntaxError{"invalid character 'x' after object key:value pair", 8}, useNumber: true},
   259  
   260  	// raw value errors
   261  	{in: "\x01 42", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}},
   262  	{in: " 42 \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 5}},
   263  	{in: "\x01 true", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}},
   264  	{in: " false \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 8}},
   265  	{in: "\x01 1.2", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}},
   266  	{in: " 3.4 \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 6}},
   267  	{in: "\x01 \"string\"", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}},
   268  	{in: " \"string\" \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 11}},
   269  
   270  	// array tests
   271  	{in: `[1, 2, 3]`, ptr: new([3]int), out: [3]int{1, 2, 3}},
   272  	{in: `[1, 2, 3]`, ptr: new([1]int), out: [1]int{1}},
   273  	{in: `[1, 2, 3]`, ptr: new([5]int), out: [5]int{1, 2, 3, 0, 0}},
   274  
   275  	// empty array to interface test
   276  	{in: `[]`, ptr: new([]interface{}), out: []interface{}{}},
   277  	{in: `null`, ptr: new([]interface{}), out: []interface{}(nil)},
   278  	{in: `{"T":[]}`, ptr: new(map[string]interface{}), out: map[string]interface{}{"T": []interface{}{}}},
   279  	{in: `{"T":null}`, ptr: new(map[string]interface{}), out: map[string]interface{}{"T": interface{}(nil)}},
   280  
   281  	// composite tests
   282  	{in: allValueIndent, ptr: new(All), out: allValue},
   283  	{in: allValueCompact, ptr: new(All), out: allValue},
   284  	{in: allValueIndent, ptr: new(*All), out: &allValue},
   285  	{in: allValueCompact, ptr: new(*All), out: &allValue},
   286  	{in: pallValueIndent, ptr: new(All), out: pallValue},
   287  	{in: pallValueCompact, ptr: new(All), out: pallValue},
   288  	{in: pallValueIndent, ptr: new(*All), out: &pallValue},
   289  	{in: pallValueCompact, ptr: new(*All), out: &pallValue},
   290  
   291  	// unmarshal interface test
   292  	{in: `{"T":false}`, ptr: &um0, out: umtrue}, // use "false" so test will fail if custom unmarshaler is not called
   293  	{in: `{"T":false}`, ptr: &ump, out: &umtrue},
   294  	{in: `[{"T":false}]`, ptr: &umslice, out: umslice},
   295  	{in: `[{"T":false}]`, ptr: &umslicep, out: &umslice},
   296  	{in: `{"M":{"T":false}}`, ptr: &umstruct, out: umstruct},
   297  
   298  	// UnmarshalText interface test
   299  	{in: `"X"`, ptr: &um0T, out: umtrueT}, // use "false" so test will fail if custom unmarshaler is not called
   300  	{in: `"X"`, ptr: &umpT, out: &umtrueT},
   301  	{in: `["X"]`, ptr: &umsliceT, out: umsliceT},
   302  	{in: `["X"]`, ptr: &umslicepT, out: &umsliceT},
   303  	{in: `{"M":"X"}`, ptr: &umstructT, out: umstructT},
   304  
   305  	{
   306  		in: `{
   307  			"Level0": 1,
   308  			"Level1b": 2,
   309  			"Level1c": 3,
   310  			"x": 4,
   311  			"Level1a": 5,
   312  			"LEVEL1B": 6,
   313  			"e": {
   314  				"Level1a": 8,
   315  				"Level1b": 9,
   316  				"Level1c": 10,
   317  				"Level1d": 11,
   318  				"x": 12
   319  			},
   320  			"Loop1": 13,
   321  			"Loop2": 14,
   322  			"X": 15,
   323  			"Y": 16,
   324  			"Z": 17
   325  		}`,
   326  		ptr: new(Top),
   327  		out: Top{
   328  			Level0: 1,
   329  			Embed0: Embed0{
   330  				Level1b: 2,
   331  				Level1c: 3,
   332  			},
   333  			Embed0a: &Embed0a{
   334  				Level1a: 5,
   335  				Level1b: 6,
   336  			},
   337  			Embed0b: &Embed0b{
   338  				Level1a: 8,
   339  				Level1b: 9,
   340  				Level1c: 10,
   341  				Level1d: 11,
   342  				Level1e: 12,
   343  			},
   344  			Loop: Loop{
   345  				Loop1: 13,
   346  				Loop2: 14,
   347  			},
   348  			Embed0p: Embed0p{
   349  				Point: image.Point{X: 15, Y: 16},
   350  			},
   351  			Embed0q: Embed0q{
   352  				Point: Point{Z: 17},
   353  			},
   354  		},
   355  	},
   356  	{
   357  		in:  `{"hello": 1}`,
   358  		ptr: new(Ambig),
   359  		out: Ambig{First: 1},
   360  	},
   361  
   362  	{
   363  		in:  `{"X": 1,"Y":2}`,
   364  		ptr: new(S5),
   365  		out: S5{S8: S8{S9: S9{Y: 2}}},
   366  	},
   367  	{
   368  		in:  `{"X": 1,"Y":2}`,
   369  		ptr: new(S10),
   370  		out: S10{S13: S13{S8: S8{S9: S9{Y: 2}}}},
   371  	},
   372  
   373  	// invalid UTF-8 is coerced to valid UTF-8.
   374  	{
   375  		in:  "\"hello\xffworld\"",
   376  		ptr: new(string),
   377  		out: "hello\ufffdworld",
   378  	},
   379  	{
   380  		in:  "\"hello\xc2\xc2world\"",
   381  		ptr: new(string),
   382  		out: "hello\ufffd\ufffdworld",
   383  	},
   384  	{
   385  		in:  "\"hello\xc2\xffworld\"",
   386  		ptr: new(string),
   387  		out: "hello\ufffd\ufffdworld",
   388  	},
   389  	{
   390  		in:  "\"hello\\ud800world\"",
   391  		ptr: new(string),
   392  		out: "hello\ufffdworld",
   393  	},
   394  	{
   395  		in:  "\"hello\\ud800\\ud800world\"",
   396  		ptr: new(string),
   397  		out: "hello\ufffd\ufffdworld",
   398  	},
   399  	{
   400  		in:  "\"hello\\ud800\\ud800world\"",
   401  		ptr: new(string),
   402  		out: "hello\ufffd\ufffdworld",
   403  	},
   404  	{
   405  		in:  "\"hello\xed\xa0\x80\xed\xb0\x80world\"",
   406  		ptr: new(string),
   407  		out: "hello\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdworld",
   408  	},
   409  }
   410  
   411  func TestMarshal(t *testing.T) {
   412  	b, err := Marshal(allValue)
   413  	if err != nil {
   414  		t.Fatalf("Marshal allValue: %v", err)
   415  	}
   416  	if string(b) != allValueCompact {
   417  		t.Errorf("Marshal allValueCompact")
   418  		diff(t, b, []byte(allValueCompact))
   419  		return
   420  	}
   421  
   422  	b, err = Marshal(pallValue)
   423  	if err != nil {
   424  		t.Fatalf("Marshal pallValue: %v", err)
   425  	}
   426  	if string(b) != pallValueCompact {
   427  		t.Errorf("Marshal pallValueCompact")
   428  		diff(t, b, []byte(pallValueCompact))
   429  		return
   430  	}
   431  }
   432  
   433  var badUTF8 = []struct {
   434  	in, out string
   435  }{
   436  	{"hello\xffworld", `"hello\ufffdworld"`},
   437  	{"", `""`},
   438  	{"\xff", `"\ufffd"`},
   439  	{"\xff\xff", `"\ufffd\ufffd"`},
   440  	{"a\xffb", `"a\ufffdb"`},
   441  	{"\xe6\x97\xa5\xe6\x9c\xac\xff\xaa\x9e", `"日本\ufffd\ufffd\ufffd"`},
   442  }
   443  
   444  func TestMarshalBadUTF8(t *testing.T) {
   445  	for _, tt := range badUTF8 {
   446  		b, err := Marshal(tt.in)
   447  		if string(b) != tt.out || err != nil {
   448  			t.Errorf("Marshal(%q) = %#q, %v, want %#q, nil", tt.in, b, err, tt.out)
   449  		}
   450  	}
   451  }
   452  
   453  func TestMarshalNumberZeroVal(t *testing.T) {
   454  	var n Number
   455  	out, err := Marshal(n)
   456  	if err != nil {
   457  		t.Fatal(err)
   458  	}
   459  	outStr := string(out)
   460  	if outStr != "0" {
   461  		t.Fatalf("Invalid zero val for Number: %q", outStr)
   462  	}
   463  }
   464  
   465  func TestMarshalEmbeds(t *testing.T) {
   466  	top := &Top{
   467  		Level0: 1,
   468  		Embed0: Embed0{
   469  			Level1b: 2,
   470  			Level1c: 3,
   471  		},
   472  		Embed0a: &Embed0a{
   473  			Level1a: 5,
   474  			Level1b: 6,
   475  		},
   476  		Embed0b: &Embed0b{
   477  			Level1a: 8,
   478  			Level1b: 9,
   479  			Level1c: 10,
   480  			Level1d: 11,
   481  			Level1e: 12,
   482  		},
   483  		Loop: Loop{
   484  			Loop1: 13,
   485  			Loop2: 14,
   486  		},
   487  		Embed0p: Embed0p{
   488  			Point: image.Point{X: 15, Y: 16},
   489  		},
   490  		Embed0q: Embed0q{
   491  			Point: Point{Z: 17},
   492  		},
   493  	}
   494  	b, err := Marshal(top)
   495  	if err != nil {
   496  		t.Fatal(err)
   497  	}
   498  	want := "{\"Level0\":1,\"Level1b\":2,\"Level1c\":3,\"Level1a\":5,\"LEVEL1B\":6,\"e\":{\"Level1a\":8,\"Level1b\":9,\"Level1c\":10,\"Level1d\":11,\"x\":12},\"Loop1\":13,\"Loop2\":14,\"X\":15,\"Y\":16,\"Z\":17}"
   499  	if string(b) != want {
   500  		t.Errorf("Wrong marshal result.\n got: %q\nwant: %q", b, want)
   501  	}
   502  }
   503  
   504  func TestUnmarshal(t *testing.T) {
   505  	for i, tt := range unmarshalTests {
   506  		var scan scanner
   507  		in := []byte(tt.in)
   508  		if err := checkValid(in, &scan); err != nil {
   509  			if !reflect.DeepEqual(err, tt.err) {
   510  				t.Errorf("#%d: checkValid: %#v", i, err)
   511  				continue
   512  			}
   513  		}
   514  		if tt.ptr == nil {
   515  			continue
   516  		}
   517  		// v = new(right-type)
   518  		v := reflect.New(reflect.TypeOf(tt.ptr).Elem())
   519  		dec := NewDecoder(bytes.NewReader(in))
   520  		if tt.useNumber {
   521  			dec.UseNumber()
   522  		}
   523  		if err := dec.Decode(v.Interface()); !reflect.DeepEqual(err, tt.err) {
   524  			t.Errorf("#%d: %v want %v", i, err, tt.err)
   525  			continue
   526  		}
   527  		if !reflect.DeepEqual(v.Elem().Interface(), tt.out) {
   528  			t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), tt.out)
   529  			data, _ := Marshal(v.Elem().Interface())
   530  			println(string(data))
   531  			data, _ = Marshal(tt.out)
   532  			println(string(data))
   533  			continue
   534  		}
   535  
   536  		// Check round trip.
   537  		if tt.err == nil {
   538  			enc, err := Marshal(v.Interface())
   539  			if err != nil {
   540  				t.Errorf("#%d: error re-marshaling: %v", i, err)
   541  				continue
   542  			}
   543  			vv := reflect.New(reflect.TypeOf(tt.ptr).Elem())
   544  			dec = NewDecoder(bytes.NewReader(enc))
   545  			if tt.useNumber {
   546  				dec.UseNumber()
   547  			}
   548  			if err := dec.Decode(vv.Interface()); err != nil {
   549  				t.Errorf("#%d: error re-unmarshaling %#q: %v", i, enc, err)
   550  				continue
   551  			}
   552  			if !reflect.DeepEqual(v.Elem().Interface(), vv.Elem().Interface()) {
   553  				t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), vv.Elem().Interface())
   554  				t.Errorf("     In: %q", strings.Map(noSpace, string(in)))
   555  				t.Errorf("Marshal: %q", strings.Map(noSpace, string(enc)))
   556  				continue
   557  			}
   558  		}
   559  	}
   560  }
   561  
   562  func TestUnmarshalMarshal(t *testing.T) {
   563  	initBig()
   564  	var v interface{}
   565  	if err := Unmarshal(jsonBig, &v); err != nil {
   566  		t.Fatalf("Unmarshal: %v", err)
   567  	}
   568  	b, err := Marshal(v)
   569  	if err != nil {
   570  		t.Fatalf("Marshal: %v", err)
   571  	}
   572  	if !bytes.Equal(jsonBig, b) {
   573  		t.Errorf("Marshal jsonBig")
   574  		diff(t, b, jsonBig)
   575  		return
   576  	}
   577  }
   578  
   579  var numberTests = []struct {
   580  	in       string
   581  	i        int64
   582  	intErr   string
   583  	f        float64
   584  	floatErr string
   585  }{
   586  	{in: "-1.23e1", intErr: "strconv.ParseInt: parsing \"-1.23e1\": invalid syntax", f: -1.23e1},
   587  	{in: "-12", i: -12, f: -12.0},
   588  	{in: "1e1000", intErr: "strconv.ParseInt: parsing \"1e1000\": invalid syntax", floatErr: "strconv.ParseFloat: parsing \"1e1000\": value out of range"},
   589  }
   590  
   591  // Independent of Decode, basic coverage of the accessors in Number
   592  func TestNumberAccessors(t *testing.T) {
   593  	for _, tt := range numberTests {
   594  		n := Number(tt.in)
   595  		if s := n.String(); s != tt.in {
   596  			t.Errorf("Number(%q).String() is %q", tt.in, s)
   597  		}
   598  		if i, err := n.Int64(); err == nil && tt.intErr == "" && i != tt.i {
   599  			t.Errorf("Number(%q).Int64() is %d", tt.in, i)
   600  		} else if (err == nil && tt.intErr != "") || (err != nil && err.Error() != tt.intErr) {
   601  			t.Errorf("Number(%q).Int64() wanted error %q but got: %v", tt.in, tt.intErr, err)
   602  		}
   603  		if f, err := n.Float64(); err == nil && tt.floatErr == "" && f != tt.f {
   604  			t.Errorf("Number(%q).Float64() is %g", tt.in, f)
   605  		} else if (err == nil && tt.floatErr != "") || (err != nil && err.Error() != tt.floatErr) {
   606  			t.Errorf("Number(%q).Float64() wanted error %q but got: %v", tt.in, tt.floatErr, err)
   607  		}
   608  	}
   609  }
   610  
   611  func TestLargeByteSlice(t *testing.T) {
   612  	s0 := make([]byte, 2000)
   613  	for i := range s0 {
   614  		s0[i] = byte(i)
   615  	}
   616  	b, err := Marshal(s0)
   617  	if err != nil {
   618  		t.Fatalf("Marshal: %v", err)
   619  	}
   620  	var s1 []byte
   621  	if err := Unmarshal(b, &s1); err != nil {
   622  		t.Fatalf("Unmarshal: %v", err)
   623  	}
   624  	if !bytes.Equal(s0, s1) {
   625  		t.Errorf("Marshal large byte slice")
   626  		diff(t, s0, s1)
   627  	}
   628  }
   629  
   630  type Xint struct {
   631  	X int
   632  }
   633  
   634  func TestUnmarshalInterface(t *testing.T) {
   635  	var xint Xint
   636  	var i interface{} = &xint
   637  	if err := Unmarshal([]byte(`{"X":1}`), &i); err != nil {
   638  		t.Fatalf("Unmarshal: %v", err)
   639  	}
   640  	if xint.X != 1 {
   641  		t.Fatalf("Did not write to xint")
   642  	}
   643  }
   644  
   645  func TestUnmarshalPtrPtr(t *testing.T) {
   646  	var xint Xint
   647  	pxint := &xint
   648  	if err := Unmarshal([]byte(`{"X":1}`), &pxint); err != nil {
   649  		t.Fatalf("Unmarshal: %v", err)
   650  	}
   651  	if xint.X != 1 {
   652  		t.Fatalf("Did not write to xint")
   653  	}
   654  }
   655  
   656  func TestEscape(t *testing.T) {
   657  	const input = `"foobar"<html>` + " [\u2028 \u2029]"
   658  	const expected = `"\"foobar\"\u003chtml\u003e [\u2028 \u2029]"`
   659  	b, err := Marshal(input)
   660  	if err != nil {
   661  		t.Fatalf("Marshal error: %v", err)
   662  	}
   663  	if s := string(b); s != expected {
   664  		t.Errorf("Encoding of [%s]:\n got [%s]\nwant [%s]", input, s, expected)
   665  	}
   666  }
   667  
   668  // WrongString is a struct that's misusing the ,string modifier.
   669  type WrongString struct {
   670  	Message string `json:"result,string"`
   671  }
   672  
   673  type wrongStringTest struct {
   674  	in, err string
   675  }
   676  
   677  var wrongStringTests = []wrongStringTest{
   678  	{`{"result":"x"}`, `json: invalid use of ,string struct tag, trying to unmarshal "x" into string`},
   679  	{`{"result":"foo"}`, `json: invalid use of ,string struct tag, trying to unmarshal "foo" into string`},
   680  	{`{"result":"123"}`, `json: invalid use of ,string struct tag, trying to unmarshal "123" into string`},
   681  }
   682  
   683  // If people misuse the ,string modifier, the error message should be
   684  // helpful, telling the user that they're doing it wrong.
   685  func TestErrorMessageFromMisusedString(t *testing.T) {
   686  	for n, tt := range wrongStringTests {
   687  		r := strings.NewReader(tt.in)
   688  		var s WrongString
   689  		err := NewDecoder(r).Decode(&s)
   690  		got := fmt.Sprintf("%v", err)
   691  		if got != tt.err {
   692  			t.Errorf("%d. got err = %q, want %q", n, got, tt.err)
   693  		}
   694  	}
   695  }
   696  
   697  func noSpace(c rune) rune {
   698  	if isSpace(c) {
   699  		return -1
   700  	}
   701  	return c
   702  }
   703  
   704  type All struct {
   705  	Bool    bool
   706  	Int     int
   707  	Int8    int8
   708  	Int16   int16
   709  	Int32   int32
   710  	Int64   int64
   711  	Uint    uint
   712  	Uint8   uint8
   713  	Uint16  uint16
   714  	Uint32  uint32
   715  	Uint64  uint64
   716  	Uintptr uintptr
   717  	Float32 float32
   718  	Float64 float64
   719  
   720  	Foo  string `json:"bar"`
   721  	Foo2 string `json:"bar2,dummyopt"`
   722  
   723  	IntStr int64 `json:",string"`
   724  
   725  	PBool    *bool
   726  	PInt     *int
   727  	PInt8    *int8
   728  	PInt16   *int16
   729  	PInt32   *int32
   730  	PInt64   *int64
   731  	PUint    *uint
   732  	PUint8   *uint8
   733  	PUint16  *uint16
   734  	PUint32  *uint32
   735  	PUint64  *uint64
   736  	PUintptr *uintptr
   737  	PFloat32 *float32
   738  	PFloat64 *float64
   739  
   740  	String  string
   741  	PString *string
   742  
   743  	Map   map[string]Small
   744  	MapP  map[string]*Small
   745  	PMap  *map[string]Small
   746  	PMapP *map[string]*Small
   747  
   748  	EmptyMap map[string]Small
   749  	NilMap   map[string]Small
   750  
   751  	Slice   []Small
   752  	SliceP  []*Small
   753  	PSlice  *[]Small
   754  	PSliceP *[]*Small
   755  
   756  	EmptySlice []Small
   757  	NilSlice   []Small
   758  
   759  	StringSlice []string
   760  	ByteSlice   []byte
   761  
   762  	Small   Small
   763  	PSmall  *Small
   764  	PPSmall **Small
   765  
   766  	Interface  interface{}
   767  	PInterface *interface{}
   768  
   769  	unexported int
   770  }
   771  
   772  type Small struct {
   773  	Tag string
   774  }
   775  
   776  var allValue = All{
   777  	Bool:    true,
   778  	Int:     2,
   779  	Int8:    3,
   780  	Int16:   4,
   781  	Int32:   5,
   782  	Int64:   6,
   783  	Uint:    7,
   784  	Uint8:   8,
   785  	Uint16:  9,
   786  	Uint32:  10,
   787  	Uint64:  11,
   788  	Uintptr: 12,
   789  	Float32: 14.1,
   790  	Float64: 15.1,
   791  	Foo:     "foo",
   792  	Foo2:    "foo2",
   793  	IntStr:  42,
   794  	String:  "16",
   795  	Map: map[string]Small{
   796  		"17": {Tag: "tag17"},
   797  		"18": {Tag: "tag18"},
   798  	},
   799  	MapP: map[string]*Small{
   800  		"19": {Tag: "tag19"},
   801  		"20": nil,
   802  	},
   803  	EmptyMap:    map[string]Small{},
   804  	Slice:       []Small{{Tag: "tag20"}, {Tag: "tag21"}},
   805  	SliceP:      []*Small{{Tag: "tag22"}, nil, {Tag: "tag23"}},
   806  	EmptySlice:  []Small{},
   807  	StringSlice: []string{"str24", "str25", "str26"},
   808  	ByteSlice:   []byte{27, 28, 29},
   809  	Small:       Small{Tag: "tag30"},
   810  	PSmall:      &Small{Tag: "tag31"},
   811  	Interface:   5.2,
   812  }
   813  
   814  var pallValue = All{
   815  	PBool:      &allValue.Bool,
   816  	PInt:       &allValue.Int,
   817  	PInt8:      &allValue.Int8,
   818  	PInt16:     &allValue.Int16,
   819  	PInt32:     &allValue.Int32,
   820  	PInt64:     &allValue.Int64,
   821  	PUint:      &allValue.Uint,
   822  	PUint8:     &allValue.Uint8,
   823  	PUint16:    &allValue.Uint16,
   824  	PUint32:    &allValue.Uint32,
   825  	PUint64:    &allValue.Uint64,
   826  	PUintptr:   &allValue.Uintptr,
   827  	PFloat32:   &allValue.Float32,
   828  	PFloat64:   &allValue.Float64,
   829  	PString:    &allValue.String,
   830  	PMap:       &allValue.Map,
   831  	PMapP:      &allValue.MapP,
   832  	PSlice:     &allValue.Slice,
   833  	PSliceP:    &allValue.SliceP,
   834  	PPSmall:    &allValue.PSmall,
   835  	PInterface: &allValue.Interface,
   836  }
   837  
   838  var allValueIndent = `{
   839  	"Bool": true,
   840  	"Int": 2,
   841  	"Int8": 3,
   842  	"Int16": 4,
   843  	"Int32": 5,
   844  	"Int64": 6,
   845  	"Uint": 7,
   846  	"Uint8": 8,
   847  	"Uint16": 9,
   848  	"Uint32": 10,
   849  	"Uint64": 11,
   850  	"Uintptr": 12,
   851  	"Float32": 14.1,
   852  	"Float64": 15.1,
   853  	"bar": "foo",
   854  	"bar2": "foo2",
   855  	"IntStr": "42",
   856  	"PBool": null,
   857  	"PInt": null,
   858  	"PInt8": null,
   859  	"PInt16": null,
   860  	"PInt32": null,
   861  	"PInt64": null,
   862  	"PUint": null,
   863  	"PUint8": null,
   864  	"PUint16": null,
   865  	"PUint32": null,
   866  	"PUint64": null,
   867  	"PUintptr": null,
   868  	"PFloat32": null,
   869  	"PFloat64": null,
   870  	"String": "16",
   871  	"PString": null,
   872  	"Map": {
   873  		"17": {
   874  			"Tag": "tag17"
   875  		},
   876  		"18": {
   877  			"Tag": "tag18"
   878  		}
   879  	},
   880  	"MapP": {
   881  		"19": {
   882  			"Tag": "tag19"
   883  		},
   884  		"20": null
   885  	},
   886  	"PMap": null,
   887  	"PMapP": null,
   888  	"EmptyMap": {},
   889  	"NilMap": null,
   890  	"Slice": [
   891  		{
   892  			"Tag": "tag20"
   893  		},
   894  		{
   895  			"Tag": "tag21"
   896  		}
   897  	],
   898  	"SliceP": [
   899  		{
   900  			"Tag": "tag22"
   901  		},
   902  		null,
   903  		{
   904  			"Tag": "tag23"
   905  		}
   906  	],
   907  	"PSlice": null,
   908  	"PSliceP": null,
   909  	"EmptySlice": [],
   910  	"NilSlice": null,
   911  	"StringSlice": [
   912  		"str24",
   913  		"str25",
   914  		"str26"
   915  	],
   916  	"ByteSlice": "Gxwd",
   917  	"Small": {
   918  		"Tag": "tag30"
   919  	},
   920  	"PSmall": {
   921  		"Tag": "tag31"
   922  	},
   923  	"PPSmall": null,
   924  	"Interface": 5.2,
   925  	"PInterface": null
   926  }`
   927  
   928  var allValueCompact = strings.Map(noSpace, allValueIndent)
   929  
   930  var pallValueIndent = `{
   931  	"Bool": false,
   932  	"Int": 0,
   933  	"Int8": 0,
   934  	"Int16": 0,
   935  	"Int32": 0,
   936  	"Int64": 0,
   937  	"Uint": 0,
   938  	"Uint8": 0,
   939  	"Uint16": 0,
   940  	"Uint32": 0,
   941  	"Uint64": 0,
   942  	"Uintptr": 0,
   943  	"Float32": 0,
   944  	"Float64": 0,
   945  	"bar": "",
   946  	"bar2": "",
   947          "IntStr": "0",
   948  	"PBool": true,
   949  	"PInt": 2,
   950  	"PInt8": 3,
   951  	"PInt16": 4,
   952  	"PInt32": 5,
   953  	"PInt64": 6,
   954  	"PUint": 7,
   955  	"PUint8": 8,
   956  	"PUint16": 9,
   957  	"PUint32": 10,
   958  	"PUint64": 11,
   959  	"PUintptr": 12,
   960  	"PFloat32": 14.1,
   961  	"PFloat64": 15.1,
   962  	"String": "",
   963  	"PString": "16",
   964  	"Map": null,
   965  	"MapP": null,
   966  	"PMap": {
   967  		"17": {
   968  			"Tag": "tag17"
   969  		},
   970  		"18": {
   971  			"Tag": "tag18"
   972  		}
   973  	},
   974  	"PMapP": {
   975  		"19": {
   976  			"Tag": "tag19"
   977  		},
   978  		"20": null
   979  	},
   980  	"EmptyMap": null,
   981  	"NilMap": null,
   982  	"Slice": null,
   983  	"SliceP": null,
   984  	"PSlice": [
   985  		{
   986  			"Tag": "tag20"
   987  		},
   988  		{
   989  			"Tag": "tag21"
   990  		}
   991  	],
   992  	"PSliceP": [
   993  		{
   994  			"Tag": "tag22"
   995  		},
   996  		null,
   997  		{
   998  			"Tag": "tag23"
   999  		}
  1000  	],
  1001  	"EmptySlice": null,
  1002  	"NilSlice": null,
  1003  	"StringSlice": null,
  1004  	"ByteSlice": null,
  1005  	"Small": {
  1006  		"Tag": ""
  1007  	},
  1008  	"PSmall": null,
  1009  	"PPSmall": {
  1010  		"Tag": "tag31"
  1011  	},
  1012  	"Interface": null,
  1013  	"PInterface": 5.2
  1014  }`
  1015  
  1016  var pallValueCompact = strings.Map(noSpace, pallValueIndent)
  1017  
  1018  func TestRefUnmarshal(t *testing.T) {
  1019  	type S struct {
  1020  		// Ref is defined in encode_test.go.
  1021  		R0 Ref
  1022  		R1 *Ref
  1023  		R2 RefText
  1024  		R3 *RefText
  1025  	}
  1026  	want := S{
  1027  		R0: 12,
  1028  		R1: new(Ref),
  1029  		R2: 13,
  1030  		R3: new(RefText),
  1031  	}
  1032  	*want.R1 = 12
  1033  	*want.R3 = 13
  1034  
  1035  	var got S
  1036  	if err := Unmarshal([]byte(`{"R0":"ref","R1":"ref","R2":"ref","R3":"ref"}`), &got); err != nil {
  1037  		t.Fatalf("Unmarshal: %v", err)
  1038  	}
  1039  	if !reflect.DeepEqual(got, want) {
  1040  		t.Errorf("got %+v, want %+v", got, want)
  1041  	}
  1042  }
  1043  
  1044  // Test that the empty string doesn't panic decoding when ,string is specified
  1045  // Issue 3450
  1046  func TestEmptyString(t *testing.T) {
  1047  	type T2 struct {
  1048  		Number1 int `json:",string"`
  1049  		Number2 int `json:",string"`
  1050  	}
  1051  	data := `{"Number1":"1", "Number2":""}`
  1052  	dec := NewDecoder(strings.NewReader(data))
  1053  	var t2 T2
  1054  	err := dec.Decode(&t2)
  1055  	if err == nil {
  1056  		t.Fatal("Decode: did not return error")
  1057  	}
  1058  	if t2.Number1 != 1 {
  1059  		t.Fatal("Decode: did not set Number1")
  1060  	}
  1061  }
  1062  
  1063  // Test that the returned error is non-nil when trying to unmarshal null string into int, for successive ,string option
  1064  // Issue 7046
  1065  func TestNullString(t *testing.T) {
  1066  	type T struct {
  1067  		A int `json:",string"`
  1068  		B int `json:",string"`
  1069  	}
  1070  	data := []byte(`{"A": "1", "B": null}`)
  1071  	var s T
  1072  	err := Unmarshal(data, &s)
  1073  	if err == nil {
  1074  		t.Fatalf("expected error; got %v", s)
  1075  	}
  1076  }
  1077  
  1078  func intp(x int) *int {
  1079  	p := new(int)
  1080  	*p = x
  1081  	return p
  1082  }
  1083  
  1084  func intpp(x *int) **int {
  1085  	pp := new(*int)
  1086  	*pp = x
  1087  	return pp
  1088  }
  1089  
  1090  var interfaceSetTests = []struct {
  1091  	pre  interface{}
  1092  	json string
  1093  	post interface{}
  1094  }{
  1095  	{"foo", `"bar"`, "bar"},
  1096  	{"foo", `2`, 2.0},
  1097  	{"foo", `true`, true},
  1098  	{"foo", `null`, nil},
  1099  
  1100  	{nil, `null`, nil},
  1101  	{new(int), `null`, nil},
  1102  	{(*int)(nil), `null`, nil},
  1103  	{new(*int), `null`, new(*int)},
  1104  	{(**int)(nil), `null`, nil},
  1105  	{intp(1), `null`, nil},
  1106  	{intpp(nil), `null`, intpp(nil)},
  1107  	{intpp(intp(1)), `null`, intpp(nil)},
  1108  }
  1109  
  1110  func TestInterfaceSet(t *testing.T) {
  1111  	for _, tt := range interfaceSetTests {
  1112  		b := struct{ X interface{} }{tt.pre}
  1113  		blob := `{"X":` + tt.json + `}`
  1114  		if err := Unmarshal([]byte(blob), &b); err != nil {
  1115  			t.Errorf("Unmarshal %#q: %v", blob, err)
  1116  			continue
  1117  		}
  1118  		if !reflect.DeepEqual(b.X, tt.post) {
  1119  			t.Errorf("Unmarshal %#q into %#v: X=%#v, want %#v", blob, tt.pre, b.X, tt.post)
  1120  		}
  1121  	}
  1122  }
  1123  
  1124  // JSON null values should be ignored for primitives and string values instead of resulting in an error.
  1125  // Issue 2540
  1126  func TestUnmarshalNulls(t *testing.T) {
  1127  	jsonData := []byte(`{
  1128  		"Bool"    : null,
  1129  		"Int"     : null,
  1130  		"Int8"    : null,
  1131  		"Int16"   : null,
  1132  		"Int32"   : null,
  1133  		"Int64"   : null,
  1134  		"Uint"    : null,
  1135  		"Uint8"   : null,
  1136  		"Uint16"  : null,
  1137  		"Uint32"  : null,
  1138  		"Uint64"  : null,
  1139  		"Float32" : null,
  1140  		"Float64" : null,
  1141  		"String"  : null}`)
  1142  
  1143  	nulls := All{
  1144  		Bool:    true,
  1145  		Int:     2,
  1146  		Int8:    3,
  1147  		Int16:   4,
  1148  		Int32:   5,
  1149  		Int64:   6,
  1150  		Uint:    7,
  1151  		Uint8:   8,
  1152  		Uint16:  9,
  1153  		Uint32:  10,
  1154  		Uint64:  11,
  1155  		Float32: 12.1,
  1156  		Float64: 13.1,
  1157  		String:  "14"}
  1158  
  1159  	err := Unmarshal(jsonData, &nulls)
  1160  	if err != nil {
  1161  		t.Errorf("Unmarshal of null values failed: %v", err)
  1162  	}
  1163  	if !nulls.Bool || nulls.Int != 2 || nulls.Int8 != 3 || nulls.Int16 != 4 || nulls.Int32 != 5 || nulls.Int64 != 6 ||
  1164  		nulls.Uint != 7 || nulls.Uint8 != 8 || nulls.Uint16 != 9 || nulls.Uint32 != 10 || nulls.Uint64 != 11 ||
  1165  		nulls.Float32 != 12.1 || nulls.Float64 != 13.1 || nulls.String != "14" {
  1166  
  1167  		t.Errorf("Unmarshal of null values affected primitives")
  1168  	}
  1169  }
  1170  
  1171  func TestStringKind(t *testing.T) {
  1172  	type stringKind string
  1173  
  1174  	var m1, m2 map[stringKind]int
  1175  	m1 = map[stringKind]int{
  1176  		"foo": 42,
  1177  	}
  1178  
  1179  	data, err := Marshal(m1)
  1180  	if err != nil {
  1181  		t.Errorf("Unexpected error marshalling: %v", err)
  1182  	}
  1183  
  1184  	err = Unmarshal(data, &m2)
  1185  	if err != nil {
  1186  		t.Errorf("Unexpected error unmarshalling: %v", err)
  1187  	}
  1188  
  1189  	if !reflect.DeepEqual(m1, m2) {
  1190  		t.Error("Items should be equal after encoding and then decoding")
  1191  	}
  1192  
  1193  }
  1194  
  1195  var decodeTypeErrorTests = []struct {
  1196  	dest interface{}
  1197  	src  string
  1198  }{
  1199  	{new(string), `{"user": "name"}`}, // issue 4628.
  1200  	{new(error), `{}`},                // issue 4222
  1201  	{new(error), `[]`},
  1202  	{new(error), `""`},
  1203  	{new(error), `123`},
  1204  	{new(error), `true`},
  1205  }
  1206  
  1207  func TestUnmarshalTypeError(t *testing.T) {
  1208  	for _, item := range decodeTypeErrorTests {
  1209  		err := Unmarshal([]byte(item.src), item.dest)
  1210  		if _, ok := err.(*UnmarshalTypeError); !ok {
  1211  			t.Errorf("expected type error for Unmarshal(%q, type %T): got %T",
  1212  				item.src, item.dest, err)
  1213  		}
  1214  	}
  1215  }
  1216  
  1217  var unmarshalSyntaxTests = []string{
  1218  	"tru",
  1219  	"fals",
  1220  	"nul",
  1221  	"123e",
  1222  	`"hello`,
  1223  	`[1,2,3`,
  1224  	`{"key":1`,
  1225  	`{"key":1,`,
  1226  }
  1227  
  1228  func TestUnmarshalSyntax(t *testing.T) {
  1229  	var x interface{}
  1230  	for _, src := range unmarshalSyntaxTests {
  1231  		err := Unmarshal([]byte(src), &x)
  1232  		if _, ok := err.(*SyntaxError); !ok {
  1233  			t.Errorf("expected syntax error for Unmarshal(%q): got %T", src, err)
  1234  		}
  1235  	}
  1236  }
  1237  
  1238  // Test handling of unexported fields that should be ignored.
  1239  // Issue 4660
  1240  type unexportedFields struct {
  1241  	Name string
  1242  	m    map[string]interface{} `json:"-"`
  1243  	m2   map[string]interface{} `json:"abcd"`
  1244  }
  1245  
  1246  func TestUnmarshalUnexported(t *testing.T) {
  1247  	input := `{"Name": "Bob", "m": {"x": 123}, "m2": {"y": 456}, "abcd": {"z": 789}}`
  1248  	want := &unexportedFields{Name: "Bob"}
  1249  
  1250  	out := &unexportedFields{}
  1251  	err := Unmarshal([]byte(input), out)
  1252  	if err != nil {
  1253  		t.Errorf("got error %v, expected nil", err)
  1254  	}
  1255  	if !reflect.DeepEqual(out, want) {
  1256  		t.Errorf("got %q, want %q", out, want)
  1257  	}
  1258  }
  1259  
  1260  // Time3339 is a time.Time which encodes to and from JSON
  1261  // as an RFC 3339 time in UTC.
  1262  type Time3339 time.Time
  1263  
  1264  func (t *Time3339) UnmarshalJSON(b []byte) error {
  1265  	if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' {
  1266  		return fmt.Errorf("types: failed to unmarshal non-string value %q as an RFC 3339 time", b)
  1267  	}
  1268  	tm, err := time.Parse(time.RFC3339, string(b[1:len(b)-1]))
  1269  	if err != nil {
  1270  		return err
  1271  	}
  1272  	*t = Time3339(tm)
  1273  	return nil
  1274  }
  1275  
  1276  func TestUnmarshalJSONLiteralError(t *testing.T) {
  1277  	var t3 Time3339
  1278  	err := Unmarshal([]byte(`"0000-00-00T00:00:00Z"`), &t3)
  1279  	if err == nil {
  1280  		t.Fatalf("expected error; got time %v", time.Time(t3))
  1281  	}
  1282  	if !strings.Contains(err.Error(), "range") {
  1283  		t.Errorf("got err = %v; want out of range error", err)
  1284  	}
  1285  }
  1286  
  1287  // Test that extra object elements in an array do not result in a
  1288  // "data changing underfoot" error.
  1289  // Issue 3717
  1290  func TestSkipArrayObjects(t *testing.T) {
  1291  	json := `[{}]`
  1292  	var dest [0]interface{}
  1293  
  1294  	err := Unmarshal([]byte(json), &dest)
  1295  	if err != nil {
  1296  		t.Errorf("got error %q, want nil", err)
  1297  	}
  1298  }
  1299  
  1300  // Test semantics of pre-filled struct fields and pre-filled map fields.
  1301  // Issue 4900.
  1302  func TestPrefilled(t *testing.T) {
  1303  	ptrToMap := func(m map[string]interface{}) *map[string]interface{} { return &m }
  1304  
  1305  	// Values here change, cannot reuse table across runs.
  1306  	var prefillTests = []struct {
  1307  		in  string
  1308  		ptr interface{}
  1309  		out interface{}
  1310  	}{
  1311  		{
  1312  			in:  `{"X": 1, "Y": 2}`,
  1313  			ptr: &XYZ{X: float32(3), Y: int16(4), Z: 1.5},
  1314  			out: &XYZ{X: float64(1), Y: float64(2), Z: 1.5},
  1315  		},
  1316  		{
  1317  			in:  `{"X": 1, "Y": 2}`,
  1318  			ptr: ptrToMap(map[string]interface{}{"X": float32(3), "Y": int16(4), "Z": 1.5}),
  1319  			out: ptrToMap(map[string]interface{}{"X": float64(1), "Y": float64(2), "Z": 1.5}),
  1320  		},
  1321  	}
  1322  
  1323  	for _, tt := range prefillTests {
  1324  		ptrstr := fmt.Sprintf("%v", tt.ptr)
  1325  		err := Unmarshal([]byte(tt.in), tt.ptr) // tt.ptr edited here
  1326  		if err != nil {
  1327  			t.Errorf("Unmarshal: %v", err)
  1328  		}
  1329  		if !reflect.DeepEqual(tt.ptr, tt.out) {
  1330  			t.Errorf("Unmarshal(%#q, %s): have %v, want %v", tt.in, ptrstr, tt.ptr, tt.out)
  1331  		}
  1332  	}
  1333  }
  1334  
  1335  var invalidUnmarshalTests = []struct {
  1336  	v    interface{}
  1337  	want string
  1338  }{
  1339  	{nil, "json: Unmarshal(nil)"},
  1340  	{struct{}{}, "json: Unmarshal(non-pointer struct {})"},
  1341  	{(*int)(nil), "json: Unmarshal(nil *int)"},
  1342  }
  1343  
  1344  func TestInvalidUnmarshal(t *testing.T) {
  1345  	buf := []byte(`{"a":"1"}`)
  1346  	for _, tt := range invalidUnmarshalTests {
  1347  		err := Unmarshal(buf, tt.v)
  1348  		if err == nil {
  1349  			t.Errorf("Unmarshal expecting error, got nil")
  1350  			continue
  1351  		}
  1352  		if got := err.Error(); got != tt.want {
  1353  			t.Errorf("Unmarshal = %q; want %q", got, tt.want)
  1354  		}
  1355  	}
  1356  }