diff options
| author | Joe Tsai <joetsai@digital-static.net> | 2024-12-23 10:35:24 -0800 |
|---|---|---|
| committer | Joseph Tsai <joetsai@digital-static.net> | 2024-12-27 17:23:24 -0800 |
| commit | 2b794ed86cb1b718bc212ee90fecbb8f3b28a744 (patch) | |
| tree | bf7db1dce3814e4ce34106db7e20eea1a4961313 /src/encoding/json/decode_test.go | |
| parent | e3cd55e9d293d519e622e788e902f372dc30338a (diff) | |
| download | go-2b794ed86cb1b718bc212ee90fecbb8f3b28a744.tar.xz | |
encoding/json: expand and modernize TestInterfaceSet
Add more test cases to cover a wider range of edge cases.
Use a generic addr function to take the address of a value.
Even though redudant, explicitly include a cast to the
top-level Go type so that it is more readable what the
expected input and ouput types are.
Change-Id: I3ef68df6f1beb903ae237cd49f3dcb91e5270fe7
Reviewed-on: https://go-review.googlesource.com/c/go/+/638256
Reviewed-by: Daniel Martà <mvdan@mvdan.cc>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src/encoding/json/decode_test.go')
| -rw-r--r-- | src/encoding/json/decode_test.go | 63 |
1 files changed, 45 insertions, 18 deletions
diff --git a/src/encoding/json/decode_test.go b/src/encoding/json/decode_test.go index de09fae50f..a2b462af77 100644 --- a/src/encoding/json/decode_test.go +++ b/src/encoding/json/decode_test.go @@ -1797,19 +1797,12 @@ func TestNullString(t *testing.T) { } } -func intp(x int) *int { - p := new(int) - *p = x - return p -} - -func intpp(x *int) **int { - pp := new(*int) - *pp = x - return pp +func addr[T any](v T) *T { + return &v } func TestInterfaceSet(t *testing.T) { + errUnmarshal := &UnmarshalTypeError{Value: "object", Offset: 6, Type: reflect.TypeFor[int](), Field: "X"} tests := []struct { CaseName pre any @@ -1820,21 +1813,55 @@ func TestInterfaceSet(t *testing.T) { {Name(""), "foo", `2`, 2.0}, {Name(""), "foo", `true`, true}, {Name(""), "foo", `null`, nil}, + {Name(""), map[string]any{}, `true`, true}, + {Name(""), []string{}, `true`, true}, + + {Name(""), any(nil), `null`, any(nil)}, + {Name(""), (*int)(nil), `null`, any(nil)}, + {Name(""), (*int)(addr(0)), `null`, any(nil)}, + {Name(""), (*int)(addr(1)), `null`, any(nil)}, + {Name(""), (**int)(nil), `null`, any(nil)}, + {Name(""), (**int)(addr[*int](nil)), `null`, (**int)(addr[*int](nil))}, + {Name(""), (**int)(addr(addr(1))), `null`, (**int)(addr[*int](nil))}, + {Name(""), (***int)(nil), `null`, any(nil)}, + {Name(""), (***int)(addr[**int](nil)), `null`, (***int)(addr[**int](nil))}, + {Name(""), (***int)(addr(addr[*int](nil))), `null`, (***int)(addr[**int](nil))}, + {Name(""), (***int)(addr(addr(addr(1)))), `null`, (***int)(addr[**int](nil))}, - {Name(""), nil, `null`, nil}, - {Name(""), new(int), `null`, nil}, - {Name(""), (*int)(nil), `null`, nil}, - {Name(""), new(*int), `null`, new(*int)}, - {Name(""), (**int)(nil), `null`, nil}, - {Name(""), intp(1), `null`, nil}, - {Name(""), intpp(nil), `null`, intpp(nil)}, - {Name(""), intpp(intp(1)), `null`, intpp(nil)}, + {Name(""), any(nil), `2`, float64(2)}, + {Name(""), (int)(1), `2`, float64(2)}, + {Name(""), (*int)(nil), `2`, float64(2)}, + {Name(""), (*int)(addr(0)), `2`, (*int)(addr(2))}, + {Name(""), (*int)(addr(1)), `2`, (*int)(addr(2))}, + {Name(""), (**int)(nil), `2`, float64(2)}, + {Name(""), (**int)(addr[*int](nil)), `2`, (**int)(addr(addr(2)))}, + {Name(""), (**int)(addr(addr(1))), `2`, (**int)(addr(addr(2)))}, + {Name(""), (***int)(nil), `2`, float64(2)}, + {Name(""), (***int)(addr[**int](nil)), `2`, (***int)(addr(addr(addr(2))))}, + {Name(""), (***int)(addr(addr[*int](nil))), `2`, (***int)(addr(addr(addr(2))))}, + {Name(""), (***int)(addr(addr(addr(1)))), `2`, (***int)(addr(addr(addr(2))))}, + + {Name(""), any(nil), `{}`, map[string]any{}}, + {Name(""), (int)(1), `{}`, map[string]any{}}, + {Name(""), (*int)(nil), `{}`, map[string]any{}}, + {Name(""), (*int)(addr(0)), `{}`, errUnmarshal}, + {Name(""), (*int)(addr(1)), `{}`, errUnmarshal}, + {Name(""), (**int)(nil), `{}`, map[string]any{}}, + {Name(""), (**int)(addr[*int](nil)), `{}`, errUnmarshal}, + {Name(""), (**int)(addr(addr(1))), `{}`, errUnmarshal}, + {Name(""), (***int)(nil), `{}`, map[string]any{}}, + {Name(""), (***int)(addr[**int](nil)), `{}`, errUnmarshal}, + {Name(""), (***int)(addr(addr[*int](nil))), `{}`, errUnmarshal}, + {Name(""), (***int)(addr(addr(addr(1)))), `{}`, errUnmarshal}, } for _, tt := range tests { t.Run(tt.Name, func(t *testing.T) { b := struct{ X any }{tt.pre} blob := `{"X":` + tt.json + `}` if err := Unmarshal([]byte(blob), &b); err != nil { + if wantErr, _ := tt.post.(error); equalError(err, wantErr) { + return + } t.Fatalf("%s: Unmarshal(%#q) error: %v", tt.Where, blob, err) } if !reflect.DeepEqual(b.X, tt.post) { |
