github.com/wI2L/jettison@v0.7.4/json_test.go (about)

     1  package jettison
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"crypto/rand"
     7  	"encoding/json"
     8  	"errors"
     9  	"fmt"
    10  	"math"
    11  	"math/big"
    12  	"net"
    13  	"reflect"
    14  	"regexp"
    15  	"strconv"
    16  	"sync"
    17  	"testing"
    18  	"time"
    19  )
    20  
    21  type (
    22  	jmr string
    23  	jmv []string
    24  )
    25  
    26  func (*jmr) MarshalJSON() ([]byte, error) { return []byte(`"XYZ"`), nil }
    27  func (jmv) MarshalJSON() ([]byte, error)  { return []byte(`"ZYX"`), nil }
    28  
    29  type (
    30  	mapss struct {
    31  		M map[string]string
    32  	}
    33  	inner struct {
    34  		M map[string]string
    35  	}
    36  	outer struct {
    37  		M map[string]inner
    38  	}
    39  	z struct {
    40  		S []byte
    41  	}
    42  	y struct {
    43  		P float64 `json:"p,omitempty"`
    44  		Q uint64  `json:"q,omitempty"`
    45  		R uint8
    46  	}
    47  	x struct {
    48  		A  *string `json:"a,string"`
    49  		B1 int64   `json:"b1,string"`
    50  		B2 uint16  `json:"b2"`
    51  		C  *bool   `json:"c,string"`
    52  		D  float32
    53  		E1 *[]int
    54  		E2 []string
    55  		E3 []jmr
    56  		F1 [4]string
    57  		F2 [1]jmr
    58  		F3 *[1]jmr
    59  		G1 map[int]*string
    60  		G2 map[string]*map[string]string
    61  		G3 map[int]map[string]map[int]string
    62  		G4 map[string]mapss
    63  		G5 outer
    64  		G6 map[int]jmr
    65  		G7 map[int]*jmr
    66  		G8 map[int]bool `json:",omitempty"`
    67  		H1 jmr
    68  		H2 *jmr
    69  		H3 jmv
    70  		H4 *jmv
    71  		I  time.Time
    72  		J  time.Duration
    73  		K  json.Number
    74  		L  json.RawMessage
    75  		M1 interface{}
    76  		M2 interface{}
    77  		N  struct{}
    78  		X  *x
    79  		*y
    80  		z `json:"z"`
    81  	}
    82  )
    83  
    84  var (
    85  	s  = "Loreum"
    86  	b  = true
    87  	m  = map[string]string{"b": "c"}
    88  	xx = x{
    89  		A:  &s,
    90  		B1: -42,
    91  		B2: 42,
    92  		C:  &b,
    93  		D:  math.MaxFloat32,
    94  		E1: &[]int{1, 2, 3},
    95  		E2: []string{"x", "y", "z"},
    96  		E3: []jmr{"1"},
    97  		F1: [4]string{"a", "b", "c", "d"},
    98  		F2: [1]jmr{"1"},
    99  		F3: &[1]jmr{"1"},
   100  		G1: map[int]*string{2: &s, 3: new(string)},
   101  		G2: map[string]*map[string]string{"a": &m},
   102  		G3: map[int]map[string]map[int]string{1: {"a": {2: "b"}}},
   103  		G4: map[string]mapss{"1": {M: map[string]string{"2": "3"}}},
   104  		G5: outer{map[string]inner{"outer": {map[string]string{"key": "val"}}}},
   105  		G6: map[int]jmr{1: "jmr"},
   106  		G7: map[int]*jmr{1: new(jmr)},
   107  		G8: map[int]bool{},
   108  		H1: "jmp",
   109  		H2: nil,
   110  		H3: nil,
   111  		H4: nil,
   112  		I:  time.Now(),
   113  		J:  3 * time.Minute,
   114  		K:  "3.14",
   115  		L:  []byte(`{ "a":"b" }`),
   116  		M1: uint32(255),
   117  		M2: &s,
   118  		X:  &x{H1: "jmv"},
   119  		y:  &y{R: math.MaxUint8},
   120  		z:  z{S: []byte("Loreum")},
   121  	}
   122  )
   123  
   124  // marshalCompare compares the JSON encoding
   125  // of v between Jettison and encoding/json.
   126  func marshalCompare(t *testing.T, v interface{}, name string) {
   127  	jb1, err := Marshal(v)
   128  	if err != nil {
   129  		t.Fatal(err)
   130  	}
   131  	jb2, err := MarshalOpts(v)
   132  	if err != nil {
   133  		t.Fatal(err)
   134  	}
   135  	if !bytes.Equal(jb1, jb2) {
   136  		t.Error("non-equal outputs for Marshal and MarshalOpts")
   137  	}
   138  	jb3, err := Append([]byte(nil), v)
   139  	if err != nil {
   140  		t.Fatal(err)
   141  	}
   142  	if !bytes.Equal(jb1, jb3) {
   143  		t.Error("non-equal outputs for Marshal and Append")
   144  	}
   145  	sb, err := json.Marshal(v)
   146  	if err != nil {
   147  		t.Fatal(err)
   148  	}
   149  	t.Logf("standard: %s", string(sb))
   150  	t.Logf("jettison: %s", string(jb1))
   151  
   152  	if !bytes.Equal(jb1, sb) {
   153  		t.Errorf("%s: non-equal outputs", name)
   154  	}
   155  }
   156  
   157  func marshalCompareError(t *testing.T, v interface{}, name string) {
   158  	_, errj := Marshal(v)
   159  	if errj == nil {
   160  		t.Fatalf("expected non-nil error")
   161  	}
   162  	_, errs := json.Marshal(v)
   163  	if errs == nil {
   164  		t.Fatalf("expected non-nil error")
   165  	}
   166  	t.Logf("standard: %s", errs)
   167  	t.Logf("jettison: %s", errj)
   168  
   169  	if errs.Error() != errj.Error() {
   170  		t.Errorf("%s: non-equal outputs", name)
   171  	}
   172  }
   173  
   174  func TestAll(t *testing.T) {
   175  	marshalCompare(t, nil, "nil")
   176  	marshalCompare(t, xx, "non-pointer")
   177  	marshalCompare(t, &xx, "pointer")
   178  }
   179  
   180  func TestInvalidEncodeOpts(t *testing.T) {
   181  	for _, opt := range []Option{
   182  		TimeLayout(""),
   183  		DurationFormat(DurationFmt(-1)),
   184  		DurationFormat(DurationFmt(6)),
   185  		WithContext(nil), // nolint:staticcheck
   186  	} {
   187  		_, err1 := MarshalOpts(struct{}{}, opt)
   188  		_, err2 := AppendOpts([]byte(nil), struct{}{}, opt)
   189  
   190  		for _, err := range []error{err1, err2} {
   191  			if err != nil {
   192  				e, ok := err.(*InvalidOptionError)
   193  				if !ok {
   194  					t.Errorf("got %T, want InvalidOptionError", err)
   195  				}
   196  				if e.Error() == "" {
   197  					t.Errorf("expected non-empty error message")
   198  				}
   199  			} else {
   200  				t.Error("expected non-nil error")
   201  			}
   202  		}
   203  	}
   204  }
   205  
   206  // TestBasicTypes tests the marshaling of basic types.
   207  func TestBasicTypes(t *testing.T) {
   208  	testdata := []interface{}{
   209  		true,
   210  		false,
   211  		"Loreum",
   212  		int8(math.MaxInt8),
   213  		int16(math.MaxInt16),
   214  		int32(math.MaxInt32),
   215  		int64(math.MaxInt64),
   216  		uint8(math.MaxUint8),
   217  		uint16(math.MaxUint16),
   218  		uint32(math.MaxUint32),
   219  		uint64(math.MaxUint64),
   220  		uintptr(0xBEEF),
   221  		(*bool)(nil),
   222  		(*int)(nil),
   223  		(*string)(nil),
   224  	}
   225  	for _, v := range testdata {
   226  		marshalCompare(t, v, "")
   227  	}
   228  }
   229  
   230  // TestCompositeTypes tests the marshaling of composite types.
   231  func TestCompositeTypes(t *testing.T) {
   232  	var (
   233  		jmref = jmr("jmr")
   234  		jmval = jmv([]string{"a", "b", "c"})
   235  	)
   236  	testdata := []interface{}{
   237  		[]uint{},
   238  		[]int{1, 2, 3},
   239  		[]int(nil),
   240  		(*[]int)(nil),
   241  		[]string{"a", "b", "c"},
   242  		[2]bool{true, false},
   243  		(*[4]string)(nil),
   244  		map[string]int{"a": 1, "b": 2},
   245  		&map[int]string{1: "a", 2: "b"},
   246  		(map[string]int)(nil),
   247  		time.Now(),
   248  		3*time.Minute + 35*time.Second,
   249  		jmref,
   250  		&jmref,
   251  		jmval,
   252  		&jmval,
   253  	}
   254  	for _, v := range testdata {
   255  		marshalCompare(t, v, "")
   256  	}
   257  }
   258  
   259  // TestUnsupportedTypes tests that marshaling an
   260  // unsupported type such as channel, complex, and
   261  // function value returns an UnsupportedTypeError.
   262  // The error message is compared with the one that
   263  // is returned by json.Marshal.
   264  func TestUnsupportedTypes(t *testing.T) {
   265  	testdata := []interface{}{
   266  		make(chan int),
   267  		func() {},
   268  		complex64(0),
   269  		complex128(0),
   270  		make([]chan int, 1),
   271  		[1]complex64{},
   272  		&[1]complex128{},
   273  		map[int]chan bool{1: make(chan bool)},
   274  		struct{ F func() }{func() {}},
   275  		&struct{ C complex64 }{0},
   276  	}
   277  	for _, v := range testdata {
   278  		marshalCompareError(t, v, "")
   279  	}
   280  }
   281  
   282  // TestInvalidFloatValues tests that encoding an
   283  // invalid float value returns UnsupportedValueError.
   284  func TestInvalidFloatValues(t *testing.T) {
   285  	for _, v := range []float64{
   286  		math.NaN(),
   287  		math.Inf(-1),
   288  		math.Inf(1),
   289  	} {
   290  		_, err := Marshal(v)
   291  		if err != nil {
   292  			if _, ok := err.(*UnsupportedValueError); !ok {
   293  				t.Errorf("got %T, want UnsupportedValueError", err)
   294  			}
   295  		} else {
   296  			t.Error("got nil, want non-nil error")
   297  		}
   298  		// Error message must be the same as
   299  		// the one of the standard library.
   300  		marshalCompareError(t, v, "")
   301  	}
   302  }
   303  
   304  // TestJSONNumber tests that a json.Number literal value
   305  // can be marshaled, and that an error is returned if it
   306  // isn't a valid number according to the JSON grammar.
   307  func TestJSONNumber(t *testing.T) {
   308  	valid := []json.Number{
   309  		"42",
   310  		"-42",
   311  		"24.42",
   312  		"-666.66",
   313  		"3.14",
   314  		"-3.14",
   315  		"1e3",
   316  		"1E-6",
   317  		"1E+42",
   318  		// Special case to keep backward
   319  		// compatibility with Go1.5, that
   320  		// encodes the empty string as "0".
   321  		"",
   322  	}
   323  	for _, v := range valid {
   324  		marshalCompare(t, v, "valid")
   325  	}
   326  	invalid := []json.Number{
   327  		"1E+4.0",
   328  		"084",
   329  		"-03.14",
   330  		"-",
   331  		"invalid",
   332  	}
   333  	for _, v := range invalid {
   334  		marshalCompareError(t, v, "invalid")
   335  	}
   336  }
   337  
   338  func TestInvalidTime(t *testing.T) {
   339  	// Special case to test error when the year
   340  	// of the date is outside of range [0.9999].
   341  	// see golang.org/issue/4556#c15.
   342  	for _, tm := range []time.Time{
   343  		time.Date(-1, time.January, 1, 0, 0, 0, 0, time.UTC),
   344  		time.Date(10000, time.January, 1, 0, 0, 0, 0, time.UTC),
   345  	} {
   346  		_, err := Marshal(tm)
   347  		if err != nil {
   348  			want := "time: year outside of range [0,9999]"
   349  			if err.Error() != want {
   350  				t.Errorf("got %q, want %q", err.Error(), want)
   351  			}
   352  		} else {
   353  			t.Error("got nil, want non-nil error")
   354  		}
   355  	}
   356  }
   357  
   358  // TestRenamedByteSlice tests that a name type
   359  // that represents a slice of bytes is marshaled
   360  // the same way as a regular byte slice.
   361  func TestRenamedByteSlice(t *testing.T) {
   362  	type (
   363  		b  byte
   364  		b1 []byte
   365  		b2 []b
   366  	)
   367  	testdata := []interface{}{
   368  		b1("byte slice 1"),
   369  		b2("byte slice 2"),
   370  	}
   371  	for _, v := range testdata {
   372  		marshalCompare(t, v, "")
   373  	}
   374  }
   375  
   376  func TestByteSliceSizes(t *testing.T) {
   377  	makeSlice := func(size int) []byte {
   378  		b := make([]byte, size)
   379  		if _, err := rand.Read(b); err != nil {
   380  			t.Fatal(err)
   381  		}
   382  		return b
   383  	}
   384  	for _, v := range []interface{}{
   385  		makeSlice(0),
   386  		makeSlice(1024),
   387  		makeSlice(2048),
   388  		makeSlice(4096),
   389  		makeSlice(8192),
   390  	} {
   391  		marshalCompare(t, v, "")
   392  	}
   393  }
   394  
   395  // TestSortedSyncMap tests the marshaling
   396  // of a sorted sync.Map value.
   397  func TestSortedSyncMap(t *testing.T) {
   398  	var sm sync.Map
   399  
   400  	sm.Store(1, "one")
   401  	sm.Store("a", 42)
   402  	sm.Store("b", false)
   403  	sm.Store(mkvstrMarshaler("c"), -42)
   404  	sm.Store(mkrstrMarshaler("d"), true)
   405  	sm.Store(mkvintMarshaler(42), 1)
   406  	sm.Store(mkrintMarshaler(42), 2)
   407  
   408  	b, err := Marshal(&sm)
   409  	if err != nil {
   410  		t.Fatal(err)
   411  	}
   412  	want := `{"1":"one","42":2,"MKVINT":1,"a":42,"b":false,"c":-42,"d":true}`
   413  
   414  	if !bytes.Equal(b, []byte(want)) {
   415  		t.Errorf("got %#q, want %#q", b, want)
   416  	}
   417  }
   418  
   419  // TestUnsortedSyncMap tests the marshaling
   420  // of an unsorted sync.Map value.
   421  func TestUnsortedSyncMap(t *testing.T) {
   422  	// entries maps each interface k/v
   423  	// pair to the string representation
   424  	// of the key in payload.
   425  	entries := map[string]struct {
   426  		key interface{}
   427  		val interface{}
   428  	}{
   429  		"1":      {1, "one"},
   430  		"a":      {"a", 42},
   431  		"b":      {"b", false},
   432  		"c":      {mkvstrMarshaler("c"), -42},
   433  		"d":      {mkrstrMarshaler("d"), true},
   434  		"MKVINT": {mkvintMarshaler(42), 1},
   435  		"42":     {mkrintMarshaler(42), 2},
   436  	}
   437  	var sm sync.Map
   438  	for _, e := range entries {
   439  		sm.Store(e.key, e.val)
   440  	}
   441  	bts, err := MarshalOpts(&sm, UnsortedMap())
   442  	if err != nil {
   443  		t.Fatal(err)
   444  	}
   445  	m := make(map[string]interface{})
   446  	if err := json.Unmarshal(bts, &m); err != nil {
   447  		t.Fatal(err)
   448  	}
   449  	// Unmarshaled map must contains exactly the
   450  	// number of entries added to the sync map.
   451  	if g, w := len(m), len(entries); g != w {
   452  		t.Errorf("invalid lengths: got %d, want %d", g, w)
   453  	}
   454  	for k, v := range m {
   455  		// Compare the marshaled representation
   456  		// of each value to avoid false-positive
   457  		// between integer and float types.
   458  		b1, err1 := json.Marshal(v)
   459  		b2, err2 := json.Marshal(entries[k].val)
   460  		if err1 != nil {
   461  			t.Fatal(err)
   462  		}
   463  		if err2 != nil {
   464  			t.Fatal(err2)
   465  		}
   466  		if !bytes.Equal(b1, b2) {
   467  			t.Errorf("for key %s: got %v, want %v", k, b1, b2)
   468  		}
   469  	}
   470  }
   471  
   472  // TestInvalidSyncMapKeys tests that marshaling a
   473  // sync.Map with unsupported key types returns an
   474  // error.
   475  func TestInvalidSyncMapKeys(t *testing.T) {
   476  	testInvalidSyncMapKeys(t, true)
   477  	testInvalidSyncMapKeys(t, false)
   478  }
   479  
   480  func testInvalidSyncMapKeys(t *testing.T, sorted bool) {
   481  	for _, f := range []func(sm *sync.Map){
   482  		func(sm *sync.Map) { sm.Store(false, nil) },
   483  		func(sm *sync.Map) { sm.Store(new(int), nil) },
   484  		func(sm *sync.Map) { sm.Store(nil, nil) },
   485  	} {
   486  		var (
   487  			sm  sync.Map
   488  			err error
   489  		)
   490  		f(&sm) // add entries to sm
   491  		if sorted {
   492  			_, err = Marshal(&sm)
   493  		} else {
   494  			_, err = MarshalOpts(&sm, UnsortedMap())
   495  		}
   496  		if err == nil {
   497  			t.Error("expected a non-nil error")
   498  		}
   499  	}
   500  }
   501  
   502  // TestCompositeMapValue tests the marshaling
   503  // of maps with composite values.
   504  func TestCompositeMapValue(t *testing.T) {
   505  	type x struct {
   506  		A string `json:"a"`
   507  		B int    `json:"b"`
   508  		C bool   `json:"c"`
   509  	}
   510  	type y []uint32
   511  
   512  	for _, v := range []interface{}{
   513  		map[string]x{
   514  			"1": {A: "A", B: 42, C: true},
   515  			"2": {A: "A", B: 84, C: false},
   516  		},
   517  		map[string]y{
   518  			"3": {7, 8, 9},
   519  			"2": {4, 5, 6},
   520  			"1": nil,
   521  		},
   522  		map[string]*x{
   523  			"b": {A: "A", B: 128, C: true},
   524  			"a": nil,
   525  			"c": {},
   526  		},
   527  		map[string]interface{}{
   528  			"1": 42,
   529  			"2": "two",
   530  			"3": nil,
   531  			"4": (*int64)(nil),
   532  			"5": x{A: "A"},
   533  			"6": &x{A: "A", B: 256, C: true},
   534  		},
   535  	} {
   536  		marshalCompare(t, v, "")
   537  	}
   538  }
   539  
   540  type (
   541  	mkstr           string
   542  	mkint           int64
   543  	mkvstrMarshaler string
   544  	mkrstrMarshaler string
   545  	mkvintMarshaler uint64
   546  	mkrintMarshaler int
   547  	mkvcmpMarshaler struct{}
   548  )
   549  
   550  func (mkvstrMarshaler) MarshalText() ([]byte, error)  { return []byte("MKVSTR"), nil }
   551  func (*mkrstrMarshaler) MarshalText() ([]byte, error) { return []byte("MKRSTR"), nil }
   552  func (mkvintMarshaler) MarshalText() ([]byte, error)  { return []byte("MKVINT"), nil }
   553  func (*mkrintMarshaler) MarshalText() ([]byte, error) { return []byte("MKRINT"), nil }
   554  func (mkvcmpMarshaler) MarshalText() ([]byte, error)  { return []byte("MKVCMP"), nil }
   555  
   556  // TestMapKeyPrecedence tests that the precedence
   557  // order of map key types is respected during marshaling.
   558  func TestMapKeyPrecedence(t *testing.T) {
   559  	testdata := []interface{}{
   560  		map[mkstr]string{"K": "V"},
   561  		map[mkint]string{1: "V"},
   562  		map[mkvstrMarshaler]string{"K": "V"},
   563  		map[mkrstrMarshaler]string{"K": "V"},
   564  		map[mkvintMarshaler]string{42: "V"},
   565  		map[mkrintMarshaler]string{1: "one"},
   566  		map[mkvcmpMarshaler]string{{}: "V"},
   567  	}
   568  	for _, v := range testdata {
   569  		marshalCompare(t, v, "")
   570  	}
   571  }
   572  
   573  // TestJSONMarshaler tests that a type implementing the
   574  // json.Marshaler interface is marshaled using the result
   575  // of its MarshalJSON method call result.
   576  // Because the types big.Int and time.Time also implements
   577  // the encoding.TextMarshaler interface, the test ensures
   578  // that MarshalJSON has priority.
   579  func TestJSONMarshaler(t *testing.T) {
   580  	type x struct {
   581  		T1 time.Time  `json:""`
   582  		T2 time.Time  `json:",omitempty"`
   583  		T3 *time.Time `json:""`
   584  		T4 *time.Time `json:""`           // nil
   585  		T5 *time.Time `json:",omitempty"` // nil
   586  		S1 bvjm       `json:",omitempty"`
   587  		S2 bvjm       `json:",omitempty"`
   588  		S3 bvjm       `json:""`
   589  		S4 *bvjm      `json:""`
   590  		S5 *bvjm      `json:""`           // nil
   591  		S6 *bvjm      `json:",omitempty"` // nil
   592  		I1 big.Int    `json:""`
   593  		I2 big.Int    `json:",omitempty"`
   594  		I3 *big.Int   `json:""`
   595  		I4 *big.Int   `json:""`           // nil
   596  		I5 *big.Int   `json:",omitempty"` // nil
   597  		P1 brjm       `json:",omitempty"`
   598  		P2 brjm       `json:",omitempty"`
   599  		P3 brjm       `json:""`
   600  		P4 *brjm      `json:""`
   601  		P5 *brjm      `json:""`           // nil
   602  		P6 *brjm      `json:",omitempty"` // nil
   603  
   604  		// NOTE
   605  		// time.Time = Non-pointer receiver of composite type.
   606  		// bvjm = Non-pointer receiver of basic type.
   607  		// big.Int = Pointer receiver of composite type.
   608  		// brjm = Pointer receiver of basic type.
   609  	}
   610  	var (
   611  		now  = time.Now()
   612  		bval = bvjm("bval")
   613  		bref = brjm("bref")
   614  		xx   = x{
   615  			T1: now,
   616  			T3: &now,
   617  			S1: "S1",
   618  			S4: &bval,
   619  			I1: *big.NewInt(math.MaxInt64),
   620  			I3: big.NewInt(math.MaxInt64),
   621  			P1: "P1",
   622  			P4: &bref,
   623  		}
   624  	)
   625  	marshalCompare(t, xx, "non-pointer")
   626  	marshalCompare(t, &xx, "pointer")
   627  }
   628  
   629  // TestTextMarshaler tests that a type implementing
   630  // the encoding.TextMarshaler interface encodes to a
   631  // quoted string of its MashalText method result.
   632  func TestTextMarshaler(t *testing.T) {
   633  	type x struct {
   634  		S1 net.IP     `json:""`
   635  		S2 net.IP     `json:",omitempty"`
   636  		S3 *net.IP    `json:""`
   637  		S4 *net.IP    `json:""`           // nil
   638  		S5 *net.IP    `json:",omitempty"` // nil
   639  		I1 bvtm       `json:",omitempty"`
   640  		I2 bvtm       `json:",omitempty"`
   641  		I3 bvtm       `json:""`
   642  		I4 *bvtm      `json:""`
   643  		I5 *bvtm      `json:""`           // nil
   644  		I6 *bvtm      `json:",omitempty"` // nil
   645  		F1 big.Float  `json:""`
   646  		F2 big.Float  `json:",omitempty"`
   647  		F3 *big.Float `json:""`
   648  		F4 *big.Float `json:""`           // nil
   649  		F5 *big.Float `json:",omitempty"` // nil
   650  		P1 brtm       `json:",omitempty"`
   651  		P2 brtm       `json:",omitempty"`
   652  		P3 brtm       `json:""`
   653  		P4 *brtm      `json:""`
   654  		P5 *brtm      `json:""`           // nil
   655  		P6 *brtm      `json:",omitempty"` // nil
   656  
   657  		// NOTE
   658  		// net.IP = Non-pointer receiver of composite type.
   659  		// bvtm = Non-pointer receiver of basic type.
   660  		// big.Float = Pointer receiver of composite type.
   661  		// brtm = Pointer receiver of basic type.
   662  	}
   663  	var (
   664  		bval = bvtm(42)
   665  		bref = brtm(42)
   666  		xx   = x{
   667  			S1: net.IP{192, 168, 0, 1},
   668  			S3: &net.IP{127, 0, 0, 1},
   669  			I1: 42,
   670  			I4: &bval,
   671  			F1: *big.NewFloat(math.MaxFloat64),
   672  			F3: big.NewFloat(math.MaxFloat64),
   673  			P1: 42,
   674  			P4: &bref,
   675  		}
   676  	)
   677  	marshalCompare(t, xx, "non-pointer")
   678  	marshalCompare(t, &xx, "pointer")
   679  }
   680  
   681  type (
   682  	bvm string
   683  	brm string
   684  	cvm struct{}
   685  	crm struct{}
   686  )
   687  
   688  func (m bvm) AppendJSON(dst []byte) ([]byte, error) {
   689  	return append(dst, strconv.Quote(string(m))...), nil
   690  }
   691  func (m *brm) AppendJSON(dst []byte) ([]byte, error) {
   692  	return append(dst, strconv.Quote(string(*m))...), nil
   693  }
   694  func (m bvm) MarshalJSON() ([]byte, error)         { return []byte(strconv.Quote(string(m))), nil }
   695  func (m *brm) MarshalJSON() ([]byte, error)        { return []byte(strconv.Quote(string(*m))), nil }
   696  func (cvm) AppendJSON(dst []byte) ([]byte, error)  { return append(dst, `"X"`...), nil }
   697  func (cvm) MarshalJSON() ([]byte, error)           { return []byte(`"X"`), nil }
   698  func (*crm) AppendJSON(dst []byte) ([]byte, error) { return append(dst, `"Y"`...), nil }
   699  func (*crm) MarshalJSON() ([]byte, error)          { return []byte(`"Y"`), nil }
   700  
   701  //nolint:dupl
   702  func TestMarshaler(t *testing.T) {
   703  	type x struct {
   704  		S1 cvm  `json:""`
   705  		S2 cvm  `json:",omitempty"`
   706  		S3 *cvm `json:""`
   707  		S4 *cvm `json:""`           // nil
   708  		S5 *cvm `json:",omitempty"` // nil
   709  		I1 bvm  `json:",omitempty"`
   710  		I2 bvm  `json:",omitempty"`
   711  		I3 bvm  `json:""`
   712  		I4 *bvm `json:""`
   713  		I5 *bvm `json:""`           // nil
   714  		I6 *bvm `json:",omitempty"` // nil
   715  		F1 crm  `json:""`
   716  		F2 crm  `json:",omitempty"`
   717  		F3 *crm `json:""`
   718  		F4 *crm `json:""`           // nil
   719  		F5 *crm `json:",omitempty"` // nil
   720  		P1 brm  `json:",omitempty"`
   721  		P2 brm  `json:",omitempty"`
   722  		P3 brm  `json:""`
   723  		P4 *brm `json:""`
   724  		P5 *brm `json:""`           // nil
   725  		P6 *brm `json:",omitempty"` // nil
   726  
   727  		// NOTE
   728  		// cvm = Non-pointer receiver of composite type.
   729  		// bvm = Non-pointer receiver of basic type.
   730  		// crm = Pointer receiver of composite type.
   731  		// brm = Pointer receiver of basic type.
   732  	}
   733  	var (
   734  		bval = bvm("bval")
   735  		bref = brm("bref")
   736  		xx   = x{
   737  			S1: cvm{},
   738  			S3: &cvm{},
   739  			I1: "I1",
   740  			I4: &bval,
   741  			F1: crm{},
   742  			F3: &crm{},
   743  			P1: "P1",
   744  			P4: &bref,
   745  		}
   746  	)
   747  	marshalCompare(t, xx, "non-pointer")
   748  	marshalCompare(t, &xx, "pointer")
   749  }
   750  
   751  type (
   752  	bvmctx string
   753  	brmctx string
   754  	cvmctx struct{}
   755  	crmctx struct{}
   756  )
   757  
   758  func (m bvmctx) AppendJSONContext(_ context.Context, dst []byte) ([]byte, error) {
   759  	return append(dst, strconv.Quote(string(m))...), nil
   760  }
   761  func (m bvmctx) MarshalJSON() ([]byte, error) {
   762  	return []byte(strconv.Quote(string(m))), nil
   763  }
   764  func (m *brmctx) AppendJSONContext(_ context.Context, dst []byte) ([]byte, error) {
   765  	return append(dst, strconv.Quote(string(*m))...), nil
   766  }
   767  func (m *brmctx) MarshalJSON() ([]byte, error) {
   768  	return []byte(strconv.Quote(string(*m))), nil
   769  }
   770  func (cvmctx) AppendJSONContext(_ context.Context, dst []byte) ([]byte, error) {
   771  	return append(dst, `"X"`...), nil
   772  }
   773  func (cvmctx) MarshalJSON() ([]byte, error) {
   774  	return []byte(`"X"`), nil
   775  }
   776  func (*crmctx) AppendJSONContext(_ context.Context, dst []byte) ([]byte, error) {
   777  	return append(dst, `"Y"`...), nil
   778  }
   779  func (*crmctx) MarshalJSON() ([]byte, error) {
   780  	return []byte(`"Y"`), nil
   781  }
   782  
   783  //nolint:dupl
   784  func TestMarshalerCtx(t *testing.T) {
   785  	type x struct {
   786  		S1 cvmctx  `json:""`
   787  		S2 cvmctx  `json:",omitempty"`
   788  		S3 *cvmctx `json:""`
   789  		S4 *cvmctx `json:""`           // nil
   790  		S5 *cvmctx `json:",omitempty"` // nil
   791  		I1 bvmctx  `json:",omitempty"`
   792  		I2 bvmctx  `json:",omitempty"`
   793  		I3 bvmctx  `json:""`
   794  		I4 *bvmctx `json:""`
   795  		I5 *bvmctx `json:""`           // nil
   796  		I6 *bvmctx `json:",omitempty"` // nil
   797  		F1 crmctx  `json:""`
   798  		F2 crmctx  `json:",omitempty"`
   799  		F3 *crmctx `json:""`
   800  		F4 *crmctx `json:""`           // nil
   801  		F5 *crmctx `json:",omitempty"` // nil
   802  		P1 brmctx  `json:",omitempty"`
   803  		P2 brmctx  `json:",omitempty"`
   804  		P3 brmctx  `json:""`
   805  		P4 *brmctx `json:""`
   806  		P5 *brmctx `json:""`           // nil
   807  		P6 *brmctx `json:",omitempty"` // nil
   808  
   809  		// NOTE
   810  		// cvmctx = Non-pointer receiver of composite type.
   811  		// bvmctx = Non-pointer receiver of basic type.
   812  		// crmctx = Pointer receiver of composite type.
   813  		// brmctx = Pointer receiver of basic type.
   814  	}
   815  	var (
   816  		bval = bvmctx("bval")
   817  		bref = brmctx("bref")
   818  		xx   = x{
   819  			S1: cvmctx{},
   820  			S3: &cvmctx{},
   821  			I1: "I1",
   822  			I4: &bval,
   823  			F1: crmctx{},
   824  			F3: &crmctx{},
   825  			P1: "P1",
   826  			P4: &bref,
   827  		}
   828  	)
   829  	marshalCompare(t, xx, "non-pointer")
   830  	marshalCompare(t, &xx, "pointer")
   831  }
   832  
   833  type (
   834  	niljetim string // jettison.Marshaler
   835  	nilmjctx string // jettison.MarshalerCtx
   836  	niljsonm string // json.Marshaler
   837  	niltextm string // encoding.TextMarshaler
   838  )
   839  
   840  // comboMarshaler combines the json.Marshaler
   841  // and jettison.AppendMarshaler interfaces so
   842  // that tests outputs can be compared.
   843  type comboMarshaler interface {
   844  	AppendMarshaler
   845  	json.Marshaler
   846  }
   847  
   848  // comboMarshalerCtx combines the json.Marshaler
   849  // and jettison.AppendMarshalerCtx interfaces so
   850  // that tests outputs can be compared.
   851  type comboMarshalerCtx interface {
   852  	AppendMarshalerCtx
   853  	json.Marshaler
   854  }
   855  
   856  func (*niljetim) MarshalJSON() ([]byte, error) { return []byte(`"W"`), nil }
   857  func (*nilmjctx) MarshalJSON() ([]byte, error) { return []byte(`"X"`), nil }
   858  func (*niljsonm) MarshalJSON() ([]byte, error) { return []byte(`"Y"`), nil }
   859  func (*niltextm) MarshalText() ([]byte, error) { return []byte("Z"), nil }
   860  
   861  func (*niljetim) AppendJSON(dst []byte) ([]byte, error) {
   862  	return append(dst, `"W"`...), nil
   863  }
   864  func (*nilmjctx) AppendJSONContext(_ context.Context, dst []byte) ([]byte, error) {
   865  	return append(dst, `"X"`...), nil
   866  }
   867  
   868  type (
   869  	errvjm   struct{}
   870  	errrjm   struct{}
   871  	errvtm   struct{}
   872  	errrtm   struct{}
   873  	errvm    struct{}
   874  	errrm    struct{}
   875  	errvmctx struct{}
   876  	errrmctx struct{}
   877  )
   878  
   879  var errMarshaler = errors.New("error")
   880  
   881  func (errvjm) MarshalJSON() ([]byte, error)          { return nil, errMarshaler }
   882  func (*errrjm) MarshalJSON() ([]byte, error)         { return nil, errMarshaler }
   883  func (errvtm) MarshalText() ([]byte, error)          { return nil, errMarshaler }
   884  func (*errrtm) MarshalText() ([]byte, error)         { return nil, errMarshaler }
   885  func (errvm) AppendJSON(dst []byte) ([]byte, error)  { return dst, errMarshaler }
   886  func (*errrm) AppendJSON(dst []byte) ([]byte, error) { return dst, errMarshaler }
   887  
   888  func (errvmctx) AppendJSONContext(_ context.Context, dst []byte) ([]byte, error) {
   889  	return dst, errMarshaler
   890  }
   891  func (*errrmctx) AppendJSONContext(_ context.Context, dst []byte) ([]byte, error) {
   892  	return dst, errMarshaler
   893  }
   894  
   895  // TestMarshalerError tests that a MarshalerError is
   896  // returned when a MarshalText, MarshalJSON, WriteJSON
   897  // or WriteJSONContext method returns an error.
   898  func TestMarshalerError(t *testing.T) {
   899  	testdata := []interface{}{
   900  		errvjm{},
   901  		&errrjm{},
   902  		errvtm{},
   903  		&errrtm{},
   904  		errvm{},
   905  		&errrm{},
   906  		errvmctx{},
   907  		&errrmctx{},
   908  	}
   909  	for _, v := range testdata {
   910  		_, err := Marshal(v)
   911  		if err != nil {
   912  			me, ok := err.(*MarshalerError)
   913  			if !ok {
   914  				t.Fatalf("got %T, want MarshalerError", err)
   915  			}
   916  			typ := reflect.TypeOf(v)
   917  			if me.Type != typ {
   918  				t.Errorf("got %s, want %s", me.Type, typ)
   919  			}
   920  			if err := me.Unwrap(); err == nil {
   921  				t.Error("expected non-nil error")
   922  			}
   923  			if me.Error() == "" {
   924  				t.Error("expected non-empty error message")
   925  			}
   926  		} else {
   927  			t.Error("got nil, want non-nil error")
   928  		}
   929  	}
   930  }
   931  
   932  // TestStructFieldName tests that invalid struct
   933  // field names are ignored during marshaling.
   934  func TestStructFieldName(t *testing.T) {
   935  	//nolint:staticcheck
   936  	type x struct {
   937  		A  string `json:"   "`         // valid, spaces
   938  		B  string `json:"0123"`        // valid, digits
   939  		C  int    `json:","`           // invalid, comma
   940  		D  int8   `json:"\\"`          // invalid, backslash,
   941  		E  int16  `json:"\""`          // invalid, quotation mark
   942  		F  int    `json:"Вилиам"`      // valid, UTF-8 runes
   943  		G  bool   `json:"<ben&jerry>"` // valid, HTML-escaped chars
   944  		Aβ int
   945  	}
   946  	marshalCompare(t, x{}, "")
   947  }
   948  
   949  // TestStructFieldOmitempty tests that the fields of
   950  // a struct with the omitempty option are not encoded
   951  // when they have the zero-value of their type.
   952  func TestStructFieldOmitempty(t *testing.T) {
   953  	type x struct {
   954  		A  string      `json:",omitempty"`
   955  		B  string      `json:",omitempty"`
   956  		C  *string     `json:",omitempty"`
   957  		Ca *string     `json:"a,omitempty"`
   958  		D  *string     `json:",omitempty"`
   959  		E  bool        `json:",omitempty"`
   960  		F  int         `json:",omitempty"`
   961  		F1 int8        `json:",omitempty"`
   962  		F2 int16       `json:",omitempty"`
   963  		F3 int32       `json:",omitempty"`
   964  		F4 int64       `json:",omitempty"`
   965  		G1 uint        `json:",omitempty"`
   966  		G2 uint8       `json:",omitempty"`
   967  		G3 uint16      `json:",omitempty"`
   968  		G4 uint32      `json:",omitempty"`
   969  		G5 uint64      `json:",omitempty"`
   970  		G6 uintptr     `json:",omitempty"`
   971  		H  float32     `json:",omitempty"`
   972  		I  float64     `json:",omitempty"`
   973  		J1 map[int]int `json:",omitempty"`
   974  		J2 map[int]int `json:",omitempty"`
   975  		J3 map[int]int `json:",omitempty"`
   976  		K1 []string    `json:",omitempty"`
   977  		K2 []string    `json:",omitempty"`
   978  		L1 [0]int      `json:",omitempty"`
   979  		L2 [2]int      `json:",omitempty"`
   980  		M1 interface{} `json:",omitempty"`
   981  		M2 interface{} `json:",omitempty"`
   982  	}
   983  	var (
   984  		s1 = "Loreum"
   985  		s2 = ""
   986  		xx = &x{
   987  			A:  "A",
   988  			B:  "",
   989  			C:  &s1,
   990  			Ca: &s2,
   991  			D:  nil,
   992  			J2: map[int]int{},
   993  			J3: map[int]int{1: 42},
   994  			K2: []string{"K2"},
   995  			M2: (*int)(nil),
   996  		}
   997  	)
   998  	marshalCompare(t, xx, "")
   999  }
  1000  
  1001  // TestStructFieldOmitnil tests that the fields of a
  1002  // struct with the omitnil option are not encoded
  1003  // when they have a nil value.
  1004  func TestStructFieldOmitnil(t *testing.T) {
  1005  	// nolint:staticcheck
  1006  	type x struct {
  1007  		Sn  string                 `json:"sn,omitnil"`
  1008  		In  int                    `json:"in,omitnil"`
  1009  		Un  uint                   `json:"un,omitnil"`
  1010  		Fn  float64                `json:"fn,omitnil"`
  1011  		Bn  bool                   `json:"bn,omitnil"`
  1012  		Sln []string               `json:"sln,omitnil"`
  1013  		Mpn map[string]interface{} `json:"mpn,omitnil"`
  1014  		Stn struct{}               `json:"stn,omitnil"`
  1015  		Ptn *string                `json:"ptn,omitnil"`
  1016  		Ifn interface{}            `json:"ifn,omitnil"`
  1017  	}
  1018  	var (
  1019  		xx     = x{}
  1020  		before = `{"sn":"","in":0,"un":0,"fn":0,"bn":false,"stn":{}}`
  1021  		after  = `{"sn":"","in":0,"un":0,"fn":0,"bn":false,"sln":[],"mpn":{},"stn":{},"ptn":"Loreum","ifn":42}`
  1022  	)
  1023  	b, err := Marshal(xx)
  1024  	if err != nil {
  1025  		t.Fatal(err)
  1026  	}
  1027  	if got := string(b); got != before {
  1028  		t.Errorf("before: got: %#q, want: %#q", got, before)
  1029  	}
  1030  	s := "Loreum"
  1031  
  1032  	xx.Sln = make([]string, 0)
  1033  	xx.Mpn = map[string]interface{}{}
  1034  	xx.Stn = struct{}{}
  1035  	xx.Ptn = &s
  1036  	xx.Ifn = 42
  1037  
  1038  	b, err = Marshal(xx)
  1039  	if err != nil {
  1040  		t.Fatal(err)
  1041  	}
  1042  	if got := string(b); got != after {
  1043  		t.Errorf("after: got: %#q, want: %#q", got, after)
  1044  	}
  1045  }
  1046  
  1047  // TestQuotedStructFields tests that the fields of
  1048  // a struct with the string option are quoted during
  1049  // marshaling if the type support it.
  1050  //nolint:staticcheck
  1051  func TestQuotedStructFields(t *testing.T) {
  1052  	type x struct {
  1053  		A1 int         `json:",string"`
  1054  		A2 *int        `json:",string"`
  1055  		A3 *int        `json:",string"`
  1056  		B  uint        `json:",string"`
  1057  		C1 bool        `json:",string"`
  1058  		C2 *bool       `json:",string"`
  1059  		D  float32     `json:",string"`
  1060  		E  string      `json:",string"`
  1061  		F  []int       `json:",string"`
  1062  		G  map[int]int `json:",string"`
  1063  	}
  1064  	var (
  1065  		i  = 84
  1066  		b  = false
  1067  		xx = &x{
  1068  			A1: -42,
  1069  			A2: nil,
  1070  			A3: &i,
  1071  			B:  42,
  1072  			C1: true,
  1073  			C2: &b,
  1074  			D:  math.Pi,
  1075  			E:  "E",
  1076  			F:  []int{1, 2, 3},
  1077  			G:  map[int]int{1: 2},
  1078  		}
  1079  	)
  1080  	marshalCompare(t, xx, "")
  1081  }
  1082  
  1083  // TestBasicStructFieldTypes tests that struct
  1084  // fields of basic types can be marshaled.
  1085  func TestBasicStructFieldTypes(t *testing.T) {
  1086  	type x struct {
  1087  		A  string  `json:"a"`
  1088  		B1 int     `json:"b1"`
  1089  		B2 int8    `json:"b2"`
  1090  		B3 int16   `json:"b3"`
  1091  		B4 int32   `json:"b4"`
  1092  		B5 int64   `json:"b5"`
  1093  		C1 uint    `json:"c1"`
  1094  		C2 uint8   `json:"c2"`
  1095  		C3 uint16  `json:"c3"`
  1096  		C4 uint32  `json:"c4"`
  1097  		C5 uint64  `json:"c5"`
  1098  		D1 bool    `json:"d1"`
  1099  		D2 bool    `json:"d2"`
  1100  		E  float32 `json:"e"`
  1101  		F  float64 `json:"f"`
  1102  		G  string  `json:"-"`  // ignored
  1103  		H  string  `json:"-,"` // use "-" as key
  1104  		i  string
  1105  	}
  1106  	xx := &x{
  1107  		A:  "A",
  1108  		B1: -42,
  1109  		B2: math.MinInt8,
  1110  		B3: math.MinInt16,
  1111  		B4: math.MinInt32,
  1112  		B5: math.MinInt64,
  1113  		C1: 42,
  1114  		C2: math.MaxUint8,
  1115  		C3: math.MaxUint16,
  1116  		C4: math.MaxUint32,
  1117  		C5: math.MaxUint64,
  1118  		D1: true,
  1119  		D2: false,
  1120  		E:  3.14169,
  1121  		F:  math.MaxFloat64,
  1122  		G:  "ignored",
  1123  		H:  "not-ignored",
  1124  		i:  "unexported",
  1125  	}
  1126  	marshalCompare(t, xx, "non-pointer")
  1127  	marshalCompare(t, &xx, "pointer")
  1128  }
  1129  
  1130  // TestBasicStructFieldPointerTypes tests
  1131  // that nil and non-nil struct field pointers
  1132  // of basic types can be marshaled.
  1133  func TestBasicStructFieldPointerTypes(t *testing.T) {
  1134  	type x struct {
  1135  		A *string  `json:"a"`
  1136  		B *int     `json:"b"`
  1137  		C *uint64  `json:"c"`
  1138  		D *bool    `json:"d"`
  1139  		E *float32 `json:"e"`
  1140  		F *float64 `json:"f"`
  1141  	}
  1142  	var (
  1143  		a  = "a"
  1144  		b  = 42
  1145  		d  = true
  1146  		f  = math.MaxFloat64
  1147  		xx = x{A: &a, B: &b, C: nil, D: &d, E: nil, F: &f}
  1148  	)
  1149  	marshalCompare(t, xx, "non-pointer")
  1150  	marshalCompare(t, &xx, "pointer")
  1151  }
  1152  
  1153  // TestCompositeStructFieldTypes tests that struct
  1154  // fields of composite types, such as struct, slice,
  1155  // array and map can be marshaled.
  1156  func TestCompositeStructFieldTypes(t *testing.T) {
  1157  	type y struct {
  1158  		X string `json:"x"`
  1159  	}
  1160  	type x struct {
  1161  		A  y `json:"a"`
  1162  		B1 *y
  1163  		B2 *y
  1164  		b3 *y
  1165  		c1 []string
  1166  		C2 []string
  1167  		D  []int
  1168  		E  []bool
  1169  		F  []float32
  1170  		G  []*uint
  1171  		H  [3]string
  1172  		I  [1]int
  1173  		J  [0]bool
  1174  		K1 []byte
  1175  		K2 []byte
  1176  		L  []*int
  1177  		M1 []y
  1178  		M2 *[]y
  1179  		N1 []*y
  1180  		N2 []*y
  1181  		O1 [3]*int
  1182  		O2 *[3]*bool
  1183  		P  [3]*y
  1184  		Q  [][]int
  1185  		R  [2][2]string
  1186  		S1 map[int]string
  1187  		S2 map[int]string
  1188  		S3 map[int]string
  1189  		S4 map[string]interface{}
  1190  		T1 *map[string]int
  1191  		T2 *map[string]int
  1192  		T3 *map[string]int
  1193  		U1 interface{}
  1194  		U2 interface{}
  1195  		U3 interface{}
  1196  		U4 interface{}
  1197  		U5 interface{}
  1198  		U6 interface{}
  1199  		u7 interface{}
  1200  	}
  1201  	k := make([]byte, 32)
  1202  	if _, err := rand.Read(k); err != nil {
  1203  		t.Error(err)
  1204  	}
  1205  	var (
  1206  		l1 = 0
  1207  		l2 = 42
  1208  		m1 = y{X: "X"}
  1209  		m2 = y{}
  1210  		i0 = 42
  1211  		i1 = &i0
  1212  		i2 = &i1
  1213  		i3 = &i2
  1214  		xx = x{
  1215  			A:  y{X: "X"},
  1216  			B1: nil,
  1217  			B2: &y{X: "Ipsum"},
  1218  			b3: nil,
  1219  			c1: nil,
  1220  			C2: []string{"one", "two", "three"},
  1221  			D:  []int{1, 2, 3},
  1222  			E:  []bool{},
  1223  			H:  [3]string{"alpha", "beta", "gamma"},
  1224  			I:  [1]int{42},
  1225  			K1: k,
  1226  			K2: []byte(nil),
  1227  			L:  []*int{&l1, &l2, nil},
  1228  			M1: []y{m1, m2},
  1229  			N1: []*y{&m1, &m2, nil},
  1230  			N2: []*y{},
  1231  			O1: [3]*int{&l1, &l2, nil},
  1232  			P:  [3]*y{&m1, &m2, nil},
  1233  			Q:  [][]int{{1, 2}, {3, 4}},
  1234  			R:  [2][2]string{{"a", "b"}, {"c", "d"}},
  1235  			S1: nil,
  1236  			S3: map[int]string{1: "x", 2: "y", 3: "z"},
  1237  			S4: map[string]interface{}{"a": 1, "b": "2"},
  1238  			T3: &map[string]int{"x": 1, "y": 2, "z": 3},
  1239  			U1: "U1",
  1240  			U2: &l2,
  1241  			U3: nil,
  1242  			U4: false,
  1243  			U5: (*int)(nil), // typed nil
  1244  			U6: i3,          // chain of pointers
  1245  			u7: nil,
  1246  		}
  1247  	)
  1248  	marshalCompare(t, xx, "non-pointer")
  1249  	marshalCompare(t, &xx, "pointer")
  1250  }
  1251  
  1252  // TestEmbeddedTypes tests that composite and basic
  1253  // embedded struct fields types are encoded whether
  1254  // they are exported.
  1255  func TestEmbeddedTypes(t *testing.T) {
  1256  	type (
  1257  		P1 int
  1258  		P2 string
  1259  		P3 bool
  1260  		p4 uint32
  1261  		C1 map[string]int
  1262  		C2 [3]string
  1263  		C3 []int
  1264  		c4 []bool
  1265  	)
  1266  	type x struct {
  1267  		P1
  1268  		P2
  1269  		P3
  1270  		p4
  1271  		C1
  1272  		C2
  1273  		C3
  1274  		c4 `json:"c4"`
  1275  	}
  1276  	xx := &x{
  1277  		P1: P1(42),
  1278  		P2: P2("P2"),
  1279  		P3: P3(true),
  1280  		p4: p4(math.MaxUint32),
  1281  		C1: C1{"A": 1, "B": 2},
  1282  		C2: C2{"A", "B", "C"},
  1283  		C3: C3{1, 2, 3},
  1284  		c4: c4{true, false},
  1285  	}
  1286  	marshalCompare(t, xx, "")
  1287  }
  1288  
  1289  // TestRecursiveType tests the marshaling of
  1290  // recursive types.
  1291  func TestRecursiveType(t *testing.T) {
  1292  	type x struct {
  1293  		A string `json:"a"`
  1294  		X *x     `json:"x"`
  1295  	}
  1296  	xx := &x{
  1297  		A: "A1",
  1298  		X: &x{A: "A2"},
  1299  	}
  1300  	marshalCompare(t, xx, "")
  1301  }
  1302  
  1303  // TestTaggedFieldDominates tests that a struct
  1304  // field with a tag dominates untagged fields.
  1305  func TestTaggedFieldDominates(t *testing.T) {
  1306  	type (
  1307  		A struct{ S string }
  1308  		D struct {
  1309  			XXX string `json:"S"`
  1310  		}
  1311  		Y struct {
  1312  			A
  1313  			D
  1314  		}
  1315  	)
  1316  	y := Y{
  1317  		A{"A"},
  1318  		D{"D"},
  1319  	}
  1320  	marshalCompare(t, y, "")
  1321  }
  1322  
  1323  // TestDuplicatedFieldDisappears tests that
  1324  // duplicate struct field at the same level
  1325  // of embedding are ignored.
  1326  func TestDuplicatedFieldDisappears(t *testing.T) {
  1327  	type (
  1328  		A struct{ S string }
  1329  		C struct{ S string }
  1330  		D struct {
  1331  			XXX string `json:"S"`
  1332  		}
  1333  		Y struct {
  1334  			A
  1335  			D
  1336  		}
  1337  		Z struct {
  1338  			A
  1339  			C
  1340  			Y
  1341  		}
  1342  	)
  1343  	z := Z{A{"A"}, C{"C"}, Y{A{"S"}, D{"D"}}}
  1344  
  1345  	marshalCompare(t, z, "")
  1346  }
  1347  
  1348  // TestEmbeddedStructs tests that named and unnamed
  1349  // embedded structs fields can be marshaled.
  1350  func TestEmbeddedStructs(t *testing.T) {
  1351  	type (
  1352  		r struct {
  1353  			J string `json:"j"`
  1354  		}
  1355  		v struct {
  1356  			H bool   `json:"h,omitempty"`
  1357  			I string `json:"i"`
  1358  		}
  1359  		y struct {
  1360  			D int8  `json:"d"`
  1361  			E uint8 `json:"e,omitempty"`
  1362  			r
  1363  			v
  1364  		}
  1365  		z struct {
  1366  			F int16  `json:"f,omitempty"`
  1367  			G uint16 `json:"g"`
  1368  			y
  1369  			v
  1370  		}
  1371  		// According to the Go rules for embedded fields,
  1372  		// y.r.J should be encoded while z.y.r.J is not,
  1373  		// because is one-level up.
  1374  		// However, y.v.H and z.v.H are present at the same
  1375  		// level, and therefore are both hidden.
  1376  		x1 struct {
  1377  			A string `json:"a,omitempty"`
  1378  			y
  1379  			B string `json:"b"`
  1380  			v `json:"v"`
  1381  			C string `json:"c,omitempty"`
  1382  			z `json:",omitempty"`
  1383  			*x1
  1384  		}
  1385  		// x2 is a variant of the x1 type without
  1386  		// the omitempty option on the first field.
  1387  		x2 struct {
  1388  			A int16 `json:"a"`
  1389  			v `json:"v"`
  1390  		}
  1391  	)
  1392  	xx1 := &x1{
  1393  		A: "A",
  1394  		y: y{
  1395  			D: math.MinInt8,
  1396  			r: r{J: "J"},
  1397  			v: v{H: false},
  1398  		},
  1399  		z: z{
  1400  			G: math.MaxUint16,
  1401  			y: y{D: 21, r: r{J: "J"}},
  1402  			v: v{H: true},
  1403  		},
  1404  		x1: &x1{
  1405  			A: "A",
  1406  		},
  1407  	}
  1408  	xx2 := &x2{A: 42, v: v{I: "I"}}
  1409  
  1410  	marshalCompare(t, xx1, "")
  1411  	marshalCompare(t, xx2, "")
  1412  }
  1413  
  1414  // TestAnonymousFields tests the marshaling of
  1415  // advanced cases for anonymous struct fields.
  1416  // Adapted from the encoding/json testsuite.
  1417  func TestAnonymousFields(t *testing.T) {
  1418  	testdata := []struct {
  1419  		label string
  1420  		input func() []interface{}
  1421  	}{{
  1422  		// Both S1 and S2 have a field named X.
  1423  		// From the perspective of S, it is
  1424  		// ambiguous which one X refers to.
  1425  		// This should not encode either field.
  1426  		label: "AmbiguousField",
  1427  		input: func() []interface{} {
  1428  			type (
  1429  				S1 struct{ x, X int }
  1430  				S2 struct{ x, X int }
  1431  				S  struct {
  1432  					S1
  1433  					S2
  1434  				}
  1435  			)
  1436  			return []interface{}{
  1437  				S{S1{1, 2}, S2{3, 4}},
  1438  				&S{S1{5, 6}, S2{7, 8}},
  1439  			}
  1440  		},
  1441  	}, {
  1442  		// Both S1 and S2 have a field named X, but
  1443  		// since S has an X field as well, it takes
  1444  		// precedence over S1.X and S2.X.
  1445  		label: "DominantField",
  1446  		input: func() []interface{} {
  1447  			type (
  1448  				S1 struct{ x, X int }
  1449  				S2 struct{ x, X int }
  1450  				S  struct {
  1451  					S1
  1452  					S2
  1453  					x, X int
  1454  				}
  1455  			)
  1456  			return []interface{}{
  1457  				S{S1{1, 2}, S2{3, 4}, 5, 6},
  1458  				&S{S1{6, 5}, S2{4, 3}, 2, 1},
  1459  			}
  1460  		},
  1461  	}, {
  1462  		// Unexported embedded field of non-struct type
  1463  		// should not be serialized.
  1464  		label: "UnexportedEmbeddedInt",
  1465  		input: func() []interface{} {
  1466  			type (
  1467  				i int
  1468  				S struct{ i }
  1469  			)
  1470  			return []interface{}{S{5}, &S{6}}
  1471  		},
  1472  	}, {
  1473  		// Exported embedded field of non-struct type
  1474  		// should be serialized.
  1475  		label: "ExportedEmbeddedInt",
  1476  		input: func() []interface{} {
  1477  			type (
  1478  				I int
  1479  				S struct{ I }
  1480  			)
  1481  			return []interface{}{S{5}, &S{6}}
  1482  		},
  1483  	}, {
  1484  		// Unexported embedded field of pointer to
  1485  		// non-struct type should not be serialized.
  1486  		label: "UnexportedEmbeddedIntPointer",
  1487  		input: func() []interface{} {
  1488  			type (
  1489  				i int
  1490  				S struct{ *i }
  1491  			)
  1492  			s := S{new(i)}
  1493  			*s.i = 5
  1494  			return []interface{}{s, &s}
  1495  		},
  1496  	}, {
  1497  		// Exported embedded field of pointer to
  1498  		// non-struct type should be serialized.
  1499  		label: "ExportedEmbeddedIntPointer",
  1500  		input: func() []interface{} {
  1501  			type (
  1502  				I int
  1503  				S struct{ *I }
  1504  			)
  1505  			s := S{new(I)}
  1506  			*s.I = 5
  1507  			return []interface{}{s, &s}
  1508  		},
  1509  	}, {
  1510  		// Exported embedded field of nil pointer
  1511  		// to non-struct type should be serialized.
  1512  		label: "ExportedEmbeddedNilIntPointer",
  1513  		input: func() []interface{} {
  1514  			type (
  1515  				I int
  1516  				S struct{ *I }
  1517  			)
  1518  			s := S{new(I)}
  1519  			s.I = nil
  1520  			return []interface{}{s, &s}
  1521  		},
  1522  	}, {
  1523  		// Exported embedded field of nil pointer to
  1524  		// non-struct type should not be serialized
  1525  		// if it has the omitempty option.
  1526  		label: "ExportedEmbeddedNilIntPointerOmitempty",
  1527  		input: func() []interface{} {
  1528  			type (
  1529  				I int
  1530  				S struct {
  1531  					*I `json:",omitempty"`
  1532  				}
  1533  			)
  1534  			s := S{new(I)}
  1535  			s.I = nil
  1536  			return []interface{}{s, &s}
  1537  		},
  1538  	}, {
  1539  		// Exported embedded field of pointer to
  1540  		// struct type should be serialized.
  1541  		label: "ExportedEmbeddedStructPointer",
  1542  		input: func() []interface{} {
  1543  			type (
  1544  				S struct{ X string }
  1545  				T struct{ *S }
  1546  			)
  1547  			t := T{S: &S{
  1548  				X: "X",
  1549  			}}
  1550  			return []interface{}{t, &t}
  1551  		},
  1552  	}, {
  1553  		// Exported fields of embedded structs should
  1554  		// have their exported fields be serialized
  1555  		// regardless of whether the struct types
  1556  		// themselves are exported.
  1557  		label: "EmbeddedStructNonPointer",
  1558  		input: func() []interface{} {
  1559  			type (
  1560  				s1 struct{ x, X int }
  1561  				S2 struct{ y, Y int }
  1562  				S  struct {
  1563  					s1
  1564  					S2
  1565  				}
  1566  			)
  1567  			return []interface{}{
  1568  				S{s1{1, 2}, S2{3, 4}},
  1569  				&S{s1{5, 6}, S2{7, 8}},
  1570  			}
  1571  		},
  1572  	}, {
  1573  		// Exported fields of pointers to embedded
  1574  		// structs should have their exported fields
  1575  		// be serialized regardless of whether the
  1576  		// struct types themselves are exported.
  1577  		label: "EmbeddedStructPointer",
  1578  		input: func() []interface{} {
  1579  			type (
  1580  				s1 struct{ x, X int }
  1581  				S2 struct{ y, Y int }
  1582  				S  struct {
  1583  					*s1
  1584  					*S2
  1585  				}
  1586  			)
  1587  			return []interface{}{
  1588  				S{&s1{1, 2}, &S2{3, 4}},
  1589  				&S{&s1{5, 6}, &S2{7, 8}},
  1590  			}
  1591  		},
  1592  	}, {
  1593  		// Exported fields on embedded unexported
  1594  		// structs at multiple levels of nesting
  1595  		// should still be serialized.
  1596  		label: "NestedStructAndInts",
  1597  		input: func() []interface{} {
  1598  			type (
  1599  				I1 int
  1600  				I2 int
  1601  				i  int
  1602  				s2 struct {
  1603  					I2
  1604  					i
  1605  				}
  1606  				s1 struct {
  1607  					I1
  1608  					i
  1609  					s2
  1610  				}
  1611  				S struct {
  1612  					s1
  1613  					i
  1614  				}
  1615  			)
  1616  			return []interface{}{
  1617  				S{s1{1, 2, s2{3, 4}}, 5},
  1618  				&S{s1{5, 4, s2{3, 2}}, 1},
  1619  			}
  1620  		},
  1621  	}, {
  1622  		// If an anonymous struct pointer field is nil,
  1623  		// we should ignore the embedded fields behind it.
  1624  		// Not properly doing so may result in the wrong
  1625  		// output or a panic.
  1626  		label: "EmbeddedFieldBehindNilPointer",
  1627  		input: func() []interface{} {
  1628  			type (
  1629  				S2 struct{ Field string }
  1630  				S  struct{ *S2 }
  1631  			)
  1632  			return []interface{}{S{}, &S{}}
  1633  		},
  1634  	}, {
  1635  		// A field behind a chain of pointer and
  1636  		// non-pointer embedded fields should be
  1637  		// accessible and serialized.
  1638  		label: "BasicEmbeddedFieldChain",
  1639  		input: func() []interface{} {
  1640  			type (
  1641  				A struct {
  1642  					X1 string
  1643  					X2 *string
  1644  				}
  1645  				B struct{ *A }
  1646  				C struct{ B }
  1647  				D struct{ *C }
  1648  				E struct{ D }
  1649  				F struct{ *E }
  1650  			)
  1651  			s := "Loreum"
  1652  			f := F{E: &E{D: D{C: &C{B: B{A: &A{X1: "X1", X2: &s}}}}}}
  1653  			return []interface{}{f, &f}
  1654  		},
  1655  	}, {
  1656  		// Variant of the test above, with embedded
  1657  		// fields of type struct that contain one or
  1658  		// more fields themselves.
  1659  		label: "ComplexEmbeddedFieldChain",
  1660  		input: func() []interface{} {
  1661  			type (
  1662  				A struct {
  1663  					X1 string `json:",omitempty"`
  1664  					X2 string
  1665  				}
  1666  				B struct {
  1667  					Z3 *bool
  1668  					A
  1669  				}
  1670  				C struct{ B }
  1671  				D struct {
  1672  					*C
  1673  					Z2 int
  1674  				}
  1675  				E struct{ *D }
  1676  				F struct {
  1677  					Z1 string `json:",omitempty"`
  1678  					*E
  1679  				}
  1680  			)
  1681  			f := F{Z1: "Z1", E: &E{D: &D{C: &C{B: B{A: A{X2: "X2"}, Z3: new(bool)}}, Z2: 1}}}
  1682  			return []interface{}{f, &f}
  1683  		},
  1684  	}}
  1685  	for i := range testdata {
  1686  		e := testdata[i]
  1687  		t.Run(e.label, func(t *testing.T) {
  1688  			for i, input := range e.input() {
  1689  				input := input
  1690  				var label string
  1691  				if i == 0 {
  1692  					label = "non-pointer"
  1693  				} else {
  1694  					label = "pointer"
  1695  				}
  1696  				t.Run(label, func(t *testing.T) {
  1697  					marshalCompare(t, input, label)
  1698  				})
  1699  			}
  1700  		})
  1701  	}
  1702  }
  1703  
  1704  func TestBytesEscaping(t *testing.T) {
  1705  	testdata := []struct {
  1706  		in, out string
  1707  	}{
  1708  		{"\x00", `"\u0000"`},
  1709  		{"\x01", `"\u0001"`},
  1710  		{"\x02", `"\u0002"`},
  1711  		{"\x03", `"\u0003"`},
  1712  		{"\x04", `"\u0004"`},
  1713  		{"\x05", `"\u0005"`},
  1714  		{"\x06", `"\u0006"`},
  1715  		{"\x07", `"\u0007"`},
  1716  		{"\x08", `"\u0008"`},
  1717  		{"\x09", `"\t"`},
  1718  		{"\x0a", `"\n"`},
  1719  		{"\x0b", `"\u000b"`},
  1720  		{"\x0c", `"\u000c"`},
  1721  		{"\x0d", `"\r"`},
  1722  		{"\x0e", `"\u000e"`},
  1723  		{"\x0f", `"\u000f"`},
  1724  		{"\x10", `"\u0010"`},
  1725  		{"\x11", `"\u0011"`},
  1726  		{"\x12", `"\u0012"`},
  1727  		{"\x13", `"\u0013"`},
  1728  		{"\x14", `"\u0014"`},
  1729  		{"\x15", `"\u0015"`},
  1730  		{"\x16", `"\u0016"`},
  1731  		{"\x17", `"\u0017"`},
  1732  		{"\x18", `"\u0018"`},
  1733  		{"\x19", `"\u0019"`},
  1734  		{"\x1a", `"\u001a"`},
  1735  		{"\x1b", `"\u001b"`},
  1736  		{"\x1c", `"\u001c"`},
  1737  		{"\x1d", `"\u001d"`},
  1738  		{"\x1e", `"\u001e"`},
  1739  		{"\x1f", `"\u001f"`},
  1740  	}
  1741  	for _, tt := range testdata {
  1742  		b, err := Marshal(tt.in)
  1743  		if err != nil {
  1744  			t.Error(err)
  1745  		}
  1746  		if s := string(b); s != tt.out {
  1747  			t.Errorf("got %#q, want %#q", s, tt.out)
  1748  		}
  1749  	}
  1750  }
  1751  
  1752  // TestStringEscaping tests that control and reserved
  1753  // JSON characters are properly escaped when a string
  1754  // is marshaled.
  1755  func TestStringEscaping(t *testing.T) {
  1756  	b := []byte{
  1757  		'A', 1, 2, 3,
  1758  		'"', '\\', '/', '\b', '\f', '\n', '\r', '\t',
  1759  		0xC7, 0xA3, 0xE2, 0x80, 0xA8, 0xE2, 0x80, 0xA9,
  1760  	}
  1761  	testdata := []struct {
  1762  		b   []byte
  1763  		s   string
  1764  		opt Option
  1765  		cmp bool
  1766  	}{
  1767  		{b, `"A\u0001\u0002\u0003\"\\/\u0008\u000c\n\r\tǣ\u2028\u2029"`, nil, true},
  1768  		{b, `"` + string(b) + `"`, NoStringEscaping(), false},
  1769  	}
  1770  	for _, tt := range testdata {
  1771  		b, err := MarshalOpts(string(tt.b), tt.opt)
  1772  		if err != nil {
  1773  			t.Error(err)
  1774  		}
  1775  		if s := string(b); s != tt.s {
  1776  			t.Errorf("got %#q, want %#q", s, tt.s)
  1777  		}
  1778  		if tt.cmp {
  1779  			bs, err := json.Marshal(string(tt.b))
  1780  			if err != nil {
  1781  				t.Error(err)
  1782  			}
  1783  			if !bytes.Equal(bs, b) {
  1784  				t.Logf("standard: %s", bs)
  1785  				t.Logf("jettison: %s", b)
  1786  				t.Errorf("expected equal outputs")
  1787  			}
  1788  		}
  1789  	}
  1790  }
  1791  
  1792  // TestStringHTMLEscaping tests that HTML characters
  1793  // are properly escaped when a string is marshaled.
  1794  func TestStringHTMLEscaping(t *testing.T) {
  1795  	htmlChars := []byte{'<', '>', '&'}
  1796  	testdata := []struct {
  1797  		b    []byte
  1798  		s    string
  1799  		opts []Option
  1800  	}{
  1801  		{htmlChars, `"\u003c\u003e\u0026"`, nil},
  1802  		{htmlChars, `"<>&"`, []Option{NoHTMLEscaping()}},
  1803  
  1804  		// NoHTMLEscaping is ignored when NoStringEscaping
  1805  		// is set, because it's part of the escaping options.
  1806  		{htmlChars, `"<>&"`, []Option{NoStringEscaping()}},
  1807  		{htmlChars, `"<>&"`, []Option{NoStringEscaping(), NoHTMLEscaping()}},
  1808  	}
  1809  	for _, tt := range testdata {
  1810  		b, err := MarshalOpts(string(tt.b), tt.opts...)
  1811  		if err != nil {
  1812  			t.Error(err)
  1813  		}
  1814  		if s := string(b); s != tt.s {
  1815  			t.Errorf("got %#q, want %#q", s, tt.s)
  1816  		}
  1817  	}
  1818  }
  1819  
  1820  // TestStringUTF8Coercion tests that invalid bytes
  1821  // are replaced by the Unicode replacement rune when
  1822  // a string is marshaled.
  1823  func TestStringUTF8Coercion(t *testing.T) {
  1824  	utf8Seq := string([]byte{'H', 'e', 'l', 'l', 'o', ',', ' ', 0xff, 0xfe, 0xff})
  1825  	testdata := []struct {
  1826  		b   string
  1827  		s   string
  1828  		opt Option
  1829  	}{
  1830  		{utf8Seq, `"Hello, \ufffd\ufffd\ufffd"`, nil},
  1831  		{utf8Seq, `"` + utf8Seq + `"`, NoUTF8Coercion()},
  1832  	}
  1833  	for _, tt := range testdata {
  1834  		b, err := MarshalOpts(tt.b, tt.opt)
  1835  		if err != nil {
  1836  			t.Error(err)
  1837  		}
  1838  		if s := string(b); s != tt.s {
  1839  			t.Errorf("got %#q, want %#q", s, tt.s)
  1840  		}
  1841  	}
  1842  }
  1843  
  1844  func TestMarshalFloat(t *testing.T) {
  1845  	// Taken from encoding/json.
  1846  	t.Parallel()
  1847  
  1848  	nf := 0
  1849  	mc := regexp.MustCompile
  1850  	re := []*regexp.Regexp{
  1851  		mc(`p`),
  1852  		mc(`^\+`),
  1853  		mc(`^-?0[^.]`),
  1854  		mc(`^-?\.`),
  1855  		mc(`\.(e|$)`),
  1856  		mc(`\.[0-9]+0(e|$)`),
  1857  		mc(`^-?(0|[0-9]{2,})\..*e`),
  1858  		mc(`e[0-9]`),
  1859  		mc(`e[+-]0`),
  1860  		mc(`e-[1-6]$`),
  1861  		mc(`e+(.|1.|20)$`),
  1862  		mc(`^-?0\.0000000`),
  1863  		mc(`^-?[0-9]{22}`),
  1864  		mc(`[1-9][0-9]{16}[1-9]`),
  1865  		mc(`[1-9][0-9.]{17}[1-9]`),
  1866  		mc(`[1-9][0-9]{8}[1-9]`),
  1867  		mc(`[1-9][0-9.]{9}[1-9]`),
  1868  	}
  1869  	fn := func(f float64, bits int) {
  1870  		vf := interface{}(f)
  1871  		if bits == 32 {
  1872  			f = float64(float32(f)) // round
  1873  			vf = float32(f)
  1874  		}
  1875  		bout, err := Marshal(vf)
  1876  		if err != nil {
  1877  			t.Errorf("Encode(%T(%g)): %v", vf, vf, err)
  1878  			nf++
  1879  			return
  1880  		}
  1881  		out := string(bout)
  1882  
  1883  		// Result must convert back to the same float.
  1884  		g, err := strconv.ParseFloat(out, bits)
  1885  		if err != nil {
  1886  			t.Errorf("%T(%g) = %q, cannot parse back: %v", vf, vf, out, err)
  1887  			nf++
  1888  			return
  1889  		}
  1890  		if f != g || fmt.Sprint(f) != fmt.Sprint(g) { // fmt.Sprint handles ±0
  1891  			t.Errorf("%T(%g) = %q (is %g, not %g)", vf, vf, out, float32(g), vf)
  1892  			nf++
  1893  			return
  1894  		}
  1895  		bad := re
  1896  		if bits == 64 {
  1897  			// Last two regexps are for 32-bits values only.
  1898  			bad = bad[:len(bad)-2]
  1899  		}
  1900  		for _, re := range bad {
  1901  			if re.MatchString(out) {
  1902  				t.Errorf("%T(%g) = %q, must not match /%s/", vf, vf, out, re)
  1903  				nf++
  1904  				return
  1905  			}
  1906  		}
  1907  	}
  1908  	fn(0, 64)
  1909  	fn(math.Copysign(0, -1), 64)
  1910  	fn(0, 32)
  1911  	fn(math.Copysign(0, -1), 32)
  1912  
  1913  	var (
  1914  		bigger  = math.Inf(+1)
  1915  		smaller = math.Inf(-1)
  1916  		digits  = "1.2345678901234567890123"
  1917  	)
  1918  	for i := len(digits); i >= 2; i-- {
  1919  		if testing.Short() && i < len(digits)-4 {
  1920  			break
  1921  		}
  1922  		for exp := -30; exp <= 30; exp++ {
  1923  			for _, sign := range "+-" {
  1924  				for bits := 32; bits <= 64; bits += 32 {
  1925  					s := fmt.Sprintf("%c%se%d", sign, digits[:i], exp)
  1926  					f, err := strconv.ParseFloat(s, bits)
  1927  					if err != nil {
  1928  						t.Fatal(err)
  1929  					}
  1930  					next := math.Nextafter
  1931  					if bits == 32 {
  1932  						next = func(g, h float64) float64 {
  1933  							return float64(math.Nextafter32(float32(g), float32(h)))
  1934  						}
  1935  					}
  1936  					fn(f, bits)
  1937  					fn(next(f, bigger), bits)
  1938  					fn(next(f, smaller), bits)
  1939  
  1940  					if nf > 50 {
  1941  						t.Fatalf("too many fails, stopping tests early")
  1942  					}
  1943  				}
  1944  			}
  1945  		}
  1946  	}
  1947  }