Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
v2_decode_test.go2946 linesDownload Raw Back to json
1// Copyright 2010 The Go Authors. All rights reserved.2// Use of this source code is governed by a BSD-style3// license that can be found in the LICENSE file.4 5//go:build goexperiment.jsonv26 7package json8 9import (10	"bytes"11	"encoding"12	"errors"13	"fmt"14	"image"15	"io"16	"maps"17	"math"18	"math/big"19	"net"20	"reflect"21	"slices"22	"strconv"23	"strings"24	"testing"25	"time"26)27 28func len64(s string) int64 {29	return int64(len(s))30}31 32type T struct {33	X string34	Y int35	Z int `json:"-"`36}37 38type U struct {39	Alphabet string `json:"alpha"`40}41 42type V struct {43	F1 any44	F2 int3245	F3 Number46	F4 *VOuter47}48 49type VOuter struct {50	V V51}52 53type W struct {54	S SS55}56 57type P struct {58	PP PP59}60 61type PP struct {62	T  T63	Ts []T64}65 66type SS string67 68func (*SS) UnmarshalJSON(data []byte) error {69	return &UnmarshalTypeError{Value: "number", Type: reflect.TypeFor[SS]()}70}71 72type TAlias T73 74func (tt *TAlias) UnmarshalJSON(data []byte) error {75	t := T{}76	if err := Unmarshal(data, &t); err != nil {77		return err78	}79	*tt = TAlias(t)80	return nil81}82 83type TOuter struct {84	T TAlias85}86 87// ifaceNumAsFloat64/ifaceNumAsNumber are used to test unmarshaling with and88// without UseNumber89var ifaceNumAsFloat64 = map[string]any{90	"k1": float64(1),91	"k2": "s",92	"k3": []any{float64(1), float64(2.0), float64(3e-3)},93	"k4": map[string]any{"kk1": "s", "kk2": float64(2)},94}95 96var ifaceNumAsNumber = map[string]any{97	"k1": Number("1"),98	"k2": "s",99	"k3": []any{Number("1"), Number("2.0"), Number("3e-3")},100	"k4": map[string]any{"kk1": "s", "kk2": Number("2")},101}102 103type tx struct {104	x int105}106 107type u8 uint8108 109// A type that can unmarshal itself.110 111type unmarshaler struct {112	T bool113}114 115func (u *unmarshaler) UnmarshalJSON(b []byte) error {116	*u = unmarshaler{true} // All we need to see that UnmarshalJSON is called.117	return nil118}119 120type ustruct struct {121	M unmarshaler122}123 124type unmarshalerText struct {125	A, B string126}127 128// needed for re-marshaling tests129func (u unmarshalerText) MarshalText() ([]byte, error) {130	return []byte(u.A + ":" + u.B), nil131}132 133func (u *unmarshalerText) UnmarshalText(b []byte) error {134	pos := bytes.IndexByte(b, ':')135	if pos == -1 {136		return errors.New("missing separator")137	}138	u.A, u.B = string(b[:pos]), string(b[pos+1:])139	return nil140}141 142var _ encoding.TextUnmarshaler = (*unmarshalerText)(nil)143 144type ustructText struct {145	M unmarshalerText146}147 148// u8marshal is an integer type that can marshal/unmarshal itself.149type u8marshal uint8150 151func (u8 u8marshal) MarshalText() ([]byte, error) {152	return []byte(fmt.Sprintf("u%d", u8)), nil153}154 155var errMissingU8Prefix = errors.New("missing 'u' prefix")156 157func (u8 *u8marshal) UnmarshalText(b []byte) error {158	if !bytes.HasPrefix(b, []byte{'u'}) {159		return errMissingU8Prefix160	}161	n, err := strconv.Atoi(string(b[1:]))162	if err != nil {163		return err164	}165	*u8 = u8marshal(n)166	return nil167}168 169var _ encoding.TextUnmarshaler = (*u8marshal)(nil)170 171var (172	umtrue   = unmarshaler{true}173	umslice  = []unmarshaler{{true}}174	umstruct = ustruct{unmarshaler{true}}175 176	umtrueXY   = unmarshalerText{"x", "y"}177	umsliceXY  = []unmarshalerText{{"x", "y"}}178	umstructXY = ustructText{unmarshalerText{"x", "y"}}179 180	ummapXY = map[unmarshalerText]bool{{"x", "y"}: true}181)182 183// Test data structures for anonymous fields.184 185type Point struct {186	Z int187}188 189type Top struct {190	Level0 int191	Embed0192	*Embed0a193	*Embed0b `json:"e,omitempty"` // treated as named194	Embed0c  `json:"-"`           // ignored195	Loop196	Embed0p // has Point with X, Y, used197	Embed0q // has Point with Z, used198	embed   // contains exported field199}200 201type Embed0 struct {202	Level1a int // overridden by Embed0a's Level1a with json tag203	Level1b int // used because Embed0a's Level1b is renamed204	Level1c int // used because Embed0a's Level1c is ignored205	Level1d int // annihilated by Embed0a's Level1d206	Level1e int `json:"x"` // annihilated by Embed0a.Level1e207}208 209type Embed0a struct {210	Level1a int `json:"Level1a,omitempty"`211	Level1b int `json:"LEVEL1B,omitempty"`212	Level1c int `json:"-"`213	Level1d int // annihilated by Embed0's Level1d214	Level1f int `json:"x"` // annihilated by Embed0's Level1e215}216 217type Embed0b Embed0218 219type Embed0c Embed0220 221type Embed0p struct {222	image.Point223}224 225type Embed0q struct {226	Point227}228 229type embed struct {230	Q int231}232 233type Loop struct {234	Loop1 int `json:",omitempty"`235	Loop2 int `json:",omitempty"`236	*Loop237}238 239// From reflect test:240// The X in S6 and S7 annihilate, but they also block the X in S8.S9.241type S5 struct {242	S6243	S7244	S8245}246 247type S6 struct {248	X int249}250 251type S7 S6252 253type S8 struct {254	S9255}256 257type S9 struct {258	X int259	Y int260}261 262// From reflect test:263// The X in S11.S6 and S12.S6 annihilate, but they also block the X in S13.S8.S9.264type S10 struct {265	S11266	S12267	S13268}269 270type S11 struct {271	S6272}273 274type S12 struct {275	S6276}277 278type S13 struct {279	S8280}281 282type Ambig struct {283	// Given "hello", the first match should win.284	First  int `json:"HELLO"`285	Second int `json:"Hello"`286}287 288type XYZ struct {289	X any290	Y any291	Z any292}293 294type unexportedWithMethods struct{}295 296func (unexportedWithMethods) F() {}297 298type byteWithMarshalJSON byte299 300func (b byteWithMarshalJSON) MarshalJSON() ([]byte, error) {301	return []byte(fmt.Sprintf(`"Z%.2x"`, byte(b))), nil302}303 304func (b *byteWithMarshalJSON) UnmarshalJSON(data []byte) error {305	if len(data) != 5 || data[0] != '"' || data[1] != 'Z' || data[4] != '"' {306		return fmt.Errorf("bad quoted string")307	}308	i, err := strconv.ParseInt(string(data[2:4]), 16, 8)309	if err != nil {310		return fmt.Errorf("bad hex")311	}312	*b = byteWithMarshalJSON(i)313	return nil314}315 316type byteWithPtrMarshalJSON byte317 318func (b *byteWithPtrMarshalJSON) MarshalJSON() ([]byte, error) {319	return byteWithMarshalJSON(*b).MarshalJSON()320}321 322func (b *byteWithPtrMarshalJSON) UnmarshalJSON(data []byte) error {323	return (*byteWithMarshalJSON)(b).UnmarshalJSON(data)324}325 326type byteWithMarshalText byte327 328func (b byteWithMarshalText) MarshalText() ([]byte, error) {329	return []byte(fmt.Sprintf(`Z%.2x`, byte(b))), nil330}331 332func (b *byteWithMarshalText) UnmarshalText(data []byte) error {333	if len(data) != 3 || data[0] != 'Z' {334		return fmt.Errorf("bad quoted string")335	}336	i, err := strconv.ParseInt(string(data[1:3]), 16, 8)337	if err != nil {338		return fmt.Errorf("bad hex")339	}340	*b = byteWithMarshalText(i)341	return nil342}343 344type byteWithPtrMarshalText byte345 346func (b *byteWithPtrMarshalText) MarshalText() ([]byte, error) {347	return byteWithMarshalText(*b).MarshalText()348}349 350func (b *byteWithPtrMarshalText) UnmarshalText(data []byte) error {351	return (*byteWithMarshalText)(b).UnmarshalText(data)352}353 354type intWithMarshalJSON int355 356func (b intWithMarshalJSON) MarshalJSON() ([]byte, error) {357	return []byte(fmt.Sprintf(`"Z%.2x"`, int(b))), nil358}359 360func (b *intWithMarshalJSON) UnmarshalJSON(data []byte) error {361	if len(data) != 5 || data[0] != '"' || data[1] != 'Z' || data[4] != '"' {362		return fmt.Errorf("bad quoted string")363	}364	i, err := strconv.ParseInt(string(data[2:4]), 16, 8)365	if err != nil {366		return fmt.Errorf("bad hex")367	}368	*b = intWithMarshalJSON(i)369	return nil370}371 372type intWithPtrMarshalJSON int373 374func (b *intWithPtrMarshalJSON) MarshalJSON() ([]byte, error) {375	return intWithMarshalJSON(*b).MarshalJSON()376}377 378func (b *intWithPtrMarshalJSON) UnmarshalJSON(data []byte) error {379	return (*intWithMarshalJSON)(b).UnmarshalJSON(data)380}381 382type intWithMarshalText int383 384func (b intWithMarshalText) MarshalText() ([]byte, error) {385	return []byte(fmt.Sprintf(`Z%.2x`, int(b))), nil386}387 388func (b *intWithMarshalText) UnmarshalText(data []byte) error {389	if len(data) != 3 || data[0] != 'Z' {390		return fmt.Errorf("bad quoted string")391	}392	i, err := strconv.ParseInt(string(data[1:3]), 16, 8)393	if err != nil {394		return fmt.Errorf("bad hex")395	}396	*b = intWithMarshalText(i)397	return nil398}399 400type intWithPtrMarshalText int401 402func (b *intWithPtrMarshalText) MarshalText() ([]byte, error) {403	return intWithMarshalText(*b).MarshalText()404}405 406func (b *intWithPtrMarshalText) UnmarshalText(data []byte) error {407	return (*intWithMarshalText)(b).UnmarshalText(data)408}409 410type mapStringToStringData struct {411	Data map[string]string `json:"data"`412}413 414type B struct {415	B bool `json:",string"`416}417 418type DoublePtr struct {419	I **int420	J **int421}422 423type NestedUnamed struct{ F struct{ V int } }424 425var unmarshalTests = []struct {426	CaseName427	in                    string428	ptr                   any // new(type)429	out                   any430	err                   error431	useNumber             bool432	golden                bool433	disallowUnknownFields bool434}{435	// basic types436	{CaseName: Name(""), in: `true`, ptr: new(bool), out: true},437	{CaseName: Name(""), in: `1`, ptr: new(int), out: 1},438	{CaseName: Name(""), in: `1.2`, ptr: new(float64), out: 1.2},439	{CaseName: Name(""), in: `-5`, ptr: new(int16), out: int16(-5)},440	{CaseName: Name(""), in: `2`, ptr: new(Number), out: Number("2"), useNumber: true},441	{CaseName: Name(""), in: `2`, ptr: new(Number), out: Number("2")},442	{CaseName: Name(""), in: `2`, ptr: new(any), out: float64(2.0)},443	{CaseName: Name(""), in: `2`, ptr: new(any), out: Number("2"), useNumber: true},444	{CaseName: Name(""), in: `"a\u1234"`, ptr: new(string), out: "a\u1234"},445	{CaseName: Name(""), in: `"http:\/\/"`, ptr: new(string), out: "http://"},446	{CaseName: Name(""), in: `"g-clef: \uD834\uDD1E"`, ptr: new(string), out: "g-clef: \U0001D11E"},447	{CaseName: Name(""), in: `"invalid: \uD834x\uDD1E"`, ptr: new(string), out: "invalid: \uFFFDx\uFFFD"},448	{CaseName: Name(""), in: "null", ptr: new(any), out: nil},449	{CaseName: Name(""), in: `{"X": [1,2,3], "Y": 4}`, ptr: new(T), out: T{Y: 4}, err: &UnmarshalTypeError{"array", reflect.TypeFor[string](), len64(`{"X": `), "T", "X", nil}},450	{CaseName: Name(""), in: `{"X": 23}`, ptr: new(T), out: T{}, err: &UnmarshalTypeError{"number", reflect.TypeFor[string](), len64(`{"X": `), "T", "X", nil}},451	{CaseName: Name(""), in: `{"x": 1}`, ptr: new(tx), out: tx{}},452	{CaseName: Name(""), in: `{"x": 1}`, ptr: new(tx), out: tx{}},453	{CaseName: Name(""), in: `{"x": 1}`, ptr: new(tx), err: fmt.Errorf("json: unknown field \"x\""), disallowUnknownFields: true},454	{CaseName: Name(""), in: `{"S": 23}`, ptr: new(W), out: W{}, err: &UnmarshalTypeError{"number", reflect.TypeFor[SS](), 0, "", "", nil}},455	{CaseName: Name(""), in: `{"T": {"X": 23}}`, ptr: new(TOuter), out: TOuter{}, err: &UnmarshalTypeError{"number", reflect.TypeFor[string](), len64(`{"X": `), "T", "X", nil}},456	{CaseName: Name(""), in: `{"F1":1,"F2":2,"F3":3}`, ptr: new(V), out: V{F1: float64(1), F2: int32(2), F3: Number("3")}},457	{CaseName: Name(""), in: `{"F1":1,"F2":2,"F3":3}`, ptr: new(V), out: V{F1: Number("1"), F2: int32(2), F3: Number("3")}, useNumber: true},458	{CaseName: Name(""), in: `{"k1":1,"k2":"s","k3":[1,2.0,3e-3],"k4":{"kk1":"s","kk2":2}}`, ptr: new(any), out: ifaceNumAsFloat64},459	{CaseName: Name(""), in: `{"k1":1,"k2":"s","k3":[1,2.0,3e-3],"k4":{"kk1":"s","kk2":2}}`, ptr: new(any), out: ifaceNumAsNumber, useNumber: true},460 461	// raw values with whitespace462	{CaseName: Name(""), in: "\n true ", ptr: new(bool), out: true},463	{CaseName: Name(""), in: "\t 1 ", ptr: new(int), out: 1},464	{CaseName: Name(""), in: "\r 1.2 ", ptr: new(float64), out: 1.2},465	{CaseName: Name(""), in: "\t -5 \n", ptr: new(int16), out: int16(-5)},466	{CaseName: Name(""), in: "\t \"a\\u1234\" \n", ptr: new(string), out: "a\u1234"},467 468	// Z has a "-" tag.469	{CaseName: Name(""), in: `{"Y": 1, "Z": 2}`, ptr: new(T), out: T{Y: 1}},470	{CaseName: Name(""), in: `{"Y": 1, "Z": 2}`, ptr: new(T), out: T{Y: 1}, err: fmt.Errorf("json: unknown field \"Z\""), disallowUnknownFields: true},471 472	{CaseName: Name(""), in: `{"alpha": "abc", "alphabet": "xyz"}`, ptr: new(U), out: U{Alphabet: "abc"}},473	{CaseName: Name(""), in: `{"alpha": "abc", "alphabet": "xyz"}`, ptr: new(U), out: U{Alphabet: "abc"}, err: fmt.Errorf("json: unknown field \"alphabet\""), disallowUnknownFields: true},474	{CaseName: Name(""), in: `{"alpha": "abc"}`, ptr: new(U), out: U{Alphabet: "abc"}},475	{CaseName: Name(""), in: `{"alphabet": "xyz"}`, ptr: new(U), out: U{}},476	{CaseName: Name(""), in: `{"alphabet": "xyz"}`, ptr: new(U), err: fmt.Errorf("json: unknown field \"alphabet\""), disallowUnknownFields: true},477 478	// syntax errors479	{CaseName: Name(""), in: ``, ptr: new(any), err: &SyntaxError{errUnexpectedEnd.Error(), 0}},480	{CaseName: Name(""), in: " \n\r\t", ptr: new(any), err: &SyntaxError{errUnexpectedEnd.Error(), len64(" \n\r\t")}},481	{CaseName: Name(""), in: `[2, 3`, ptr: new(any), err: &SyntaxError{errUnexpectedEnd.Error(), len64(`[2, 3`)}},482	{CaseName: Name(""), in: `{"X": "foo", "Y"}`, err: &SyntaxError{"invalid character '}' after object key", len64(`{"X": "foo", "Y"`)}},483	{CaseName: Name(""), in: `[1, 2, 3+]`, err: &SyntaxError{"invalid character '+' after array element", len64(`[1, 2, 3`)}},484	{CaseName: Name(""), in: `{"X":12x}`, err: &SyntaxError{"invalid character 'x' after object key:value pair", len64(`{"X":12`)}, useNumber: true},485	{CaseName: Name(""), in: `{"F3": -}`, ptr: new(V), err: &SyntaxError{"invalid character '}' in numeric literal", len64(`{"F3": -`)}},486 487	// raw value errors488	{CaseName: Name(""), in: "\x01 42", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", len64(``)}},489	{CaseName: Name(""), in: " 42 \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", len64(` 42 `)}},490	{CaseName: Name(""), in: "\x01 true", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", len64(``)}},491	{CaseName: Name(""), in: " false \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", len64(` false `)}},492	{CaseName: Name(""), in: "\x01 1.2", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", len64(``)}},493	{CaseName: Name(""), in: " 3.4 \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", len64(` 3.4 `)}},494	{CaseName: Name(""), in: "\x01 \"string\"", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", len64(``)}},495	{CaseName: Name(""), in: " \"string\" \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", len64(` "string" `)}},496 497	// array tests498	{CaseName: Name(""), in: `[1, 2, 3]`, ptr: new([3]int), out: [3]int{1, 2, 3}},499	{CaseName: Name(""), in: `[1, 2, 3]`, ptr: new([1]int), out: [1]int{1}},500	{CaseName: Name(""), in: `[1, 2, 3]`, ptr: new([5]int), out: [5]int{1, 2, 3, 0, 0}},501	{CaseName: Name(""), in: `[1, 2, 3]`, ptr: new(MustNotUnmarshalJSON), err: errors.New("MustNotUnmarshalJSON was used")},502 503	// empty array to interface test504	{CaseName: Name(""), in: `[]`, ptr: new([]any), out: []any{}},505	{CaseName: Name(""), in: `null`, ptr: new([]any), out: []any(nil)},506	{CaseName: Name(""), in: `{"T":[]}`, ptr: new(map[string]any), out: map[string]any{"T": []any{}}},507	{CaseName: Name(""), in: `{"T":null}`, ptr: new(map[string]any), out: map[string]any{"T": any(nil)}},508 509	// composite tests510	{CaseName: Name(""), in: allValueIndent, ptr: new(All), out: allValue},511	{CaseName: Name(""), in: allValueCompact, ptr: new(All), out: allValue},512	{CaseName: Name(""), in: allValueIndent, ptr: new(*All), out: &allValue},513	{CaseName: Name(""), in: allValueCompact, ptr: new(*All), out: &allValue},514	{CaseName: Name(""), in: pallValueIndent, ptr: new(All), out: pallValue},515	{CaseName: Name(""), in: pallValueCompact, ptr: new(All), out: pallValue},516	{CaseName: Name(""), in: pallValueIndent, ptr: new(*All), out: &pallValue},517	{CaseName: Name(""), in: pallValueCompact, ptr: new(*All), out: &pallValue},518 519	// unmarshal interface test520	{CaseName: Name(""), in: `{"T":false}`, ptr: new(unmarshaler), out: umtrue}, // use "false" so test will fail if custom unmarshaler is not called521	{CaseName: Name(""), in: `{"T":false}`, ptr: new(*unmarshaler), out: &umtrue},522	{CaseName: Name(""), in: `[{"T":false}]`, ptr: new([]unmarshaler), out: umslice},523	{CaseName: Name(""), in: `[{"T":false}]`, ptr: new(*[]unmarshaler), out: &umslice},524	{CaseName: Name(""), in: `{"M":{"T":"x:y"}}`, ptr: new(ustruct), out: umstruct},525 526	// UnmarshalText interface test527	{CaseName: Name(""), in: `"x:y"`, ptr: new(unmarshalerText), out: umtrueXY},528	{CaseName: Name(""), in: `"x:y"`, ptr: new(*unmarshalerText), out: &umtrueXY},529	{CaseName: Name(""), in: `["x:y"]`, ptr: new([]unmarshalerText), out: umsliceXY},530	{CaseName: Name(""), in: `["x:y"]`, ptr: new(*[]unmarshalerText), out: &umsliceXY},531	{CaseName: Name(""), in: `{"M":"x:y"}`, ptr: new(ustructText), out: umstructXY},532 533	// integer-keyed map test534	{535		CaseName: Name(""),536		in:       `{"-1":"a","0":"b","1":"c"}`,537		ptr:      new(map[int]string),538		out:      map[int]string{-1: "a", 0: "b", 1: "c"},539	},540	{541		CaseName: Name(""),542		in:       `{"0":"a","10":"c","9":"b"}`,543		ptr:      new(map[u8]string),544		out:      map[u8]string{0: "a", 9: "b", 10: "c"},545	},546	{547		CaseName: Name(""),548		in:       `{"-9223372036854775808":"min","9223372036854775807":"max"}`,549		ptr:      new(map[int64]string),550		out:      map[int64]string{math.MinInt64: "min", math.MaxInt64: "max"},551	},552	{553		CaseName: Name(""),554		in:       `{"18446744073709551615":"max"}`,555		ptr:      new(map[uint64]string),556		out:      map[uint64]string{math.MaxUint64: "max"},557	},558	{559		CaseName: Name(""),560		in:       `{"0":false,"10":true}`,561		ptr:      new(map[uintptr]bool),562		out:      map[uintptr]bool{0: false, 10: true},563	},564 565	// Check that MarshalText and UnmarshalText take precedence566	// over default integer handling in map keys.567	{568		CaseName: Name(""),569		in:       `{"u2":4}`,570		ptr:      new(map[u8marshal]int),571		out:      map[u8marshal]int{2: 4},572	},573	{574		CaseName: Name(""),575		in:       `{"2":4}`,576		ptr:      new(map[u8marshal]int),577		out:      map[u8marshal]int{},578		err:      errMissingU8Prefix,579	},580 581	// integer-keyed map errors582	{583		CaseName: Name(""),584		in:       `{"abc":"abc"}`,585		ptr:      new(map[int]string),586		out:      map[int]string{},587		err:      &UnmarshalTypeError{Value: "number abc", Type: reflect.TypeFor[int](), Field: "abc", Offset: len64(`{`)},588	},589	{590		CaseName: Name(""),591		in:       `{"256":"abc"}`,592		ptr:      new(map[uint8]string),593		out:      map[uint8]string{},594		err:      &UnmarshalTypeError{Value: "number 256", Type: reflect.TypeFor[uint8](), Field: "256", Offset: len64(`{`)},595	},596	{597		CaseName: Name(""),598		in:       `{"128":"abc"}`,599		ptr:      new(map[int8]string),600		out:      map[int8]string{},601		err:      &UnmarshalTypeError{Value: "number 128", Type: reflect.TypeFor[int8](), Field: "128", Offset: len64(`{`)},602	},603	{604		CaseName: Name(""),605		in:       `{"-1":"abc"}`,606		ptr:      new(map[uint8]string),607		out:      map[uint8]string{},608		err:      &UnmarshalTypeError{Value: "number -1", Type: reflect.TypeFor[uint8](), Field: "-1", Offset: len64(`{`)},609	},610	{611		CaseName: Name(""),612		in:       `{"F":{"a":2,"3":4}}`,613		ptr:      new(map[string]map[int]int),614		out:      map[string]map[int]int{"F": {3: 4}},615		err:      &UnmarshalTypeError{Value: "number a", Type: reflect.TypeFor[int](), Field: "F.a", Offset: len64(`{"F":{`)},616	},617	{618		CaseName: Name(""),619		in:       `{"F":{"a":2,"3":4}}`,620		ptr:      new(map[string]map[uint]int),621		out:      map[string]map[uint]int{"F": {3: 4}},622		err:      &UnmarshalTypeError{Value: "number a", Type: reflect.TypeFor[uint](), Field: "F.a", Offset: len64(`{"F":{`)},623	},624 625	// Map keys can be encoding.TextUnmarshalers.626	{CaseName: Name(""), in: `{"x:y":true}`, ptr: new(map[unmarshalerText]bool), out: ummapXY},627	// If multiple values for the same key exists, only the most recent value is used.628	{CaseName: Name(""), in: `{"x:y":false,"x:y":true}`, ptr: new(map[unmarshalerText]bool), out: ummapXY},629 630	{631		CaseName: Name(""),632		in: `{633			"Level0": 1,634			"Level1b": 2,635			"Level1c": 3,636			"x": 4,637			"Level1a": 5,638			"LEVEL1B": 6,639			"e": {640				"Level1a": 8,641				"Level1b": 9,642				"Level1c": 10,643				"Level1d": 11,644				"x": 12645			},646			"Loop1": 13,647			"Loop2": 14,648			"X": 15,649			"Y": 16,650			"Z": 17,651			"Q": 18652		}`,653		ptr: new(Top),654		out: Top{655			Level0: 1,656			Embed0: Embed0{657				Level1b: 2,658				Level1c: 3,659			},660			Embed0a: &Embed0a{661				Level1a: 5,662				Level1b: 6,663			},664			Embed0b: &Embed0b{665				Level1a: 8,666				Level1b: 9,667				Level1c: 10,668				Level1d: 11,669				Level1e: 12,670			},671			Loop: Loop{672				Loop1: 13,673				Loop2: 14,674			},675			Embed0p: Embed0p{676				Point: image.Point{X: 15, Y: 16},677			},678			Embed0q: Embed0q{679				Point: Point{Z: 17},680			},681			embed: embed{682				Q: 18,683			},684		},685	},686	{687		CaseName: Name(""),688		in:       `{"hello": 1}`,689		ptr:      new(Ambig),690		out:      Ambig{First: 1},691	},692 693	{694		CaseName: Name(""),695		in:       `{"X": 1,"Y":2}`,696		ptr:      new(S5),697		out:      S5{S8: S8{S9: S9{Y: 2}}},698	},699	{700		CaseName:              Name(""),701		in:                    `{"X": 1,"Y":2}`,702		ptr:                   new(S5),703		out:                   S5{S8: S8{S9{Y: 2}}},704		err:                   fmt.Errorf("json: unknown field \"X\""),705		disallowUnknownFields: true,706	},707	{708		CaseName: Name(""),709		in:       `{"X": 1,"Y":2}`,710		ptr:      new(S10),711		out:      S10{S13: S13{S8: S8{S9: S9{Y: 2}}}},712	},713	{714		CaseName:              Name(""),715		in:                    `{"X": 1,"Y":2}`,716		ptr:                   new(S10),717		out:                   S10{S13: S13{S8{S9{Y: 2}}}},718		err:                   fmt.Errorf("json: unknown field \"X\""),719		disallowUnknownFields: true,720	},721	{722		CaseName: Name(""),723		in:       `{"I": 0, "I": null, "J": null}`,724		ptr:      new(DoublePtr),725		out:      DoublePtr{I: nil, J: nil},726	},727 728	// invalid UTF-8 is coerced to valid UTF-8.729	{730		CaseName: Name(""),731		in:       "\"hello\xffworld\"",732		ptr:      new(string),733		out:      "hello\ufffdworld",734	},735	{736		CaseName: Name(""),737		in:       "\"hello\xc2\xc2world\"",738		ptr:      new(string),739		out:      "hello\ufffd\ufffdworld",740	},741	{742		CaseName: Name(""),743		in:       "\"hello\xc2\xffworld\"",744		ptr:      new(string),745		out:      "hello\ufffd\ufffdworld",746	},747	{748		CaseName: Name(""),749		in:       "\"hello\\ud800world\"",750		ptr:      new(string),751		out:      "hello\ufffdworld",752	},753	{754		CaseName: Name(""),755		in:       "\"hello\\ud800\\ud800world\"",756		ptr:      new(string),757		out:      "hello\ufffd\ufffdworld",758	},759	{760		CaseName: Name(""),761		in:       "\"hello\\ud800\\ud800world\"",762		ptr:      new(string),763		out:      "hello\ufffd\ufffdworld",764	},765	{766		CaseName: Name(""),767		in:       "\"hello\xed\xa0\x80\xed\xb0\x80world\"",768		ptr:      new(string),769		out:      "hello\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdworld",770	},771 772	// Used to be issue 8305, but time.Time implements encoding.TextUnmarshaler so this works now.773	{774		CaseName: Name(""),775		in:       `{"2009-11-10T23:00:00Z": "hello world"}`,776		ptr:      new(map[time.Time]string),777		out:      map[time.Time]string{time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC): "hello world"},778	},779 780	// issue 8305781	{782		CaseName: Name(""),783		in:       `{"2009-11-10T23:00:00Z": "hello world"}`,784		ptr:      new(map[Point]string),785		out:      map[Point]string{},786		err:      &UnmarshalTypeError{Value: "string", Type: reflect.TypeFor[Point](), Field: `2009-11-10T23:00:00Z`, Offset: len64(`{`)},787	},788	{789		CaseName: Name(""),790		in:       `{"asdf": "hello world"}`,791		ptr:      new(map[unmarshaler]string),792		out:      map[unmarshaler]string{},793		err:      &UnmarshalTypeError{Value: "string", Type: reflect.TypeFor[unmarshaler](), Field: "asdf", Offset: len64(`{`)},794	},795 796	// related to issue 13783.797	// Go 1.7 changed marshaling a slice of typed byte to use the methods on the byte type,798	// similar to marshaling a slice of typed int.799	// These tests check that, assuming the byte type also has valid decoding methods,800	// either the old base64 string encoding or the new per-element encoding can be801	// successfully unmarshaled. The custom unmarshalers were accessible in earlier802	// versions of Go, even though the custom marshaler was not.803	{804		CaseName: Name(""),805		in:       `"AQID"`,806		ptr:      new([]byteWithMarshalJSON),807		out:      []byteWithMarshalJSON{1, 2, 3},808	},809	{810		CaseName: Name(""),811		in:       `["Z01","Z02","Z03"]`,812		ptr:      new([]byteWithMarshalJSON),813		out:      []byteWithMarshalJSON{1, 2, 3},814		golden:   true,815	},816	{817		CaseName: Name(""),818		in:       `"AQID"`,819		ptr:      new([]byteWithMarshalText),820		out:      []byteWithMarshalText{1, 2, 3},821	},822	{823		CaseName: Name(""),824		in:       `["Z01","Z02","Z03"]`,825		ptr:      new([]byteWithMarshalText),826		out:      []byteWithMarshalText{1, 2, 3},827		golden:   true,828	},829	{830		CaseName: Name(""),831		in:       `"AQID"`,832		ptr:      new([]byteWithPtrMarshalJSON),833		out:      []byteWithPtrMarshalJSON{1, 2, 3},834	},835	{836		CaseName: Name(""),837		in:       `["Z01","Z02","Z03"]`,838		ptr:      new([]byteWithPtrMarshalJSON),839		out:      []byteWithPtrMarshalJSON{1, 2, 3},840		golden:   true,841	},842	{843		CaseName: Name(""),844		in:       `"AQID"`,845		ptr:      new([]byteWithPtrMarshalText),846		out:      []byteWithPtrMarshalText{1, 2, 3},847	},848	{849		CaseName: Name(""),850		in:       `["Z01","Z02","Z03"]`,851		ptr:      new([]byteWithPtrMarshalText),852		out:      []byteWithPtrMarshalText{1, 2, 3},853		golden:   true,854	},855 856	// ints work with the marshaler but not the base64 []byte case857	{858		CaseName: Name(""),859		in:       `["Z01","Z02","Z03"]`,860		ptr:      new([]intWithMarshalJSON),861		out:      []intWithMarshalJSON{1, 2, 3},862		golden:   true,863	},864	{865		CaseName: Name(""),866		in:       `["Z01","Z02","Z03"]`,867		ptr:      new([]intWithMarshalText),868		out:      []intWithMarshalText{1, 2, 3},869		golden:   true,870	},871	{872		CaseName: Name(""),873		in:       `["Z01","Z02","Z03"]`,874		ptr:      new([]intWithPtrMarshalJSON),875		out:      []intWithPtrMarshalJSON{1, 2, 3},876		golden:   true,877	},878	{879		CaseName: Name(""),880		in:       `["Z01","Z02","Z03"]`,881		ptr:      new([]intWithPtrMarshalText),882		out:      []intWithPtrMarshalText{1, 2, 3},883		golden:   true,884	},885 886	{CaseName: Name(""), in: `0.000001`, ptr: new(float64), out: 0.000001, golden: true},887	{CaseName: Name(""), in: `1e-7`, ptr: new(float64), out: 1e-7, golden: true},888	{CaseName: Name(""), in: `100000000000000000000`, ptr: new(float64), out: 100000000000000000000.0, golden: true},889	{CaseName: Name(""), in: `1e+21`, ptr: new(float64), out: 1e21, golden: true},890	{CaseName: Name(""), in: `-0.000001`, ptr: new(float64), out: -0.000001, golden: true},891	{CaseName: Name(""), in: `-1e-7`, ptr: new(float64), out: -1e-7, golden: true},892	{CaseName: Name(""), in: `-100000000000000000000`, ptr: new(float64), out: -100000000000000000000.0, golden: true},893	{CaseName: Name(""), in: `-1e+21`, ptr: new(float64), out: -1e21, golden: true},894	{CaseName: Name(""), in: `999999999999999900000`, ptr: new(float64), out: 999999999999999900000.0, golden: true},895	{CaseName: Name(""), in: `9007199254740992`, ptr: new(float64), out: 9007199254740992.0, golden: true},896	{CaseName: Name(""), in: `9007199254740993`, ptr: new(float64), out: 9007199254740992.0, golden: false},897 898	{899		CaseName: Name(""),900		in:       `{"V": {"F2": "hello"}}`,901		ptr:      new(VOuter),902		err: &UnmarshalTypeError{903			Value:  "string",904			Struct: "VOuter",905			Field:  "V.F2",906			Type:   reflect.TypeFor[int32](),907			Offset: len64(`{"V": {"F2": `),908		},909	},910	{911		CaseName: Name(""),912		in:       `{"V": {"F4": {}, "F2": "hello"}}`,913		ptr:      new(VOuter),914		out:      VOuter{V: V{F4: &VOuter{}}},915		err: &UnmarshalTypeError{916			Value:  "string",917			Struct: "VOuter",918			Field:  "V.F2",919			Type:   reflect.TypeFor[int32](),920			Offset: len64(`{"V": {"F4": {}, "F2": `),921		},922	},923 924	{925		CaseName: Name(""),926		in:       `{"Level1a": "hello"}`,927		ptr:      new(Top),928		out:      Top{Embed0a: &Embed0a{}},929		err: &UnmarshalTypeError{930			Value:  "string",931			Struct: "Top",932			Field:  "Level1a",933			Type:   reflect.TypeFor[int](),934			Offset: len64(`{"Level1a": `),935		},936	},937 938	// issue 15146.939	// invalid inputs in wrongStringTests below.940	{CaseName: Name(""), in: `{"B":"true"}`, ptr: new(B), out: B{true}, golden: true},941	{CaseName: Name(""), in: `{"B":"false"}`, ptr: new(B), out: B{false}, golden: true},942	{CaseName: Name(""), in: `{"B": "maybe"}`, ptr: new(B), err: &UnmarshalTypeError{Value: `string "maybe"`, Type: reflect.TypeFor[bool](), Struct: "B", Field: "B", Offset: len64(`{"B": `), Err: strconv.ErrSyntax}},943	{CaseName: Name(""), in: `{"B": "tru"}`, ptr: new(B), err: &UnmarshalTypeError{Value: `string "tru"`, Type: reflect.TypeFor[bool](), Struct: "B", Field: "B", Offset: len64(`{"B": `), Err: strconv.ErrSyntax}},944	{CaseName: Name(""), in: `{"B": "False"}`, ptr: new(B), err: &UnmarshalTypeError{Value: `string "False"`, Type: reflect.TypeFor[bool](), Struct: "B", Field: "B", Offset: len64(`{"B": `), Err: strconv.ErrSyntax}},945	{CaseName: Name(""), in: `{"B": "null"}`, ptr: new(B), out: B{false}},946	{CaseName: Name(""), in: `{"B": "nul"}`, ptr: new(B), err: &UnmarshalTypeError{Value: `string "nul"`, Type: reflect.TypeFor[bool](), Struct: "B", Field: "B", Offset: len64(`{"B": `), Err: strconv.ErrSyntax}},947	{CaseName: Name(""), in: `{"B": [2, 3]}`, ptr: new(B), err: &UnmarshalTypeError{Value: "array", Type: reflect.TypeFor[bool](), Struct: "B", Field: "B", Offset: len64(`{"B": `)}},948 949	// additional tests for disallowUnknownFields950	{951		CaseName: Name(""),952		in: `{953			"Level0": 1,954			"Level1b": 2,955			"Level1c": 3,956			"x": 4,957			"Level1a": 5,958			"LEVEL1B": 6,959			"e": {960				"Level1a": 8,961				"Level1b": 9,962				"Level1c": 10,963				"Level1d": 11,964				"x": 12965			},966			"Loop1": 13,967			"Loop2": 14,968			"X": 15,969			"Y": 16,970			"Z": 17,971			"Q": 18,972			"extra": true973		}`,974		ptr: new(Top),975		out: Top{976			Level0: 1,977			Embed0: Embed0{978				Level1b: 2,979				Level1c: 3,980			},981			Embed0a: &Embed0a{Level1a: 5, Level1b: 6},982			Embed0b: &Embed0b{Level1a: 8, Level1b: 9, Level1c: 10, Level1d: 11, Level1e: 12},983			Loop: Loop{984				Loop1: 13,985				Loop2: 14,986				Loop:  nil,987			},988			Embed0p: Embed0p{989				Point: image.Point{990					X: 15,991					Y: 16,992				},993			},994			Embed0q: Embed0q{Point: Point{Z: 17}},995			embed:   embed{Q: 18},996		},997		err:                   fmt.Errorf("json: unknown field \"extra\""),998		disallowUnknownFields: true,999	},1000	{1001		CaseName: Name(""),1002		in: `{1003			"Level0": 1,1004			"Level1b": 2,1005			"Level1c": 3,1006			"x": 4,1007			"Level1a": 5,1008			"LEVEL1B": 6,1009			"e": {1010				"Level1a": 8,1011				"Level1b": 9,1012				"Level1c": 10,1013				"Level1d": 11,1014				"x": 12,1015				"extra": null1016			},1017			"Loop1": 13,1018			"Loop2": 14,1019			"X": 15,1020			"Y": 16,1021			"Z": 17,1022			"Q": 181023		}`,1024		ptr: new(Top),1025		out: Top{1026			Level0: 1,1027			Embed0: Embed0{1028				Level1b: 2,1029				Level1c: 3,1030			},1031			Embed0a: &Embed0a{Level1a: 5, Level1b: 6},1032			Embed0b: &Embed0b{Level1a: 8, Level1b: 9, Level1c: 10, Level1d: 11, Level1e: 12},1033			Loop: Loop{1034				Loop1: 13,1035				Loop2: 14,1036				Loop:  nil,1037			},1038			Embed0p: Embed0p{1039				Point: image.Point{1040					X: 15,1041					Y: 16,1042				},1043			},1044			Embed0q: Embed0q{Point: Point{Z: 17}},1045			embed:   embed{Q: 18},1046		},1047		err:                   fmt.Errorf("json: unknown field \"extra\""),1048		disallowUnknownFields: true,1049	},1050	// issue 264441051	// UnmarshalTypeError without field & struct values1052	{1053		CaseName: Name(""),1054		in:       `{"data":{"test1": "bob", "test2": 123}}`,1055		ptr:      new(mapStringToStringData),1056		out:      mapStringToStringData{map[string]string{"test1": "bob", "test2": ""}},1057		err:      &UnmarshalTypeError{Value: "number", Type: reflect.TypeFor[string](), Offset: len64(`{"data":{"test1": "bob", "test2": `), Struct: "mapStringToStringData", Field: "data.test2"},1058	},1059	{1060		CaseName: Name(""),1061		in:       `{"data":{"test1": 123, "test2": "bob"}}`,1062		ptr:      new(mapStringToStringData),1063		out:      mapStringToStringData{Data: map[string]string{"test1": "", "test2": "bob"}},1064		err:      &UnmarshalTypeError{Value: "number", Type: reflect.TypeFor[string](), Offset: len64(`{"data":{"test1": `), Struct: "mapStringToStringData", Field: "data.test1"},1065	},1066 1067	// trying to decode JSON arrays or objects via TextUnmarshaler1068	{1069		CaseName: Name(""),1070		in:       `[1, 2, 3]`,1071		ptr:      new(MustNotUnmarshalText),1072		err:      &UnmarshalTypeError{Value: "array", Type: reflect.TypeFor[MustNotUnmarshalText](), Err: errors.New("JSON value must be string type")},1073	},1074	{1075		CaseName: Name(""),1076		in:       `{"foo": "bar"}`,1077		ptr:      new(MustNotUnmarshalText),1078		err:      &UnmarshalTypeError{Value: "object", Type: reflect.TypeFor[MustNotUnmarshalText](), Err: errors.New("JSON value must be string type")},1079	},1080	// #223691081	{1082		CaseName: Name(""),1083		in:       `{"PP": {"T": {"Y": "bad-type"}}}`,1084		ptr:      new(P),1085		err: &UnmarshalTypeError{1086			Value:  "string",1087			Struct: "P",1088			Field:  "PP.T.Y",1089			Type:   reflect.TypeFor[int](),1090			Offset: len64(`{"PP": {"T": {"Y": `),1091		},1092	},1093	{1094		CaseName: Name(""),1095		in:       `{"Ts": [{"Y": 1}, {"Y": 2}, {"Y": "bad-type"}]}`,1096		ptr:      new(PP),1097		out:      PP{Ts: []T{{Y: 1}, {Y: 2}, {Y: 0}}},1098		err: &UnmarshalTypeError{1099			Value:  "string",1100			Struct: "PP",1101			Field:  "Ts.2.Y",1102			Type:   reflect.TypeFor[int](),1103			Offset: len64(`{"Ts": [{"Y": 1}, {"Y": 2}, {"Y": `),1104		},1105	},1106	// #147021107	{1108		CaseName: Name(""),1109		in:       `invalid`,1110		ptr:      new(Number),1111		err: &SyntaxError{1112			msg:    "invalid character 'i' looking for beginning of value",1113			Offset: len64(``),1114		},1115	},1116	{1117		CaseName: Name(""),1118		in:       `"invalid"`,1119		ptr:      new(Number),1120		err:      &UnmarshalTypeError{Value: `string "invalid"`, Type: reflect.TypeFor[Number](), Err: strconv.ErrSyntax},1121	},1122	{1123		CaseName: Name(""),1124		in:       `{"A":"invalid"}`,1125		ptr:      new(struct{ A Number }),1126		err:      &UnmarshalTypeError{Value: `string "invalid"`, Type: reflect.TypeFor[Number](), Err: strconv.ErrSyntax},1127	},1128	{1129		CaseName: Name(""),1130		in:       `{"A":"invalid"}`,1131		ptr: new(struct {1132			A Number `json:",string"`1133		}),1134		err: &UnmarshalTypeError{Value: `string "invalid"`, Type: reflect.TypeFor[Number](), Err: strconv.ErrSyntax},1135	},1136	{1137		CaseName: Name(""),1138		in:       `{"A":"invalid"}`,1139		ptr:      new(map[string]Number),1140		out:      map[string]Number{"A": ""},1141		err:      &UnmarshalTypeError{Value: `string "invalid"`, Type: reflect.TypeFor[Number](), Err: strconv.ErrSyntax},1142	},1143 1144	{1145		CaseName: Name(""),1146		in:       `5`,1147		ptr:      new(Number),1148		out:      Number("5"),1149	},1150	{1151		CaseName: Name(""),1152		in:       `"5"`,1153		ptr:      new(Number),1154		out:      Number("5"),1155	},1156	{1157		CaseName: Name(""),1158		in:       `{"N":5}`,1159		ptr:      new(struct{ N Number }),1160		out:      struct{ N Number }{"5"},1161	},1162	{1163		CaseName: Name(""),1164		in:       `{"N":"5"}`,1165		ptr:      new(struct{ N Number }),1166		out:      struct{ N Number }{"5"},1167	},1168	{1169		CaseName: Name(""),1170		in:       `{"N":5}`,1171		ptr: new(struct {1172			N Number `json:",string"`1173		}),1174		err: &UnmarshalTypeError{Value: "number", Type: reflect.TypeFor[Number]()},1175	},1176	{1177		CaseName: Name(""),1178		in:       `{"N":"5"}`,1179		ptr: new(struct {1180			N Number `json:",string"`1181		}),1182		out: struct {1183			N Number `json:",string"`1184		}{"5"},1185	},1186 1187	// Verify that syntactic errors are immediately fatal,1188	// while semantic errors are lazily reported1189	// (i.e., allow processing to continue).1190	{1191		CaseName: Name(""),1192		in:       `[1,2,true,4,5}`,1193		ptr:      new([]int),1194		err:      &SyntaxError{msg: "invalid character '}' after array element", Offset: len64(`[1,2,true,4,5`)},1195	},1196	{1197		CaseName: Name(""),1198		in:       `[1,2,true,4,5]`,1199		ptr:      new([]int),1200		out:      []int{1, 2, 0, 4, 5},

Showing the first 1,200 of 2946 lines. Download the file for the rest.

codekingpro/portable-devtools · Team Ai