github.com/neilotoole/jsoncolor@v0.7.2-0.20231115150201-1637fae69be1/json_test.go (about)

     1  package jsoncolor
     2  
     3  import (
     4  	"bytes"
     5  	"compress/gzip"
     6  	"encoding"
     7  	"encoding/json"
     8  	"errors"
     9  	"flag"
    10  	"fmt"
    11  	"io"
    12  	"io/ioutil"
    13  	"math"
    14  	"os"
    15  	"path/filepath"
    16  	"reflect"
    17  	"runtime"
    18  	"strconv"
    19  	"strings"
    20  	"testing"
    21  	"time"
    22  )
    23  
    24  // The encoding/json package does not export the msg field of json.SyntaxError,
    25  // so we use this replacement type in tests.
    26  type testSyntaxError struct {
    27  	msg    string
    28  	Offset int64
    29  }
    30  
    31  func (e *testSyntaxError) Error() string { return e.msg }
    32  
    33  var (
    34  	marshal    func([]byte, interface{}) ([]byte, error)
    35  	unmarshal  func([]byte, interface{}) error
    36  	escapeHTML bool
    37  )
    38  
    39  func TestMain(m *testing.M) {
    40  	var pkg string
    41  	flag.StringVar(&pkg, "package", ".", "The name of the package to test (encoding/json, or default to this package)")
    42  	flag.BoolVar(&escapeHTML, "escapehtml", false, "Whether to enable HTML escaping or not")
    43  	flag.Parse()
    44  
    45  	switch pkg {
    46  	case "encoding/json":
    47  		buf := &buffer{}
    48  		enc := json.NewEncoder(buf)
    49  		enc.SetEscapeHTML(escapeHTML)
    50  
    51  		marshal = func(b []byte, v interface{}) ([]byte, error) {
    52  			buf.data = b
    53  			err := enc.Encode(v)
    54  			return buf.data, err
    55  		}
    56  
    57  		unmarshal = json.Unmarshal
    58  
    59  	default:
    60  		flags := AppendFlags(0)
    61  		if escapeHTML {
    62  			flags |= EscapeHTML
    63  		}
    64  
    65  		marshal = func(b []byte, v interface{}) ([]byte, error) {
    66  			return Append(b, v, flags, nil, nil)
    67  		}
    68  
    69  		unmarshal = func(b []byte, v interface{}) error {
    70  			_, err := Parse(b, v, ZeroCopy)
    71  			return err
    72  		}
    73  	}
    74  
    75  	os.Exit(m.Run())
    76  }
    77  
    78  type point struct {
    79  	X int `json:"x"`
    80  	Y int `json:"y"`
    81  }
    82  
    83  type tree struct {
    84  	Value string
    85  	Left  *tree
    86  	Right *tree
    87  }
    88  
    89  var testValues = [...]interface{}{
    90  	// constants
    91  	nil,
    92  	false,
    93  	true,
    94  
    95  	// int
    96  	int(0),
    97  	int(1),
    98  	int(42),
    99  	int(-1),
   100  	int(-42),
   101  	int8(math.MaxInt8),
   102  	int8(math.MinInt8),
   103  	int16(math.MaxInt16),
   104  	int16(math.MinInt16),
   105  	int32(math.MaxInt32),
   106  	int32(math.MinInt32),
   107  	int64(math.MaxInt64),
   108  	int64(math.MinInt64),
   109  
   110  	// uint
   111  	uint(0),
   112  	uint(1),
   113  	uintptr(0),
   114  	uintptr(1),
   115  	uint8(math.MaxUint8),
   116  	uint16(math.MaxUint16),
   117  	uint32(math.MaxUint32),
   118  	uint64(math.MaxUint64),
   119  
   120  	// float
   121  	float32(0),
   122  	float32(0.5),
   123  	float32(math.SmallestNonzeroFloat32),
   124  	float32(math.MaxFloat32),
   125  	float64(0),
   126  	float64(0.5),
   127  	float64(math.SmallestNonzeroFloat64),
   128  	float64(math.MaxFloat64),
   129  
   130  	// number
   131  	Number("0"),
   132  	Number("1234567890"),
   133  	Number("-0.5"),
   134  	Number("-1e+2"),
   135  
   136  	// string
   137  	"",
   138  	"Hello World!",
   139  	"Hello\"World!",
   140  	"Hello\\World!",
   141  	"Hello\nWorld!",
   142  	"Hello\rWorld!",
   143  	"Hello\tWorld!",
   144  	"Hello\bWorld!",
   145  	"Hello\fWorld!",
   146  	"你好",
   147  	"<",
   148  	">",
   149  	"&",
   150  	"\u001944",
   151  	"\u00c2e>",
   152  	"\u00c2V?",
   153  	"\u000e=8",
   154  	"\u001944\u00c2e>\u00c2V?\u000e=8",
   155  	"ir\u001bQJ\u007f\u0007y\u0015)",
   156  	strings.Repeat("A", 32),
   157  	strings.Repeat("A", 250),
   158  	strings.Repeat("A", 1020),
   159  
   160  	// bytes
   161  	[]byte(""),
   162  	[]byte("Hello World!"),
   163  	bytes.Repeat([]byte("A"), 250),
   164  	bytes.Repeat([]byte("A"), 1020),
   165  
   166  	// time
   167  	time.Unix(0, 0).In(time.UTC),
   168  	time.Unix(1, 42).In(time.UTC),
   169  	time.Unix(17179869184, 999999999).In(time.UTC),
   170  	time.Date(2016, 12, 20, 0, 20, 1, 0, time.UTC),
   171  
   172  	// array
   173  	[...]int{},
   174  	[...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
   175  
   176  	// slice
   177  	[]int{},
   178  	[]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
   179  	makeSlice(250),
   180  	makeSlice(1020),
   181  	[]string{"A", "B", "C"},
   182  	[]interface{}{nil, true, false, 0.5, "Hello World!"},
   183  
   184  	// map
   185  	makeMapStringBool(0),
   186  	makeMapStringBool(15),
   187  	makeMapStringBool(1020),
   188  	makeMapStringInterface(0),
   189  	makeMapStringInterface(15),
   190  	makeMapStringInterface(1020),
   191  	map[int]bool{1: false, 42: true},
   192  	map[textValue]bool{{1, 2}: true, {3, 4}: false},
   193  	map[string]*point{
   194  		"A": {1, 2},
   195  		"B": {3, 4},
   196  		"C": {5, 6},
   197  	},
   198  	map[string]RawMessage{
   199  		"A": RawMessage(`{}`),
   200  		"B": RawMessage(`null`),
   201  		"C": RawMessage(`42`),
   202  	},
   203  
   204  	// struct
   205  	struct{}{},
   206  	struct{ A int }{42},
   207  	struct{ A, B, C int }{1, 2, 3},
   208  	struct {
   209  		A int
   210  		T time.Time
   211  		S string
   212  	}{42, time.Date(2016, 12, 20, 0, 20, 1, 0, time.UTC), "Hello World!"},
   213  	// These types are interesting because they fit in a pointer so the compiler
   214  	// puts their value directly into the pointer field of the interface{} that
   215  	// is passed to Marshal.
   216  	struct{ X *int }{},
   217  	struct{ X *int }{new(int)},
   218  	struct{ X **int }{},
   219  	// Struct types with more than one pointer, those exercise the regular
   220  	// pointer handling with code that dereferences the fields.
   221  	struct{ X, Y *int }{},
   222  	struct{ X, Y *int }{new(int), new(int)},
   223  	struct {
   224  		A string                 `json:"name"`
   225  		B string                 `json:"-"`
   226  		C string                 `json:",omitempty"`
   227  		D map[string]interface{} `json:",string"`
   228  		e string
   229  	}{A: "Luke", D: map[string]interface{}{"answer": float64(42)}},
   230  	struct{ point }{point{1, 2}},
   231  	tree{
   232  		Value: "T",
   233  		Left:  &tree{Value: "L"},
   234  		Right: &tree{Value: "R", Left: &tree{Value: "R-L"}},
   235  	},
   236  
   237  	// pointer
   238  	(*string)(nil),
   239  	new(int),
   240  
   241  	// Marshaler/Unmarshaler
   242  	jsonValue{},
   243  	jsonValue{1, 2},
   244  
   245  	// encoding.TextMarshaler/encoding.TextUnmarshaler
   246  	textValue{},
   247  	textValue{1, 2},
   248  
   249  	// RawMessage
   250  	RawMessage(`{
   251  	"answer": 42,
   252  	"hello": "world"
   253  }`),
   254  
   255  	// fixtures
   256  	loadTestdata(filepath.Join(runtime.GOROOT(), "src/encoding/json/testdata/code.json.gz")),
   257  }
   258  
   259  var durationTestValues = []interface{}{
   260  	// duration
   261  	time.Nanosecond,
   262  	time.Microsecond,
   263  	time.Millisecond,
   264  	time.Second,
   265  	time.Minute,
   266  	time.Hour,
   267  
   268  	// struct with duration
   269  	struct{ D1, D2 time.Duration }{time.Millisecond, time.Hour},
   270  }
   271  
   272  func makeSlice(n int) []int {
   273  	s := make([]int, n)
   274  	for i := range s {
   275  		s[i] = i
   276  	}
   277  	return s
   278  }
   279  
   280  func makeMapStringBool(n int) map[string]bool {
   281  	m := make(map[string]bool, n)
   282  	for i := 0; i != n; i++ {
   283  		m[strconv.Itoa(i)] = true
   284  	}
   285  	return m
   286  }
   287  
   288  func makeMapStringInterface(n int) map[string]interface{} {
   289  	m := make(map[string]interface{}, n)
   290  	for i := 0; i != n; i++ {
   291  		m[strconv.Itoa(i)] = nil
   292  	}
   293  	return m
   294  }
   295  
   296  func testName(v interface{}) string {
   297  	return fmt.Sprintf("%T", v)
   298  }
   299  
   300  type codeResponse2 struct {
   301  	Tree     *codeNode2 `json:"tree"`
   302  	Username string     `json:"username"`
   303  }
   304  
   305  type codeNode2 struct {
   306  	Name     string      `json:"name"`
   307  	Kids     []*codeNode `json:"kids"`
   308  	CLWeight float64     `json:"cl_weight"`
   309  	Touches  int         `json:"touches"`
   310  	MinT     int64       `json:"min_t"`
   311  	MaxT     int64       `json:"max_t"`
   312  	MeanT    int64       `json:"mean_t"`
   313  }
   314  
   315  func loadTestdata(path string) interface{} {
   316  	f, err := os.Open(path)
   317  	if err != nil {
   318  		return err.Error()
   319  	}
   320  	defer f.Close()
   321  
   322  	r, err := gzip.NewReader(f)
   323  	if err != nil {
   324  		return err.Error()
   325  	}
   326  	defer r.Close()
   327  
   328  	testdata := new(codeResponse2)
   329  	if err := json.NewDecoder(r).Decode(testdata); err != nil {
   330  		return err.Error()
   331  	}
   332  	return testdata
   333  }
   334  
   335  func TestCodec(t *testing.T) {
   336  	for _, v1 := range testValues {
   337  		t.Run(testName(v1), func(t *testing.T) {
   338  			v2 := newValue(v1)
   339  
   340  			a, err := json.MarshalIndent(v1, "", "\t")
   341  			if err != nil {
   342  				t.Error(err)
   343  				return
   344  			}
   345  			a = append(a, '\n')
   346  
   347  			buf := &bytes.Buffer{}
   348  			enc := NewEncoder(buf)
   349  			enc.SetIndent("", "\t")
   350  
   351  			if err := enc.Encode(v1); err != nil {
   352  				t.Error(err)
   353  				return
   354  			}
   355  			b := buf.Bytes()
   356  
   357  			if !Valid(b) {
   358  				t.Error("invalid JSON representation")
   359  			}
   360  
   361  			if !bytes.Equal(a, b) {
   362  				t.Error("JSON representations mismatch")
   363  				t.Log("expected:", string(a))
   364  				t.Log("found:   ", string(b))
   365  			}
   366  
   367  			dec := NewDecoder(bytes.NewBuffer(b))
   368  
   369  			if err := dec.Decode(v2.Interface()); err != nil {
   370  				t.Errorf("%T: %v", err, err)
   371  				return
   372  			}
   373  
   374  			x1 := v1
   375  			x2 := v2.Elem().Interface()
   376  
   377  			if !reflect.DeepEqual(x1, x2) {
   378  				t.Error("values mismatch")
   379  				t.Logf("expected: %#v", x1)
   380  				t.Logf("found:    %#v", x2)
   381  			}
   382  
   383  			if b, err := ioutil.ReadAll(dec.Buffered()); err != nil {
   384  				t.Error(err)
   385  			} else if len(b) != 0 {
   386  				t.Errorf("leftover trailing bytes in the decoder: %q", b)
   387  			}
   388  		})
   389  	}
   390  }
   391  
   392  // TestCodecDuration isolates testing of time.Duration.  The stdlib un/marshals
   393  // this type as integers whereas this library un/marshals formatted string
   394  // values.  Therefore, plugging durations into TestCodec would cause fail since
   395  // it checks equality on the marshaled strings from the two libraries.
   396  func TestCodecDuration(t *testing.T) {
   397  	t.Skip("Skipping because neilotoole/jsoncolor follows stdlib (encode to int64) rather than segmentj (encode to string)")
   398  	for _, v1 := range durationTestValues {
   399  		t.Run(testName(v1), func(t *testing.T) {
   400  			v2 := newValue(v1)
   401  
   402  			// encode using stdlib. (will be an int)
   403  			std, err := json.MarshalIndent(v1, "", "\t")
   404  			if err != nil {
   405  				t.Error(err)
   406  				return
   407  			}
   408  			std = append(std, '\n')
   409  
   410  			// decode using our decoder. (reads int to duration)
   411  			dec := NewDecoder(bytes.NewBuffer([]byte(std)))
   412  
   413  			if err := dec.Decode(v2.Interface()); err != nil {
   414  				t.Errorf("%T: %v", err, err)
   415  				return
   416  			}
   417  
   418  			x1 := v1
   419  			x2 := v2.Elem().Interface()
   420  
   421  			if !reflect.DeepEqual(x1, x2) {
   422  				t.Error("values mismatch")
   423  				t.Logf("expected: %#v", x1)
   424  				t.Logf("found:    %#v", x2)
   425  			}
   426  
   427  			// encoding using our encoder. (writes duration as string)
   428  			buf := &bytes.Buffer{}
   429  			enc := NewEncoder(buf)
   430  			enc.SetIndent("", "\t")
   431  
   432  			if err := enc.Encode(v1); err != nil {
   433  				t.Error(err)
   434  				return
   435  			}
   436  			b := buf.Bytes()
   437  
   438  			if !Valid(b) {
   439  				t.Error("invalid JSON representation")
   440  			}
   441  
   442  			if reflect.DeepEqual(std, b) {
   443  				t.Error("encoded durations should not match stdlib")
   444  				t.Logf("got: %s", b)
   445  			}
   446  
   447  			// decode using our decoder. (reads string to duration)
   448  			dec = NewDecoder(bytes.NewBuffer([]byte(std)))
   449  
   450  			if err := dec.Decode(v2.Interface()); err != nil {
   451  				t.Errorf("%T: %v", err, err)
   452  				return
   453  			}
   454  
   455  			x1 = v1
   456  			x2 = v2.Elem().Interface()
   457  
   458  			if !reflect.DeepEqual(x1, x2) {
   459  				t.Error("values mismatch")
   460  				t.Logf("expected: %#v", x1)
   461  				t.Logf("found:    %#v", x2)
   462  			}
   463  		})
   464  	}
   465  }
   466  
   467  func newValue(model interface{}) reflect.Value {
   468  	if model == nil {
   469  		return reflect.New(reflect.TypeOf(&model).Elem())
   470  	}
   471  	return reflect.New(reflect.TypeOf(model))
   472  }
   473  
   474  func BenchmarkMarshal(b *testing.B) {
   475  	j := make([]byte, 0, 128*1024)
   476  
   477  	for _, v := range testValues {
   478  		b.Run(testName(v), func(b *testing.B) {
   479  			if marshal == nil {
   480  				return
   481  			}
   482  
   483  			for i := 0; i != b.N; i++ {
   484  				j, _ = marshal(j[:0], v)
   485  			}
   486  
   487  			b.SetBytes(int64(len(j)))
   488  		})
   489  	}
   490  }
   491  
   492  func BenchmarkUnmarshal(b *testing.B) {
   493  	for _, v := range testValues {
   494  		b.Run(testName(v), func(b *testing.B) {
   495  			if unmarshal == nil {
   496  				return
   497  			}
   498  
   499  			x := v
   500  			if d, ok := x.(time.Duration); ok {
   501  				x = duration(d)
   502  			}
   503  
   504  			j, _ := json.Marshal(x)
   505  			x = newValue(v).Interface()
   506  
   507  			for i := 0; i != b.N; i++ {
   508  				unmarshal(j, x)
   509  			}
   510  
   511  			b.SetBytes(int64(len(j)))
   512  		})
   513  	}
   514  }
   515  
   516  type buffer struct{ data []byte }
   517  
   518  func (buf *buffer) Write(b []byte) (int, error) {
   519  	buf.data = append(buf.data, b...)
   520  	return len(b), nil
   521  }
   522  
   523  func (buf *buffer) WriteString(s string) (int, error) {
   524  	buf.data = append(buf.data, s...)
   525  	return len(s), nil
   526  }
   527  
   528  type jsonValue struct {
   529  	x int32
   530  	y int32
   531  }
   532  
   533  func (v jsonValue) MarshalJSON() ([]byte, error) {
   534  	return Marshal([2]int32{v.x, v.y})
   535  }
   536  
   537  func (v *jsonValue) UnmarshalJSON(b []byte) error {
   538  	var a [2]int32
   539  	err := Unmarshal(b, &a)
   540  	v.x = a[0]
   541  	v.y = a[1]
   542  	return err
   543  }
   544  
   545  type textValue struct {
   546  	x int32
   547  	y int32
   548  }
   549  
   550  func (v textValue) MarshalText() ([]byte, error) {
   551  	return []byte(fmt.Sprintf("(%d,%d)", v.x, v.y)), nil
   552  }
   553  
   554  func (v *textValue) UnmarshalText(b []byte) error {
   555  	_, err := fmt.Sscanf(string(b), "(%d,%d)", &v.x, &v.y)
   556  	return err
   557  }
   558  
   559  type duration time.Duration
   560  
   561  func (d duration) MarshalJSON() ([]byte, error) {
   562  	return []byte(`"` + time.Duration(d).String() + `"`), nil
   563  }
   564  
   565  func (d *duration) UnmarshalJSON(b []byte) error {
   566  	var s string
   567  	if err := json.Unmarshal(b, &s); err != nil {
   568  		return err
   569  	}
   570  	x, err := time.ParseDuration(s)
   571  	*d = duration(x)
   572  	return err
   573  }
   574  
   575  var (
   576  	_ Marshaler = jsonValue{}
   577  	_ Marshaler = duration(0)
   578  
   579  	_ encoding.TextMarshaler = textValue{}
   580  
   581  	_ Unmarshaler = (*jsonValue)(nil)
   582  	_ Unmarshaler = (*duration)(nil)
   583  
   584  	_ encoding.TextUnmarshaler = (*textValue)(nil)
   585  )
   586  
   587  func TestDecodeStructFieldCaseInsensitive(t *testing.T) {
   588  	b := []byte(`{ "type": "changed" }`)
   589  	s := struct {
   590  		Type string
   591  	}{"unchanged"}
   592  
   593  	if err := Unmarshal(b, &s); err != nil {
   594  		t.Error(err)
   595  	}
   596  
   597  	if s.Type != "changed" {
   598  		t.Error("s.Type: expected to be changed but found", s.Type)
   599  	}
   600  }
   601  
   602  func TestDecodeLines(t *testing.T) {
   603  	tests := []struct {
   604  		desc        string
   605  		reader      io.Reader
   606  		expectCount int
   607  	}{
   608  		// simple
   609  
   610  		{
   611  			desc:        "bare object",
   612  			reader:      strings.NewReader("{\"Good\":true}"),
   613  			expectCount: 1,
   614  		},
   615  		{
   616  			desc:        "multiple objects on one line",
   617  			reader:      strings.NewReader("{\"Good\":true}{\"Good\":true}\n"),
   618  			expectCount: 2,
   619  		},
   620  		{
   621  			desc:        "object spanning multiple lines",
   622  			reader:      strings.NewReader("{\n\"Good\":true\n}\n"),
   623  			expectCount: 1,
   624  		},
   625  
   626  		// whitespace handling
   627  
   628  		{
   629  			desc:        "trailing newline",
   630  			reader:      strings.NewReader("{\"Good\":true}\n{\"Good\":true}\n"),
   631  			expectCount: 2,
   632  		},
   633  		{
   634  			desc:        "multiple trailing newlines",
   635  			reader:      strings.NewReader("{\"Good\":true}\n{\"Good\":true}\n\n"),
   636  			expectCount: 2,
   637  		},
   638  		{
   639  			desc:        "blank lines",
   640  			reader:      strings.NewReader("{\"Good\":true}\n\n{\"Good\":true}"),
   641  			expectCount: 2,
   642  		},
   643  		{
   644  			desc:        "no trailing newline",
   645  			reader:      strings.NewReader("{\"Good\":true}\n{\"Good\":true}"),
   646  			expectCount: 2,
   647  		},
   648  		{
   649  			desc:        "leading whitespace",
   650  			reader:      strings.NewReader("  {\"Good\":true}\n\t{\"Good\":true}"),
   651  			expectCount: 2,
   652  		},
   653  
   654  		// multiple reads
   655  
   656  		{
   657  			desc: "one object, multiple reads",
   658  			reader: io.MultiReader(
   659  				strings.NewReader("{"),
   660  				strings.NewReader("\"Good\": true"),
   661  				strings.NewReader("}\n"),
   662  			),
   663  			expectCount: 1,
   664  		},
   665  
   666  		// EOF reads
   667  
   668  		{
   669  			desc:        "one object + EOF",
   670  			reader:      &eofReader{"{\"Good\":true}\n"},
   671  			expectCount: 1,
   672  		},
   673  		{
   674  			desc:        "leading whitespace + EOF",
   675  			reader:      &eofReader{"\n{\"Good\":true}\n"},
   676  			expectCount: 1,
   677  		},
   678  		{
   679  			desc:        "multiple objects + EOF",
   680  			reader:      &eofReader{"{\"Good\":true}\n{\"Good\":true}\n"},
   681  			expectCount: 2,
   682  		},
   683  		{
   684  			desc: "one object + multiple reads + EOF",
   685  			reader: io.MultiReader(
   686  				strings.NewReader("{"),
   687  				strings.NewReader("  \"Good\": true"),
   688  				&eofReader{"}\n"},
   689  			),
   690  			expectCount: 1,
   691  		},
   692  		{
   693  			desc: "multiple objects + multiple reads + EOF",
   694  			reader: io.MultiReader(
   695  				strings.NewReader("{"),
   696  				strings.NewReader("  \"Good\": true}{\"Good\": true}"),
   697  				&eofReader{"\n"},
   698  			),
   699  			expectCount: 2,
   700  		},
   701  
   702  		{
   703  			// the 2nd object should be discarded, as 42 cannot be cast to bool
   704  			desc:        "unmarshal error while decoding",
   705  			reader:      strings.NewReader("{\"Good\":true}\n{\"Good\":42}\n{\"Good\":true}\n"),
   706  			expectCount: 2,
   707  		},
   708  		{
   709  			// the 2nd object should be discarded, as 42 cannot be cast to bool
   710  			desc:        "unmarshal error while decoding last object",
   711  			reader:      strings.NewReader("{\"Good\":true}\n{\"Good\":42}\n"),
   712  			expectCount: 1,
   713  		},
   714  	}
   715  
   716  	type obj struct {
   717  		Good bool
   718  	}
   719  
   720  	for _, test := range tests {
   721  		t.Run(test.desc, func(t *testing.T) {
   722  			d := NewDecoder(test.reader)
   723  			var count int
   724  			var err error
   725  			for {
   726  				var o obj
   727  				err = d.Decode(&o)
   728  				if err != nil {
   729  					if err == io.EOF {
   730  						break
   731  					}
   732  
   733  					switch err.(type) {
   734  					case *SyntaxError, *UnmarshalTypeError:
   735  						t.Log("unmarshal error", err)
   736  						continue
   737  					}
   738  
   739  					t.Error("decode error", err)
   740  					break
   741  				}
   742  				if !o.Good {
   743  					t.Errorf("object was not unmarshaled correctly: %#v", o)
   744  				}
   745  				count++
   746  			}
   747  
   748  			if err != nil && err != io.EOF {
   749  				t.Error(err)
   750  			}
   751  
   752  			if count != test.expectCount {
   753  				t.Errorf("expected %d objects, got %d", test.expectCount, count)
   754  			}
   755  		})
   756  	}
   757  }
   758  
   759  // eofReader is a simple io.Reader that reads its full contents _and_ returns
   760  // and EOF in the first call. Subsequent Read calls only return EOF.
   761  type eofReader struct {
   762  	s string
   763  }
   764  
   765  func (r *eofReader) Read(p []byte) (n int, err error) {
   766  	n = copy(p, r.s)
   767  	r.s = r.s[n:]
   768  	if r.s == "" {
   769  		err = io.EOF
   770  	}
   771  	return
   772  }
   773  
   774  func TestDontMatchCaseIncensitiveStructFields(t *testing.T) {
   775  	b := []byte(`{ "type": "changed" }`)
   776  	s := struct {
   777  		Type string
   778  	}{"unchanged"}
   779  
   780  	if _, err := Parse(b, &s, DontMatchCaseInsensitiveStructFields); err != nil {
   781  		t.Error(err)
   782  	}
   783  
   784  	if s.Type != "unchanged" {
   785  		t.Error("s.Type: expected to be unchanged but found", s.Type)
   786  	}
   787  }
   788  
   789  func TestMarshalFuzzBugs(t *testing.T) {
   790  	tests := []struct {
   791  		value  interface{}
   792  		output string
   793  	}{
   794  		{ // html sequences are escaped even in RawMessage
   795  			value: struct {
   796  				P RawMessage
   797  			}{P: RawMessage(`"<"`)},
   798  			output: "{\"P\":\"\\u003c\"}",
   799  		},
   800  		{ // raw message output is compacted
   801  			value: struct {
   802  				P RawMessage
   803  			}{P: RawMessage(`{"" :{}}`)},
   804  			output: "{\"P\":{\"\":{}}}",
   805  		},
   806  	}
   807  
   808  	for _, test := range tests {
   809  		t.Run("", func(t *testing.T) {
   810  			b, err := Marshal(test.value)
   811  			if err != nil {
   812  				t.Fatal(err)
   813  			}
   814  
   815  			if string(b) != test.output {
   816  				t.Error("values mismatch")
   817  				t.Logf("expected: %#v", test.output)
   818  				t.Logf("found:    %#v", string(b))
   819  			}
   820  		})
   821  	}
   822  }
   823  
   824  func TestUnmarshalFuzzBugs(t *testing.T) {
   825  	tests := []struct {
   826  		input string
   827  		value interface{}
   828  	}{
   829  		{ // non-UTF8 sequences must be converted to the utf8.RuneError character.
   830  			input: "[\"00000\xef\"]",
   831  			value: []interface{}{"00000�"},
   832  		},
   833  		{ // UTF16 surrogate followed by null character
   834  			input: "[\"\\ud800\\u0000\"]",
   835  			value: []interface{}{"�\x00"},
   836  		},
   837  		{ // UTF16 surrogate followed by ascii character
   838  			input: "[\"\\uDF00\\u000e\"]",
   839  			value: []interface{}{"�\x0e"},
   840  		},
   841  		{ // UTF16 surrogate followed by unicode character
   842  			input: "[[\"\\uDF00\\u0800\"]]",
   843  			value: []interface{}{[]interface{}{"�ࠀ"}},
   844  		},
   845  		{ // invalid UTF16 surrogate sequenced followed by a valid UTF16 surrogate sequence
   846  			input: "[\"\\udf00\\udb00\\udf00\"]",
   847  			value: []interface{}{"�\U000d0300"},
   848  		},
   849  		{ // decode single-element slice into []byte field
   850  			input: "{\"f\":[0],\"0\":[0]}",
   851  			value: struct{ F []byte }{F: []byte{0}},
   852  		},
   853  		{ // decode multi-element slice into []byte field
   854  			input: "{\"F\":[3,1,1,1,9,9]}",
   855  			value: struct{ F []byte }{F: []byte{3, 1, 1, 1, 9, 9}},
   856  		},
   857  		{ // decode string with escape sequence into []byte field
   858  			input: "{\"F\":\"0p00\\r\"}",
   859  			value: struct{ F []byte }{F: []byte("ҝ4")},
   860  		},
   861  		{ // decode unicode code points which fold into ascii characters
   862  			input: "{\"ſ\":\"8\"}",
   863  			value: struct {
   864  				S int `json:",string"`
   865  			}{S: 8},
   866  		},
   867  		{ // decode unicode code points which don't fold into ascii characters
   868  			input: "{\"İ\":\"\"}",
   869  			value: struct{ I map[string]string }{I: nil},
   870  		},
   871  		{ // override pointer-to-pointer field clears the inner pointer only
   872  			input: "{\"o\":0,\"o\":null}",
   873  			value: struct{ O **int }{O: new(*int)},
   874  		},
   875  		{ // subsequent occurrences of a map field retain keys previously loaded
   876  			input: "{\"i\":{\"\":null},\"i\":{}}",
   877  			value: struct{ I map[string]string }{I: map[string]string{"": ""}},
   878  		},
   879  		{ // an empty string is an invalid JSON input
   880  			input: "",
   881  		},
   882  		{ // ASCII character below 0x20 are invalid JSON input
   883  			input: "[\"\b\"]",
   884  		},
   885  		{ // random byte before any value
   886  			input: "\xad",
   887  		},
   888  		{ // cloud be the beginning of a false value but not
   889  			input: "f",
   890  			value: false,
   891  		},
   892  		{ // random ASCII character
   893  			input: "}",
   894  			value: []interface{}{},
   895  		},
   896  		{ // random byte after valid JSON, decoded to a nil type
   897  			input: "0\x93",
   898  		},
   899  		{ // random byte after valid JSON, decoded to a int type
   900  			input: "0\x93",
   901  			value: 0,
   902  		},
   903  		{ // random byte after valid JSON, decoded to a slice type
   904  			input: "0\x93",
   905  			value: []interface{}{},
   906  		},
   907  		{ // decode integer into slice
   908  			input: "0",
   909  			value: []interface{}{},
   910  		},
   911  		{ // decode integer with trailing space into slice
   912  			input: "0\t",
   913  			value: []interface{}{},
   914  		},
   915  		{ // decode integer with leading random bytes into slice
   916  			input: "\b0",
   917  			value: []interface{}{},
   918  		},
   919  		{ // decode string into slice followed by number
   920  			input: "\"\"0",
   921  			value: []interface{}{},
   922  		},
   923  		{ // decode what looks like an object followed by a number into a string
   924  			input: "{0",
   925  			value: "",
   926  		},
   927  		{ // decode what looks like an object followed by a number into a map
   928  			input: "{0",
   929  			value: map[string]string{},
   930  		},
   931  		{ // decode string into string with trailing random byte
   932  			input: "\"\"\f",
   933  			value: "",
   934  		},
   935  		{ // decode weird number value into nil
   936  			input: "-00",
   937  		},
   938  		{ // decode an invalid escaped sequence
   939  			input: "\"\\0\"",
   940  			value: "",
   941  		},
   942  		{ // decode what looks like an array followed by a number into a slice
   943  			input: "[9E600",
   944  			value: []interface{}{},
   945  		},
   946  		{ // decode a number which is too large to fit in a float64
   947  			input: "[1e900]",
   948  			value: []interface{}{},
   949  		},
   950  		{ // many nested arrays openings
   951  			input: "[[[[[[",
   952  			value: []interface{}{},
   953  		},
   954  		{ // decode a map with value type mismatch and missing closing character
   955  			input: "{\"\":0",
   956  			value: map[string]string{},
   957  		},
   958  		{ // decode a struct with value type mismatch and missing closing character
   959  			input: "{\"E\":\"\"",
   960  			value: struct{ E uint8 }{},
   961  		},
   962  		{ // decode a map with value type mismatch
   963  			input: "{\"\":0}",
   964  			value: map[string]string{},
   965  		},
   966  		{ // decode number with exponent into integer field
   967  			input: "{\"e\":0e0}",
   968  			value: struct{ E uint8 }{},
   969  		},
   970  		{ // decode invalid integer representation into integer field
   971  			input: "{\"e\":00}",
   972  			value: struct{ E uint8 }{},
   973  		},
   974  		{ // decode unterminated array into byte slice
   975  			input: "{\"F\":[",
   976  			value: struct{ F []byte }{},
   977  		},
   978  		{ // attempt to decode string into in
   979  			input: "{\"S\":\"\"}",
   980  			value: struct {
   981  				S int `json:",string"`
   982  			}{},
   983  		},
   984  		{ // decode object with null key into map
   985  			input: "{null:0}",
   986  			value: map[string]interface{}{},
   987  		},
   988  		{ // decode unquoted integer into struct field with string tag
   989  			input: "{\"S\":0}",
   990  			value: struct {
   991  				S int `json:",string"`
   992  			}{},
   993  		},
   994  		{ // invalid base64 content when decoding string into byte slice
   995  			input: "{\"F\":\"0\"}",
   996  			value: struct{ F []byte }{},
   997  		},
   998  		{ // decode an object with a "null" string as key
   999  			input: "{\"null\":null}",
  1000  			value: struct {
  1001  				S int `json:",string"`
  1002  			}{},
  1003  		},
  1004  		{ // decode an invalid floating point number representation into an integer field with string tag
  1005  			input: "{\"s\":8e800}",
  1006  			value: struct {
  1007  				S int `json:",string"`
  1008  			}{},
  1009  		},
  1010  		{ // decode a string with leading zeroes into an integer field with string tag
  1011  			input: "{\"S\":\"00\"}",
  1012  			value: struct {
  1013  				S int `json:",string"`
  1014  			}{},
  1015  		},
  1016  		{ // decode a string with invalid leading sign and zeroes into an integer field with string tag
  1017  			input: "{\"S\":\"+00\"}",
  1018  			value: struct {
  1019  				S int `json:",string"`
  1020  			}{},
  1021  		},
  1022  		{ // decode a string with valid leading sign and zeroes into an integer field with string tag
  1023  			input: "{\"S\":\"-00\"}",
  1024  			value: struct {
  1025  				S int `json:",string"`
  1026  			}{},
  1027  		},
  1028  		{ // decode non-ascii string into integer field with string tag
  1029  			input: "{\"ſ\":\"\xbf\"}",
  1030  			value: struct {
  1031  				S int `json:",string"`
  1032  			}{},
  1033  		},
  1034  		{ // decode a valid floating point number representation into an integer field with string tag
  1035  			input: "{\"S\":0.0}",
  1036  			value: struct {
  1037  				S int `json:",string"`
  1038  			}{},
  1039  		},
  1040  		{ // decode string with invalid leading sign to integer field with string tag
  1041  			input: "{\"S\":\"+0\"}",
  1042  			value: struct {
  1043  				S int `json:",string"`
  1044  			}{},
  1045  		},
  1046  		{ // decode string with valid leading sign to integer field with string tag
  1047  			input: "{\"S\":\"-0\"}",
  1048  			value: struct {
  1049  				S int `json:",string"`
  1050  			}{},
  1051  		},
  1052  		{ // decode string with object representation to integer field with string tag
  1053  			input: "{\"s\":{}}",
  1054  			value: struct {
  1055  				S int `json:",string"`
  1056  			}{},
  1057  		},
  1058  		{ // decoding integer with leading zeroes
  1059  			input: "{\"o\":00}",
  1060  			value: struct{ O **int }{},
  1061  		},
  1062  		{ // codeding string with invalid float representation into integer field with string tag
  1063  			input: "{\"s\":\"0.\"}",
  1064  			value: struct {
  1065  				S int `json:",string"`
  1066  			}{},
  1067  		},
  1068  		{ // malformed negative integer in object value
  1069  			input: "{\"N\":-00}",
  1070  			value: struct{ N *int }{},
  1071  		},
  1072  		{ // integer overflow
  1073  			input: "{\"a\":9223372036854775808}",
  1074  			value: struct {
  1075  				A int `json:",omitempty"`
  1076  			}{},
  1077  		},
  1078  		{ // decode string with number followed by random byte into integer field with string tag
  1079  			input: "{\"s\":\"0]\"}",
  1080  			value: struct {
  1081  				S int `json:",string"`
  1082  			}{},
  1083  		},
  1084  		{ // decode object into integer field
  1085  			input: "{\"n\":{}}",
  1086  			value: struct{ N *int }{},
  1087  		},
  1088  		{ // decode negative integer into unsigned type
  1089  			input: "{\"E\":-0}",
  1090  			value: struct{ E uint8 }{},
  1091  		},
  1092  		{ // decode string with number followed by random byte into integer field with string tag
  1093  			input: "{\"s\":\"03�\"}",
  1094  			value: struct {
  1095  				S int `json:",string"`
  1096  			}{},
  1097  		},
  1098  		{ // decode string with leading zeroes into integer field with string tag
  1099  			input: "{\"s\":\"03\"}",
  1100  			value: struct {
  1101  				S int `json:",string"`
  1102  			}{S: 3},
  1103  		},
  1104  		{ // decode string containing what looks like an object into integer field with string tag
  1105  			input: "{\"S\":\"{}\"}",
  1106  			value: struct {
  1107  				S int `json:",string"`
  1108  			}{},
  1109  		},
  1110  		{ // decode an empty string followed by the same field with a null value into a byte slice
  1111  			input: "{\"F\":\"\",\"F\":null}",
  1112  			value: struct{ F []byte }{},
  1113  		},
  1114  		{ // decode string containing a float into an integer field with string tag
  1115  			input: "{\"S\":\"0e0\"}",
  1116  			value: struct {
  1117  				S int `json:",string"`
  1118  			}{},
  1119  		},
  1120  		{ // decode string with negative sign into a an integer field with string tag
  1121  			input: "{\"s\":\"-\"}",
  1122  			value: struct {
  1123  				S int `json:",string"`
  1124  			}{},
  1125  		},
  1126  		{ // decode string with positive sign into a an integer field with string tag
  1127  			input: "{\"s\":\"+\"}",
  1128  			value: struct {
  1129  				S int `json:",string"`
  1130  			}{},
  1131  		},
  1132  		{ // decode an integer into a json unmarshaler
  1133  			input: "{\"q\":0}",
  1134  			value: struct {
  1135  				Q testMarshaller
  1136  			}{},
  1137  		},
  1138  		// This test fails because it appears that the encoding/json package
  1139  		// will decode "q" before "s", so it returns an error about "q" being of
  1140  		// the wrong type while this package will prase object keys in the order
  1141  		// that they appear in the JSON input, so it detects the error from "s"
  1142  		// first.
  1143  		//
  1144  		//{
  1145  		//	input: "{\"s\":0,\"q\":0}",
  1146  		//	value: struct {
  1147  		//		Q testMarshaller
  1148  		//		S int `json:",string"`
  1149  		//	}{},
  1150  		//},
  1151  	}
  1152  
  1153  	for _, test := range tests {
  1154  		t.Run("", func(t *testing.T) {
  1155  			var ptr1 interface{}
  1156  			var ptr2 interface{}
  1157  
  1158  			if test.value != nil {
  1159  				ptr1 = reflect.New(reflect.TypeOf(test.value)).Interface()
  1160  				ptr2 = reflect.New(reflect.TypeOf(test.value)).Interface()
  1161  			}
  1162  
  1163  			err1 := json.Unmarshal([]byte(test.input), ptr1)
  1164  			err2 := Unmarshal([]byte(test.input), ptr2)
  1165  
  1166  			if reflect.TypeOf(err1) != reflect.TypeOf(err2) {
  1167  				t.Error("errors mismatch")
  1168  				t.Logf("expected: %T: %v", err1, err1)
  1169  				t.Logf("found:    %T: %v", err2, err2)
  1170  			} else if err1 == nil && test.value != nil {
  1171  				if value := reflect.ValueOf(ptr2).Elem().Interface(); !reflect.DeepEqual(test.value, value) {
  1172  					t.Error("values mismatch")
  1173  					t.Logf("expected: %#v", test.value)
  1174  					t.Logf("found:    %#v", value)
  1175  				}
  1176  			}
  1177  		})
  1178  	}
  1179  }
  1180  
  1181  func BenchmarkEasyjsonUnmarshalSmallStruct(b *testing.B) {
  1182  	type Hashtag struct {
  1183  		Indices []int  `json:"indices"`
  1184  		Text    string `json:"text"`
  1185  	}
  1186  
  1187  	//easyjson:json
  1188  	type Entities struct {
  1189  		Hashtags     []Hashtag `json:"hashtags"`
  1190  		Urls         []*string `json:"urls"`
  1191  		UserMentions []*string `json:"user_mentions"`
  1192  	}
  1193  
  1194  	json := []byte(`{"hashtags":[{"indices":[5, 10],"text":"some-text"}],"urls":[],"user_mentions":[]}`)
  1195  
  1196  	for i := 0; i < b.N; i++ {
  1197  		var value Entities
  1198  		if err := Unmarshal(json, &value); err != nil {
  1199  			b.Fatal(err)
  1200  		}
  1201  	}
  1202  }
  1203  
  1204  type testMarshaller struct {
  1205  	v string
  1206  }
  1207  
  1208  func (m *testMarshaller) MarshalJSON() ([]byte, error) {
  1209  	return Marshal(m.v)
  1210  }
  1211  
  1212  func (m *testMarshaller) UnmarshalJSON(data []byte) error {
  1213  	return Unmarshal(data, &m.v)
  1214  }
  1215  
  1216  func TestGithubIssue11(t *testing.T) {
  1217  	// https://github.com/segmentio/encoding/issues/11
  1218  	v := struct{ F float64 }{
  1219  		F: math.NaN(),
  1220  	}
  1221  
  1222  	_, err := Marshal(v)
  1223  	if err == nil {
  1224  		t.Error("no error returned when marshalling NaN value")
  1225  	} else if s := err.Error(); !strings.Contains(s, "NaN") {
  1226  		t.Error("error returned when marshalling NaN value does not mention 'NaN':", s)
  1227  	} else {
  1228  		t.Log(s)
  1229  	}
  1230  }
  1231  
  1232  type Issue13 struct {
  1233  	Stringer fmt.Stringer
  1234  	Field    int `json:"MyInt"`
  1235  }
  1236  
  1237  type S string
  1238  
  1239  func (s S) String() string { return string(s) }
  1240  
  1241  func TestGithubIssue13(t *testing.T) {
  1242  	// https://github.com/segmentio/encoding/issues/13
  1243  	v := Issue13{}
  1244  
  1245  	b, err := Marshal(v)
  1246  	if err != nil {
  1247  		t.Error("unexpected errror:", err)
  1248  	} else {
  1249  		t.Log(string(b))
  1250  	}
  1251  
  1252  	v = Issue13{Stringer: S("")}
  1253  	if err := Unmarshal([]byte(`{"Stringer":null}`), &v); err != nil {
  1254  		t.Error("unexpected error:", err)
  1255  	}
  1256  	if v.Stringer != nil {
  1257  		t.Error("Stringer field was not overwritten")
  1258  	}
  1259  
  1260  	v = Issue13{}
  1261  	if err := Unmarshal([]byte(`{"Stringer":"whatever"}`), &v); err == nil {
  1262  		t.Error("expected error but decoding string value into nil fmt.Stringer but got <nil>")
  1263  	}
  1264  
  1265  	v = Issue13{Stringer: S("")}
  1266  	if err := Unmarshal([]byte(`{"Stringer":"whatever"}`), &v); err == nil {
  1267  		t.Error("expected error but decoding string value into non-pointer fmt.Stringer but got <nil>")
  1268  	}
  1269  
  1270  	s := S("")
  1271  	v = Issue13{Stringer: &s}
  1272  	if err := Unmarshal([]byte(`{"Stringer":"whatever"}`), &v); err != nil {
  1273  		t.Error("unexpected error decoding string value into pointer fmt.Stringer:", err)
  1274  	}
  1275  }
  1276  
  1277  func TestGithubIssue15(t *testing.T) {
  1278  	// https://github.com/segmentio/encoding/issues/15
  1279  	tests := []struct {
  1280  		m interface{}
  1281  		s string
  1282  	}{
  1283  		{
  1284  			m: map[uint]bool{1: true, 123: true, 333: true, 42: true},
  1285  			s: `{"1":true,"123":true,"333":true,"42":true}`,
  1286  		},
  1287  		{
  1288  			m: map[int]bool{-1: true, -123: true, 333: true, 42: true},
  1289  			s: `{"-1":true,"-123":true,"333":true,"42":true}`,
  1290  		},
  1291  	}
  1292  
  1293  	for _, test := range tests {
  1294  		b, _ := Marshal(test.m)
  1295  
  1296  		if string(b) != test.s {
  1297  			t.Error("map with integer keys must be ordered by their string representation, got", string(b))
  1298  		}
  1299  
  1300  	}
  1301  }
  1302  
  1303  type sliceA []byte
  1304  
  1305  func (sliceA) MarshalJSON() ([]byte, error) {
  1306  	return []byte(`"A"`), nil
  1307  }
  1308  
  1309  type sliceB []byte
  1310  
  1311  func (sliceB) MarshalText() ([]byte, error) {
  1312  	return []byte("B"), nil
  1313  }
  1314  
  1315  type mapA map[string]string
  1316  
  1317  func (mapA) MarshalJSON() ([]byte, error) {
  1318  	return []byte(`"A"`), nil
  1319  }
  1320  
  1321  type mapB map[string]string
  1322  
  1323  func (mapB) MarshalText() ([]byte, error) {
  1324  	return []byte("B"), nil
  1325  }
  1326  
  1327  type intPtrA int
  1328  
  1329  func (*intPtrA) MarshalJSON() ([]byte, error) {
  1330  	return []byte(`"A"`), nil
  1331  }
  1332  
  1333  type intPtrB int
  1334  
  1335  func (*intPtrB) MarshalText() ([]byte, error) {
  1336  	return []byte("B"), nil
  1337  }
  1338  
  1339  type (
  1340  	structA struct{ I intPtrA }
  1341  	structB struct{ I intPtrB }
  1342  	structC struct{ M Marshaler }
  1343  	structD struct{ M encoding.TextMarshaler }
  1344  )
  1345  
  1346  func TestGithubIssue16(t *testing.T) {
  1347  	// https://github.com/segmentio/encoding/issues/16
  1348  	tests := []struct {
  1349  		value  interface{}
  1350  		output string
  1351  	}{
  1352  		{value: sliceA(nil), output: `"A"`},
  1353  		{value: sliceB(nil), output: `"B"`},
  1354  		{value: mapA(nil), output: `"A"`},
  1355  		{value: mapB(nil), output: `"B"`},
  1356  		{value: intPtrA(1), output: `1`},
  1357  		{value: intPtrB(2), output: `2`},
  1358  		{value: new(intPtrA), output: `"A"`},
  1359  		{value: new(intPtrB), output: `"B"`},
  1360  		{value: (*intPtrA)(nil), output: `null`},
  1361  		{value: (*intPtrB)(nil), output: `null`},
  1362  		{value: structA{I: 1}, output: `{"I":1}`},
  1363  		{value: structB{I: 2}, output: `{"I":2}`},
  1364  		{value: structC{}, output: `{"M":null}`},
  1365  		{value: structD{}, output: `{"M":null}`},
  1366  		{value: &structA{I: 1}, output: `{"I":"A"}`},
  1367  		{value: &structB{I: 2}, output: `{"I":"B"}`},
  1368  		{value: &structC{}, output: `{"M":null}`},
  1369  		{value: &structD{}, output: `{"M":null}`},
  1370  	}
  1371  
  1372  	for _, test := range tests {
  1373  		t.Run(fmt.Sprintf("%T", test.value), func(t *testing.T) {
  1374  			if b, _ := Marshal(test.value); string(b) != test.output {
  1375  				t.Errorf(`%s != %s`, string(b), test.output)
  1376  			}
  1377  		})
  1378  	}
  1379  }
  1380  
  1381  func TestDecoderInputOffset(t *testing.T) {
  1382  	checkOffset := func(o, expected int64) {
  1383  		if o != expected {
  1384  			t.Error("unexpected input offset", o, expected)
  1385  		}
  1386  	}
  1387  
  1388  	b := []byte(`{"userId": "blah"}{"userId": "blah"}
  1389  	{"userId": "blah"}{"num": 0}`)
  1390  	d := NewDecoder(bytes.NewReader(b))
  1391  
  1392  	var expected int64
  1393  	checkOffset(d.InputOffset(), expected)
  1394  
  1395  	var a struct {
  1396  		UserId string `json:"userId"`
  1397  	}
  1398  
  1399  	if err := d.Decode(&a); err != nil {
  1400  		t.Error("unexpected decode error", err)
  1401  	}
  1402  	expected = int64(18)
  1403  	checkOffset(d.InputOffset(), expected)
  1404  
  1405  	if err := d.Decode(&a); err != nil {
  1406  		t.Error("unexpected decode error", err)
  1407  	}
  1408  	expected = int64(38)
  1409  	checkOffset(d.InputOffset(), expected)
  1410  
  1411  	if err := d.Decode(&a); err != nil {
  1412  		t.Error("unexpected decode error", err)
  1413  	}
  1414  	expected = int64(56)
  1415  	checkOffset(d.InputOffset(), expected)
  1416  
  1417  	var z struct {
  1418  		Num int64 `json:"num"`
  1419  	}
  1420  	if err := d.Decode(&z); err != nil {
  1421  		t.Error("unexpected decode error", err)
  1422  	}
  1423  	expected = int64(66)
  1424  	checkOffset(d.InputOffset(), expected)
  1425  }
  1426  
  1427  func TestGithubIssue18(t *testing.T) {
  1428  	// https://github.com/segmentio/encoding/issues/18
  1429  	b := []byte(`{
  1430  	"userId": "blah",
  1431  	}`)
  1432  
  1433  	d := NewDecoder(bytes.NewReader(b))
  1434  
  1435  	var a struct {
  1436  		UserId string `json:"userId"`
  1437  	}
  1438  	switch err := d.Decode(&a).(type) {
  1439  	case *SyntaxError:
  1440  	default:
  1441  		t.Error("expected syntax error but found:", err)
  1442  	}
  1443  
  1444  	for i := 1; i <= 18; i++ { // up to the invalid ',' character
  1445  		d := NewDecoder(bytes.NewReader(b[:i])) // cut somewhere in the middle
  1446  		switch err := d.Decode(&a); err {
  1447  		case io.ErrUnexpectedEOF:
  1448  		default:
  1449  			t.Error("expected 'unexpected EOF' error but found:", err)
  1450  		}
  1451  	}
  1452  }
  1453  
  1454  func TestGithubIssue23(t *testing.T) {
  1455  	t.Run("marshal-1", func(t *testing.T) {
  1456  		type d struct{ S map[string]string }
  1457  
  1458  		b, _ := Marshal(map[string]d{"1": {S: map[string]string{"2": "3"}}})
  1459  		if string(b) != `{"1":{"S":{"2":"3"}}}` {
  1460  			t.Error(string(b))
  1461  		}
  1462  	})
  1463  
  1464  	t.Run("marshal-2", func(t *testing.T) {
  1465  		type testInner struct {
  1466  			InnerMap map[string]string `json:"inner_map"`
  1467  		}
  1468  
  1469  		type testOuter struct {
  1470  			OuterMap map[string]testInner `json:"outer_map"`
  1471  		}
  1472  
  1473  		b, _ := Marshal(testOuter{
  1474  			OuterMap: map[string]testInner{
  1475  				"outer": {
  1476  					InnerMap: map[string]string{"inner": "value"},
  1477  				},
  1478  			},
  1479  		})
  1480  
  1481  		if string(b) != `{"outer_map":{"outer":{"inner_map":{"inner":"value"}}}}` {
  1482  			t.Error(string(b))
  1483  		}
  1484  	})
  1485  
  1486  	t.Run("marshal-3", func(t *testing.T) {
  1487  		type A struct{ A map[string]string }
  1488  		type B struct{ B map[string]A }
  1489  		type C struct{ C map[string]B }
  1490  
  1491  		b, _ := Marshal(C{
  1492  			C: map[string]B{
  1493  				"1": {
  1494  					B: map[string]A{
  1495  						"2": {
  1496  							A: map[string]string{"3": "!"},
  1497  						},
  1498  					},
  1499  				},
  1500  			},
  1501  		})
  1502  
  1503  		if string(b) != `{"C":{"1":{"B":{"2":{"A":{"3":"!"}}}}}}` {
  1504  			t.Error(string(b))
  1505  		}
  1506  	})
  1507  
  1508  	t.Run("unmarshal-1", func(t *testing.T) {
  1509  		var d struct{ S map[string]string }
  1510  
  1511  		if err := Unmarshal([]byte(`{"1":{"S":{"2":"3"}}}`), &d); err != nil {
  1512  			t.Error(err)
  1513  		}
  1514  	})
  1515  }
  1516  
  1517  func TestGithubIssue26(t *testing.T) {
  1518  	type interfaceType interface{}
  1519  
  1520  	var value interfaceType
  1521  	data := []byte(`{}`)
  1522  
  1523  	if err := Unmarshal(data, &value); err != nil {
  1524  		t.Error(err)
  1525  	}
  1526  }
  1527  
  1528  func TestGithubIssue28(t *testing.T) {
  1529  	type A struct {
  1530  		Err error `json:"err"`
  1531  	}
  1532  
  1533  	if b, err := Marshal(&A{Err: errors.New("ABC")}); err != nil {
  1534  		t.Error(err)
  1535  	} else if string(b) != `{"err":{}}` {
  1536  		t.Error(string(b))
  1537  	}
  1538  }
  1539  
  1540  func TestSetTrustRawMessage(t *testing.T) {
  1541  	buf := &bytes.Buffer{}
  1542  	enc := NewEncoder(buf)
  1543  	enc.SetTrustRawMessage(true)
  1544  
  1545  	// "Good" values are encoded in the regular way
  1546  	m := map[string]json.RawMessage{
  1547  		"k": json.RawMessage(`"value"`),
  1548  	}
  1549  	if err := enc.Encode(m); err != nil {
  1550  		t.Error(err)
  1551  	}
  1552  
  1553  	b := buf.Bytes()
  1554  	exp := []byte(`{"k":"value"}`)
  1555  	exp = append(exp, '\n')
  1556  	if bytes.Compare(exp, b) != 0 {
  1557  		t.Error(
  1558  			"unexpected encoding:",
  1559  			"expected", exp,
  1560  			"got", b,
  1561  		)
  1562  	}
  1563  
  1564  	// "Bad" values are encoded without checking and throwing an error
  1565  	buf.Reset()
  1566  	m = map[string]json.RawMessage{
  1567  		"k": json.RawMessage(`bad"value`),
  1568  	}
  1569  	if err := enc.Encode(m); err != nil {
  1570  		t.Error(err)
  1571  	}
  1572  
  1573  	b = buf.Bytes()
  1574  	exp = []byte(`{"k":bad"value}`)
  1575  	exp = append(exp, '\n')
  1576  	if bytes.Compare(exp, b) != 0 {
  1577  		t.Error(
  1578  			"unexpected encoding:",
  1579  			"expected", exp,
  1580  			"got", b,
  1581  		)
  1582  	}
  1583  }