]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/json: expand and modernize TestInterfaceSet
authorJoe Tsai <joetsai@digital-static.net>
Mon, 23 Dec 2024 18:35:24 +0000 (10:35 -0800)
committerJoseph Tsai <joetsai@digital-static.net>
Sat, 28 Dec 2024 01:23:24 +0000 (17:23 -0800)
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>

src/encoding/json/decode_test.go

index de09fae50f09d1315acb7960472ff6cc42f033f9..a2b462af775e3ad5c474bcd6af3247793d86abb5 100644 (file)
@@ -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(""), 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(""), 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(""), 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) {