github.com/neilotoole/jsoncolor@v0.6.0/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  
   609  		// simple
   610  
   611  		{
   612  			desc:        "bare object",
   613  			reader:      strings.NewReader("{\"Good\":true}"),
   614  			expectCount: 1,
   615  		},
   616  		{
   617  			desc:        "multiple objects on one line",
   618  			reader:      strings.NewReader("{\"Good\":true}{\"Good\":true}\n"),
   619  			expectCount: 2,
   620  		},
   621  		{
   622  			desc:        "object spanning multiple lines",
   623  			reader:      strings.NewReader("{\n\"Good\":true\n}\n"),
   624  			expectCount: 1,
   625  		},
   626  
   627  		// whitespace handling
   628  
   629  		{
   630  			desc:        "trailing newline",
   631  			reader:      strings.NewReader("{\"Good\":true}\n{\"Good\":true}\n"),
   632  			expectCount: 2,
   633  		},
   634  		{
   635  			desc:        "multiple trailing newlines",
   636  			reader:      strings.NewReader("{\"Good\":true}\n{\"Good\":true}\n\n"),
   637  			expectCount: 2,
   638  		},
   639  		{
   640  			desc:        "blank lines",
   641  			reader:      strings.NewReader("{\"Good\":true}\n\n{\"Good\":true}"),
   642  			expectCount: 2,
   643  		},
   644  		{
   645  			desc:        "no trailing newline",
   646  			reader:      strings.NewReader("{\"Good\":true}\n{\"Good\":true}"),
   647  			expectCount: 2,
   648  		},
   649  		{
   650  			desc:        "leading whitespace",
   651  			reader:      strings.NewReader("  {\"Good\":true}\n\t{\"Good\":true}"),
   652  			expectCount: 2,
   653  		},
   654  
   655  		// multiple reads
   656  
   657  		{
   658  			desc: "one object, multiple reads",
   659  			reader: io.MultiReader(
   660  				strings.NewReader("{"),
   661  				strings.NewReader("\"Good\": true"),
   662  				strings.NewReader("}\n"),
   663  			),
   664  			expectCount: 1,
   665  		},
   666  
   667  		// EOF reads
   668  
   669  		{
   670  			desc:        "one object + EOF",
   671  			reader:      &eofReader{"{\"Good\":true}\n"},
   672  			expectCount: 1,
   673  		},
   674  		{
   675  			desc:        "leading whitespace + EOF",
   676  			reader:      &eofReader{"\n{\"Good\":true}\n"},
   677  			expectCount: 1,
   678  		},
   679  		{
   680  			desc:        "multiple objects + EOF",
   681  			reader:      &eofReader{"{\"Good\":true}\n{\"Good\":true}\n"},
   682  			expectCount: 2,
   683  		},
   684  		{
   685  			desc: "one object + multiple reads + EOF",
   686  			reader: io.MultiReader(
   687  				strings.NewReader("{"),
   688  				strings.NewReader("  \"Good\": true"),
   689  				&eofReader{"}\n"},
   690  			),
   691  			expectCount: 1,
   692  		},
   693  		{
   694  			desc: "multiple objects + multiple reads + EOF",
   695  			reader: io.MultiReader(
   696  				strings.NewReader("{"),
   697  				strings.NewReader("  \"Good\": true}{\"Good\": true}"),
   698  				&eofReader{"\n"},
   699  			),
   700  			expectCount: 2,
   701  		},
   702  
   703  		{
   704  			// the 2nd object should be discarded, as 42 cannot be cast to bool
   705  			desc:        "unmarshal error while decoding",
   706  			reader:      strings.NewReader("{\"Good\":true}\n{\"Good\":42}\n{\"Good\":true}\n"),
   707  			expectCount: 2,
   708  		},
   709  		{
   710  			// the 2nd object should be discarded, as 42 cannot be cast to bool
   711  			desc:        "unmarshal error while decoding last object",
   712  			reader:      strings.NewReader("{\"Good\":true}\n{\"Good\":42}\n"),
   713  			expectCount: 1,
   714  		},
   715  	}
   716  
   717  	type obj struct {
   718  		Good bool
   719  	}
   720  
   721  	for _, test := range tests {
   722  		t.Run(test.desc, func(t *testing.T) {
   723  			d := NewDecoder(test.reader)
   724  			var count int
   725  			var err error
   726  			for {
   727  				var o obj
   728  				err = d.Decode(&o)
   729  				if err != nil {
   730  					if err == io.EOF {
   731  						break
   732  					}
   733  
   734  					switch err.(type) {
   735  					case *SyntaxError, *UnmarshalTypeError, *UnmarshalFieldError:
   736  						t.Log("unmarshal error", err)
   737  						continue
   738  					}
   739  
   740  					t.Error("decode error", err)
   741  					break
   742  				}
   743  				if !o.Good {
   744  					t.Errorf("object was not unmarshaled correctly: %#v", o)
   745  				}
   746  				count++
   747  			}
   748  
   749  			if err != nil && err != io.EOF {
   750  				t.Error(err)
   751  			}
   752  
   753  			if count != test.expectCount {
   754  				t.Errorf("expected %d objects, got %d", test.expectCount, count)
   755  			}
   756  		})
   757  	}
   758  }
   759  
   760  // eofReader is a simple io.Reader that reads its full contents _and_ returns
   761  // and EOF in the first call. Subsequent Read calls only return EOF.
   762  type eofReader struct {
   763  	s string
   764  }
   765  
   766  func (r *eofReader) Read(p []byte) (n int, err error) {
   767  	n = copy(p, r.s)
   768  	r.s = r.s[n:]
   769  	if r.s == "" {
   770  		err = io.EOF
   771  	}
   772  	return
   773  }
   774  
   775  func TestDontMatchCaseIncensitiveStructFields(t *testing.T) {
   776  	b := []byte(`{ "type": "changed" }`)
   777  	s := struct {
   778  		Type string
   779  	}{"unchanged"}
   780  
   781  	if _, err := Parse(b, &s, DontMatchCaseInsensitiveStructFields); err != nil {
   782  		t.Error(err)
   783  	}
   784  
   785  	if s.Type != "unchanged" {
   786  		t.Error("s.Type: expected to be unchanged but found", s.Type)
   787  	}
   788  }
   789  
   790  func TestMarshalFuzzBugs(t *testing.T) {
   791  	tests := []struct {
   792  		value  interface{}
   793  		output string
   794  	}{
   795  		{ // html sequences are escaped even in RawMessage
   796  			value: struct {
   797  				P RawMessage
   798  			}{P: RawMessage(`"<"`)},
   799  			output: "{\"P\":\"\\u003c\"}",
   800  		},
   801  		{ // raw message output is compacted
   802  			value: struct {
   803  				P RawMessage
   804  			}{P: RawMessage(`{"" :{}}`)},
   805  			output: "{\"P\":{\"\":{}}}",
   806  		},
   807  	}
   808  
   809  	for _, test := range tests {
   810  		t.Run("", func(t *testing.T) {
   811  			b, err := Marshal(test.value)
   812  			if err != nil {
   813  				t.Fatal(err)
   814  			}
   815  
   816  			if string(b) != test.output {
   817  				t.Error("values mismatch")
   818  				t.Logf("expected: %#v", test.output)
   819  				t.Logf("found:    %#v", string(b))
   820  			}
   821  		})
   822  	}
   823  }
   824  
   825  func TestUnmarshalFuzzBugs(t *testing.T) {
   826  	tests := []struct {
   827  		input string
   828  		value interface{}
   829  	}{
   830  		{ // non-UTF8 sequences must be converted to the utf8.RuneError character.
   831  			input: "[\"00000\xef\"]",
   832  			value: []interface{}{"00000�"},
   833  		},
   834  		{ // UTF16 surrogate followed by null character
   835  			input: "[\"\\ud800\\u0000\"]",
   836  			value: []interface{}{"�\x00"},
   837  		},
   838  		{ // UTF16 surrogate followed by ascii character
   839  			input: "[\"\\uDF00\\u000e\"]",
   840  			value: []interface{}{"�\x0e"},
   841  		},
   842  		{ // UTF16 surrogate followed by unicode character
   843  			input: "[[\"\\uDF00\\u0800\"]]",
   844  			value: []interface{}{[]interface{}{"�ࠀ"}},
   845  		},
   846  		{ // invalid UTF16 surrogate sequenced followed by a valid UTF16 surrogate sequence
   847  			input: "[\"\\udf00\\udb00\\udf00\"]",
   848  			value: []interface{}{"�\U000d0300"},
   849  		},
   850  		{ // decode single-element slice into []byte field
   851  			input: "{\"f\":[0],\"0\":[0]}",
   852  			value: struct{ F []byte }{F: []byte{0}},
   853  		},
   854  		{ // decode multi-element slice into []byte field
   855  			input: "{\"F\":[3,1,1,1,9,9]}",
   856  			value: struct{ F []byte }{F: []byte{3, 1, 1, 1, 9, 9}},
   857  		},
   858  		{ // decode string with escape sequence into []byte field
   859  			input: "{\"F\":\"0p00\\r\"}",
   860  			value: struct{ F []byte }{F: []byte("ҝ4")},
   861  		},
   862  		{ // decode unicode code points which fold into ascii characters
   863  			input: "{\"ſ\":\"8\"}",
   864  			value: struct {
   865  				S int `json:",string"`
   866  			}{S: 8},
   867  		},
   868  		{ // decode unicode code points which don't fold into ascii characters
   869  			input: "{\"İ\":\"\"}",
   870  			value: struct{ I map[string]string }{I: nil},
   871  		},
   872  		{ // override pointer-to-pointer field clears the inner pointer only
   873  			input: "{\"o\":0,\"o\":null}",
   874  			value: struct{ O **int }{O: new(*int)},
   875  		},
   876  		{ // subsequent occurrences of a map field retain keys previously loaded
   877  			input: "{\"i\":{\"\":null},\"i\":{}}",
   878  			value: struct{ I map[string]string }{I: map[string]string{"": ""}},
   879  		},
   880  		{ // an empty string is an invalid JSON input
   881  			input: "",
   882  		},
   883  		{ // ASCII character below 0x20 are invalid JSON input
   884  			input: "[\"\b\"]",
   885  		},
   886  		{ // random byte before any value
   887  			input: "\xad",
   888  		},
   889  		{ // cloud be the beginning of a false value but not
   890  			input: "f",
   891  			value: false,
   892  		},
   893  		{ // random ASCII character
   894  			input: "}",
   895  			value: []interface{}{},
   896  		},
   897  		{ // random byte after valid JSON, decoded to a nil type
   898  			input: "0\x93",
   899  		},
   900  		{ // random byte after valid JSON, decoded to a int type
   901  			input: "0\x93",
   902  			value: 0,
   903  		},
   904  		{ // random byte after valid JSON, decoded to a slice type
   905  			input: "0\x93",
   906  			value: []interface{}{},
   907  		},
   908  		{ // decode integer into slice
   909  			input: "0",
   910  			value: []interface{}{},
   911  		},
   912  		{ // decode integer with trailing space into slice
   913  			input: "0\t",
   914  			value: []interface{}{},
   915  		},
   916  		{ // decode integer with leading random bytes into slice
   917  			input: "\b0",
   918  			value: []interface{}{},
   919  		},
   920  		{ // decode string into slice followed by number
   921  			input: "\"\"0",
   922  			value: []interface{}{},
   923  		},
   924  		{ // decode what looks like an object followed by a number into a string
   925  			input: "{0",
   926  			value: "",
   927  		},
   928  		{ // decode what looks like an object followed by a number into a map
   929  			input: "{0",
   930  			value: map[string]string{},
   931  		},
   932  		{ // decode string into string with trailing random byte
   933  			input: "\"\"\f",
   934  			value: "",
   935  		},
   936  		{ // decode weird number value into nil
   937  			input: "-00",
   938  		},
   939  		{ // decode an invalid escaped sequence
   940  			input: "\"\\0\"",
   941  			value: "",
   942  		},
   943  		{ // decode what looks like an array followed by a number into a slice
   944  			input: "[9E600",
   945  			value: []interface{}{},
   946  		},
   947  		{ // decode a number which is too large to fit in a float64
   948  			input: "[1e900]",
   949  			value: []interface{}{},
   950  		},
   951  		{ // many nested arrays openings
   952  			input: "[[[[[[",
   953  			value: []interface{}{},
   954  		},
   955  		{ // decode a map with value type mismatch and missing closing character
   956  			input: "{\"\":0",
   957  			value: map[string]string{},
   958  		},
   959  		{ // decode a struct with value type mismatch and missing closing character
   960  			input: "{\"E\":\"\"",
   961  			value: struct{ E uint8 }{},
   962  		},
   963  		{ // decode a map with value type mismatch
   964  			input: "{\"\":0}",
   965  			value: map[string]string{},
   966  		},
   967  		{ // decode number with exponent into integer field
   968  			input: "{\"e\":0e0}",
   969  			value: struct{ E uint8 }{},
   970  		},
   971  		{ // decode invalid integer representation into integer field
   972  			input: "{\"e\":00}",
   973  			value: struct{ E uint8 }{},
   974  		},
   975  		{ // decode unterminated array into byte slice
   976  			input: "{\"F\":[",
   977  			value: struct{ F []byte }{},
   978  		},
   979  		{ // attempt to decode string into in
   980  			input: "{\"S\":\"\"}",
   981  			value: struct {
   982  				S int `json:",string"`
   983  			}{},
   984  		},
   985  		{ // decode object with null key into map
   986  			input: "{null:0}",
   987  			value: map[string]interface{}{},
   988  		},
   989  		{ // decode unquoted integer into struct field with string tag
   990  			input: "{\"S\":0}",
   991  			value: struct {
   992  				S int `json:",string"`
   993  			}{},
   994  		},
   995  		{ // invalid base64 content when decoding string into byte slice
   996  			input: "{\"F\":\"0\"}",
   997  			value: struct{ F []byte }{},
   998  		},
   999  		{ // decode an object with a "null" string as key
  1000  			input: "{\"null\":null}",
  1001  			value: struct {
  1002  				S int `json:",string"`
  1003  			}{},
  1004  		},
  1005  		{ // decode an invalid floating point number representation into an integer field with string tag
  1006  			input: "{\"s\":8e800}",
  1007  			value: struct {
  1008  				S int `json:",string"`
  1009  			}{},
  1010  		},
  1011  		{ // decode a string with leading zeroes into an integer field with string tag
  1012  			input: "{\"S\":\"00\"}",
  1013  			value: struct {
  1014  				S int `json:",string"`
  1015  			}{},
  1016  		},
  1017  		{ // decode a string with invalid leading sign and zeroes into an integer field with string tag
  1018  			input: "{\"S\":\"+00\"}",
  1019  			value: struct {
  1020  				S int `json:",string"`
  1021  			}{},
  1022  		},
  1023  		{ // decode a string with valid leading sign and zeroes into an integer field with string tag
  1024  			input: "{\"S\":\"-00\"}",
  1025  			value: struct {
  1026  				S int `json:",string"`
  1027  			}{},
  1028  		},
  1029  		{ // decode non-ascii string into integer field with string tag
  1030  			input: "{\"ſ\":\"\xbf\"}",
  1031  			value: struct {
  1032  				S int `json:",string"`
  1033  			}{},
  1034  		},
  1035  		{ // decode a valid floating point number representation into an integer field with string tag
  1036  			input: "{\"S\":0.0}",
  1037  			value: struct {
  1038  				S int `json:",string"`
  1039  			}{},
  1040  		},
  1041  		{ // decode string with invalid leading sign to integer field with string tag
  1042  			input: "{\"S\":\"+0\"}",
  1043  			value: struct {
  1044  				S int `json:",string"`
  1045  			}{},
  1046  		},
  1047  		{ // decode string with valid leading sign to integer field with string tag
  1048  			input: "{\"S\":\"-0\"}",
  1049  			value: struct {
  1050  				S int `json:",string"`
  1051  			}{},
  1052  		},
  1053  		{ // decode string with object representation to integer field with string tag
  1054  			input: "{\"s\":{}}",
  1055  			value: struct {
  1056  				S int `json:",string"`
  1057  			}{},
  1058  		},
  1059  		{ // decoding integer with leading zeroes
  1060  			input: "{\"o\":00}",
  1061  			value: struct{ O **int }{},
  1062  		},
  1063  		{ // codeding string with invalid float representation into integer field with string tag
  1064  			input: "{\"s\":\"0.\"}",
  1065  			value: struct {
  1066  				S int `json:",string"`
  1067  			}{},
  1068  		},
  1069  		{ // malformed negative integer in object value
  1070  			input: "{\"N\":-00}",
  1071  			value: struct{ N *int }{},
  1072  		},
  1073  		{ // integer overflow
  1074  			input: "{\"a\":9223372036854775808}",
  1075  			value: struct {
  1076  				A int `json:",omitempty"`
  1077  			}{},
  1078  		},
  1079  		{ // decode string with number followed by random byte into integer field with string tag
  1080  			input: "{\"s\":\"0]\"}",
  1081  			value: struct {
  1082  				S int `json:",string"`
  1083  			}{},
  1084  		},
  1085  		{ // decode object into integer field
  1086  			input: "{\"n\":{}}",
  1087  			value: struct{ N *int }{},
  1088  		},
  1089  		{ // decode negative integer into unsigned type
  1090  			input: "{\"E\":-0}",
  1091  			value: struct{ E uint8 }{},
  1092  		},
  1093  		{ // decode string with number followed by random byte into integer field with string tag
  1094  			input: "{\"s\":\"03�\"}",
  1095  			value: struct {
  1096  				S int `json:",string"`
  1097  			}{},
  1098  		},
  1099  		{ // decode string with leading zeroes into integer field with string tag
  1100  			input: "{\"s\":\"03\"}",
  1101  			value: struct {
  1102  				S int `json:",string"`
  1103  			}{S: 3},
  1104  		},
  1105  		{ // decode string containing what looks like an object into integer field with string tag
  1106  			input: "{\"S\":\"{}\"}",
  1107  			value: struct {
  1108  				S int `json:",string"`
  1109  			}{},
  1110  		},
  1111  		{ // decode an empty string followed by the same field with a null value into a byte slice
  1112  			input: "{\"F\":\"\",\"F\":null}",
  1113  			value: struct{ F []byte }{},
  1114  		},
  1115  		{ // decode string containing a float into an integer field with string tag
  1116  			input: "{\"S\":\"0e0\"}",
  1117  			value: struct {
  1118  				S int `json:",string"`
  1119  			}{},
  1120  		},
  1121  		{ // decode string with negative sign into a an integer field with string tag
  1122  			input: "{\"s\":\"-\"}",
  1123  			value: struct {
  1124  				S int `json:",string"`
  1125  			}{},
  1126  		},
  1127  		{ // decode string with positive sign into a an integer field with string tag
  1128  			input: "{\"s\":\"+\"}",
  1129  			value: struct {
  1130  				S int `json:",string"`
  1131  			}{},
  1132  		},
  1133  		{ // decode an integer into a json unmarshaler
  1134  			input: "{\"q\":0}",
  1135  			value: struct {
  1136  				Q testMarshaller
  1137  			}{},
  1138  		},
  1139  		// This test fails because it appears that the encoding/json package
  1140  		// will decode "q" before "s", so it returns an error about "q" being of
  1141  		// the wrong type while this package will prase object keys in the order
  1142  		// that they appear in the JSON input, so it detects the error from "s"
  1143  		// first.
  1144  		//
  1145  		//{
  1146  		//	input: "{\"s\":0,\"q\":0}",
  1147  		//	value: struct {
  1148  		//		Q testMarshaller
  1149  		//		S int `json:",string"`
  1150  		//	}{},
  1151  		//},
  1152  	}
  1153  
  1154  	for _, test := range tests {
  1155  		t.Run("", func(t *testing.T) {
  1156  			var ptr1 interface{}
  1157  			var ptr2 interface{}
  1158  
  1159  			if test.value != nil {
  1160  				ptr1 = reflect.New(reflect.TypeOf(test.value)).Interface()
  1161  				ptr2 = reflect.New(reflect.TypeOf(test.value)).Interface()
  1162  			}
  1163  
  1164  			err1 := json.Unmarshal([]byte(test.input), ptr1)
  1165  			err2 := Unmarshal([]byte(test.input), ptr2)
  1166  
  1167  			if reflect.TypeOf(err1) != reflect.TypeOf(err2) {
  1168  				t.Error("errors mismatch")
  1169  				t.Logf("expected: %T: %v", err1, err1)
  1170  				t.Logf("found:    %T: %v", err2, err2)
  1171  			} else if err1 == nil && test.value != nil {
  1172  				if value := reflect.ValueOf(ptr2).Elem().Interface(); !reflect.DeepEqual(test.value, value) {
  1173  					t.Error("values mismatch")
  1174  					t.Logf("expected: %#v", test.value)
  1175  					t.Logf("found:    %#v", value)
  1176  				}
  1177  			}
  1178  		})
  1179  	}
  1180  }
  1181  
  1182  func BenchmarkEasyjsonUnmarshalSmallStruct(b *testing.B) {
  1183  	type Hashtag struct {
  1184  		Indices []int  `json:"indices"`
  1185  		Text    string `json:"text"`
  1186  	}
  1187  
  1188  	//easyjson:json
  1189  	type Entities struct {
  1190  		Hashtags     []Hashtag `json:"hashtags"`
  1191  		Urls         []*string `json:"urls"`
  1192  		UserMentions []*string `json:"user_mentions"`
  1193  	}
  1194  
  1195  	var json = []byte(`{"hashtags":[{"indices":[5, 10],"text":"some-text"}],"urls":[],"user_mentions":[]}`)
  1196  
  1197  	for i := 0; i < b.N; i++ {
  1198  		var value Entities
  1199  		if err := Unmarshal(json, &value); err != nil {
  1200  			b.Fatal(err)
  1201  		}
  1202  	}
  1203  }
  1204  
  1205  type testMarshaller struct {
  1206  	v string
  1207  }
  1208  
  1209  func (m *testMarshaller) MarshalJSON() ([]byte, error) {
  1210  	return Marshal(m.v)
  1211  }
  1212  
  1213  func (m *testMarshaller) UnmarshalJSON(data []byte) error {
  1214  	return Unmarshal(data, &m.v)
  1215  }
  1216  
  1217  func TestGithubIssue11(t *testing.T) {
  1218  	// https://github.com/segmentio/encoding/issues/11
  1219  	v := struct{ F float64 }{
  1220  		F: math.NaN(),
  1221  	}
  1222  
  1223  	_, err := Marshal(v)
  1224  	if err == nil {
  1225  		t.Error("no error returned when marshalling NaN value")
  1226  	} else if s := err.Error(); !strings.Contains(s, "NaN") {
  1227  		t.Error("error returned when marshalling NaN value does not mention 'NaN':", s)
  1228  	} else {
  1229  		t.Log(s)
  1230  	}
  1231  }
  1232  
  1233  type Issue13 struct {
  1234  	Stringer fmt.Stringer
  1235  	Field    int `json:"MyInt"`
  1236  }
  1237  
  1238  type S string
  1239  
  1240  func (s S) String() string { return string(s) }
  1241  
  1242  func TestGithubIssue13(t *testing.T) {
  1243  	// https://github.com/segmentio/encoding/issues/13
  1244  	v := Issue13{}
  1245  
  1246  	b, err := Marshal(v)
  1247  	if err != nil {
  1248  		t.Error("unexpected errror:", err)
  1249  	} else {
  1250  		t.Log(string(b))
  1251  	}
  1252  
  1253  	v = Issue13{Stringer: S("")}
  1254  	if err := Unmarshal([]byte(`{"Stringer":null}`), &v); err != nil {
  1255  		t.Error("unexpected error:", err)
  1256  	}
  1257  	if v.Stringer != nil {
  1258  		t.Error("Stringer field was not overwritten")
  1259  	}
  1260  
  1261  	v = Issue13{}
  1262  	if err := Unmarshal([]byte(`{"Stringer":"whatever"}`), &v); err == nil {
  1263  		t.Error("expected error but decoding string value into nil fmt.Stringer but got <nil>")
  1264  	}
  1265  
  1266  	v = Issue13{Stringer: S("")}
  1267  	if err := Unmarshal([]byte(`{"Stringer":"whatever"}`), &v); err == nil {
  1268  		t.Error("expected error but decoding string value into non-pointer fmt.Stringer but got <nil>")
  1269  	}
  1270  
  1271  	s := S("")
  1272  	v = Issue13{Stringer: &s}
  1273  	if err := Unmarshal([]byte(`{"Stringer":"whatever"}`), &v); err != nil {
  1274  		t.Error("unexpected error decoding string value into pointer fmt.Stringer:", err)
  1275  	}
  1276  }
  1277  
  1278  func TestGithubIssue15(t *testing.T) {
  1279  	// https://github.com/segmentio/encoding/issues/15
  1280  	tests := []struct {
  1281  		m interface{}
  1282  		s string
  1283  	}{
  1284  		{
  1285  			m: map[uint]bool{1: true, 123: true, 333: true, 42: true},
  1286  			s: `{"1":true,"123":true,"333":true,"42":true}`,
  1287  		},
  1288  		{
  1289  			m: map[int]bool{-1: true, -123: true, 333: true, 42: true},
  1290  			s: `{"-1":true,"-123":true,"333":true,"42":true}`,
  1291  		},
  1292  	}
  1293  
  1294  	for _, test := range tests {
  1295  		b, _ := Marshal(test.m)
  1296  
  1297  		if string(b) != test.s {
  1298  			t.Error("map with integer keys must be ordered by their string representation, got", string(b))
  1299  		}
  1300  
  1301  	}
  1302  }
  1303  
  1304  type sliceA []byte
  1305  
  1306  func (sliceA) MarshalJSON() ([]byte, error) {
  1307  	return []byte(`"A"`), nil
  1308  }
  1309  
  1310  type sliceB []byte
  1311  
  1312  func (sliceB) MarshalText() ([]byte, error) {
  1313  	return []byte("B"), nil
  1314  }
  1315  
  1316  type mapA map[string]string
  1317  
  1318  func (mapA) MarshalJSON() ([]byte, error) {
  1319  	return []byte(`"A"`), nil
  1320  }
  1321  
  1322  type mapB map[string]string
  1323  
  1324  func (mapB) MarshalText() ([]byte, error) {
  1325  	return []byte("B"), nil
  1326  }
  1327  
  1328  type intPtrA int
  1329  
  1330  func (*intPtrA) MarshalJSON() ([]byte, error) {
  1331  	return []byte(`"A"`), nil
  1332  }
  1333  
  1334  type intPtrB int
  1335  
  1336  func (*intPtrB) MarshalText() ([]byte, error) {
  1337  	return []byte("B"), nil
  1338  }
  1339  
  1340  type structA struct{ I intPtrA }
  1341  type structB struct{ I intPtrB }
  1342  type structC struct{ M Marshaler }
  1343  type structD struct{ M encoding.TextMarshaler }
  1344  
  1345  func TestGithubIssue16(t *testing.T) {
  1346  	// https://github.com/segmentio/encoding/issues/16
  1347  	tests := []struct {
  1348  		value  interface{}
  1349  		output string
  1350  	}{
  1351  		{value: sliceA(nil), output: `"A"`},
  1352  		{value: sliceB(nil), output: `"B"`},
  1353  		{value: mapA(nil), output: `"A"`},
  1354  		{value: mapB(nil), output: `"B"`},
  1355  		{value: intPtrA(1), output: `1`},
  1356  		{value: intPtrB(2), output: `2`},
  1357  		{value: new(intPtrA), output: `"A"`},
  1358  		{value: new(intPtrB), output: `"B"`},
  1359  		{value: (*intPtrA)(nil), output: `null`},
  1360  		{value: (*intPtrB)(nil), output: `null`},
  1361  		{value: structA{I: 1}, output: `{"I":1}`},
  1362  		{value: structB{I: 2}, output: `{"I":2}`},
  1363  		{value: structC{}, output: `{"M":null}`},
  1364  		{value: structD{}, output: `{"M":null}`},
  1365  		{value: &structA{I: 1}, output: `{"I":"A"}`},
  1366  		{value: &structB{I: 2}, output: `{"I":"B"}`},
  1367  		{value: &structC{}, output: `{"M":null}`},
  1368  		{value: &structD{}, output: `{"M":null}`},
  1369  	}
  1370  
  1371  	for _, test := range tests {
  1372  		t.Run(fmt.Sprintf("%T", test.value), func(t *testing.T) {
  1373  			if b, _ := Marshal(test.value); string(b) != test.output {
  1374  				t.Errorf(`%s != %s`, string(b), test.output)
  1375  			}
  1376  		})
  1377  	}
  1378  }
  1379  
  1380  func TestDecoderInputOffset(t *testing.T) {
  1381  	checkOffset := func(o, expected int64) {
  1382  		if o != expected {
  1383  			t.Error("unexpected input offset", o, expected)
  1384  		}
  1385  	}
  1386  
  1387  	b := []byte(`{"userId": "blah"}{"userId": "blah"}
  1388  	{"userId": "blah"}{"num": 0}`)
  1389  	d := NewDecoder(bytes.NewReader(b))
  1390  
  1391  	var expected int64
  1392  	checkOffset(d.InputOffset(), expected)
  1393  
  1394  	var a struct {
  1395  		UserId string `json:"userId"`
  1396  	}
  1397  
  1398  	if err := d.Decode(&a); err != nil {
  1399  		t.Error("unexpected decode error", err)
  1400  	}
  1401  	expected = int64(18)
  1402  	checkOffset(d.InputOffset(), expected)
  1403  
  1404  	if err := d.Decode(&a); err != nil {
  1405  		t.Error("unexpected decode error", err)
  1406  	}
  1407  	expected = int64(38)
  1408  	checkOffset(d.InputOffset(), expected)
  1409  
  1410  	if err := d.Decode(&a); err != nil {
  1411  		t.Error("unexpected decode error", err)
  1412  	}
  1413  	expected = int64(56)
  1414  	checkOffset(d.InputOffset(), expected)
  1415  
  1416  	var z struct {
  1417  		Num int64 `json:"num"`
  1418  	}
  1419  	if err := d.Decode(&z); err != nil {
  1420  		t.Error("unexpected decode error", err)
  1421  	}
  1422  	expected = int64(66)
  1423  	checkOffset(d.InputOffset(), expected)
  1424  }
  1425  
  1426  func TestGithubIssue18(t *testing.T) {
  1427  	// https://github.com/segmentio/encoding/issues/18
  1428  	b := []byte(`{
  1429  	"userId": "blah",
  1430  	}`)
  1431  
  1432  	d := NewDecoder(bytes.NewReader(b))
  1433  
  1434  	var a struct {
  1435  		UserId string `json:"userId"`
  1436  	}
  1437  	switch err := d.Decode(&a).(type) {
  1438  	case *SyntaxError:
  1439  	default:
  1440  		t.Error("expected syntax error but found:", err)
  1441  	}
  1442  
  1443  	for i := 1; i <= 18; i++ { // up to the invalid ',' character
  1444  		d := NewDecoder(bytes.NewReader(b[:i])) // cut somewhere in the middle
  1445  		switch err := d.Decode(&a); err {
  1446  		case io.ErrUnexpectedEOF:
  1447  		default:
  1448  			t.Error("expected 'unexpected EOF' error but found:", err)
  1449  		}
  1450  	}
  1451  }
  1452  
  1453  func TestGithubIssue23(t *testing.T) {
  1454  	t.Run("marshal-1", func(t *testing.T) {
  1455  		type d struct{ S map[string]string }
  1456  
  1457  		b, _ := Marshal(map[string]d{"1": {S: map[string]string{"2": "3"}}})
  1458  		if string(b) != `{"1":{"S":{"2":"3"}}}` {
  1459  			t.Error(string(b))
  1460  		}
  1461  	})
  1462  
  1463  	t.Run("marshal-2", func(t *testing.T) {
  1464  		type testInner struct {
  1465  			InnerMap map[string]string `json:"inner_map"`
  1466  		}
  1467  
  1468  		type testOuter struct {
  1469  			OuterMap map[string]testInner `json:"outer_map"`
  1470  		}
  1471  
  1472  		b, _ := Marshal(testOuter{
  1473  			OuterMap: map[string]testInner{
  1474  				"outer": {
  1475  					InnerMap: map[string]string{"inner": "value"},
  1476  				},
  1477  			},
  1478  		})
  1479  
  1480  		if string(b) != `{"outer_map":{"outer":{"inner_map":{"inner":"value"}}}}` {
  1481  			t.Error(string(b))
  1482  		}
  1483  	})
  1484  
  1485  	t.Run("marshal-3", func(t *testing.T) {
  1486  		type A struct{ A map[string]string }
  1487  		type B struct{ B map[string]A }
  1488  		type C struct{ C map[string]B }
  1489  
  1490  		b, _ := Marshal(C{
  1491  			C: map[string]B{
  1492  				"1": B{
  1493  					B: map[string]A{
  1494  						"2": A{
  1495  							A: map[string]string{"3": "!"},
  1496  						},
  1497  					},
  1498  				},
  1499  			},
  1500  		})
  1501  
  1502  		if string(b) != `{"C":{"1":{"B":{"2":{"A":{"3":"!"}}}}}}` {
  1503  			t.Error(string(b))
  1504  		}
  1505  	})
  1506  
  1507  	t.Run("unmarshal-1", func(t *testing.T) {
  1508  		var d struct{ S map[string]string }
  1509  
  1510  		if err := Unmarshal([]byte(`{"1":{"S":{"2":"3"}}}`), &d); err != nil {
  1511  			t.Error(err)
  1512  		}
  1513  	})
  1514  }
  1515  
  1516  func TestGithubIssue26(t *testing.T) {
  1517  	type interfaceType interface{}
  1518  
  1519  	var value interfaceType
  1520  	var data = []byte(`{}`)
  1521  
  1522  	if err := Unmarshal(data, &value); err != nil {
  1523  		t.Error(err)
  1524  	}
  1525  }
  1526  
  1527  func TestGithubIssue28(t *testing.T) {
  1528  	type A struct {
  1529  		Err error `json:"err"`
  1530  	}
  1531  
  1532  	if b, err := Marshal(&A{Err: errors.New("ABC")}); err != nil {
  1533  		t.Error(err)
  1534  	} else if string(b) != `{"err":{}}` {
  1535  		t.Error(string(b))
  1536  	}
  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  }