mirror of https://github.com/goccy/go-json.git
Compare commits
5 Commits
c15276a0e2
...
42a5eaf686
Author | SHA1 | Date |
---|---|---|
Fabio Nascimento Brandão | 42a5eaf686 | |
Masaaki Goshima | 3e9769d637 | |
Andrey Grazhdankov | 65c8b28ca1 | |
Fabio Nascimento Brandão | b29e1ad08b | |
fbrandao | 4bce081dac |
|
@ -12,7 +12,7 @@ jobs:
|
||||||
- name: checkout
|
- name: checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
- name: build
|
- name: build
|
||||||
run: docker-compose run go-json
|
run: docker compose run go-json
|
||||||
|
|
||||||
test:
|
test:
|
||||||
name: Test
|
name: Test
|
||||||
|
|
|
@ -4057,3 +4057,28 @@ func TestIssue429(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIssue464(t *testing.T) {
|
||||||
|
type testStruct struct {
|
||||||
|
Name string
|
||||||
|
Value int
|
||||||
|
Description string
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonValue := []byte("{\"Name\":\"Test Name\",\"Value\":\"incorrect\",\"Description\":\"Test Description\"}")
|
||||||
|
|
||||||
|
jsonData := testStruct{}
|
||||||
|
err := stdjson.Unmarshal(jsonValue, &jsonData)
|
||||||
|
assertIsType(t, "Incorrect error type stdjson", &stdjson.UnmarshalTypeError{}, err)
|
||||||
|
|
||||||
|
gojsonData := testStruct{}
|
||||||
|
err = json.Unmarshal(jsonValue, &gojsonData)
|
||||||
|
assertIsType(t, "Incorrect error type go-json", &json.UnmarshalTypeError{}, err)
|
||||||
|
|
||||||
|
assertEq(t, "Incorrect name stdjson", "Test Name", jsonData.Name)
|
||||||
|
assertEq(t, "Incorrect name go-json", "Test Name", gojsonData.Name)
|
||||||
|
assertEq(t, "Incorrect value stdjson", 0, jsonData.Value)
|
||||||
|
assertEq(t, "Incorrect value go-json", 0, gojsonData.Value)
|
||||||
|
assertEq(t, "Incorrect description stdjson", "Test Description", jsonData.Description)
|
||||||
|
assertEq(t, "Incorrect description go-json", "Test Description", gojsonData.Description)
|
||||||
|
}
|
||||||
|
|
|
@ -426,6 +426,11 @@ func Test_Marshal(t *testing.T) {
|
||||||
assertErr(t, err)
|
assertErr(t, err)
|
||||||
assertEq(t, "[]interface{}", `[1,2.1,"hello"]`, string(bytes))
|
assertEq(t, "[]interface{}", `[1,2.1,"hello"]`, string(bytes))
|
||||||
})
|
})
|
||||||
|
t.Run("[]*time.Time", func(t *testing.T) {
|
||||||
|
bytes, err := json.Marshal([]*time.Time{nil})
|
||||||
|
assertErr(t, err)
|
||||||
|
assertEq(t, "[]*time.Time", `[null]`, string(bytes))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("array", func(t *testing.T) {
|
t.Run("array", func(t *testing.T) {
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package json_test
|
package json_test
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
func assertErr(t *testing.T, err error) {
|
func assertErr(t *testing.T, err error) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
@ -22,3 +25,12 @@ func assertNeq(t *testing.T, msg string, exp interface{}, act interface{}) {
|
||||||
t.Fatalf("failed to test for %s. expected value is not [%v] but got same value", msg, act)
|
t.Fatalf("failed to test for %s. expected value is not [%v] but got same value", msg, act)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func assertIsType(t *testing.T, msg string, exp interface{}, act interface{}) {
|
||||||
|
t.Helper()
|
||||||
|
expType := reflect.TypeOf(exp)
|
||||||
|
actType := reflect.TypeOf(act)
|
||||||
|
if expType != actType {
|
||||||
|
t.Fatalf("failed to test for %s. exp[%v] bug act=[%v]", msg, expType, actType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -778,6 +778,7 @@ func (d *structDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsaf
|
||||||
if firstWin {
|
if firstWin {
|
||||||
seenFields = make(map[int]struct{}, d.fieldUniqueNameNum)
|
seenFields = make(map[int]struct{}, d.fieldUniqueNameNum)
|
||||||
}
|
}
|
||||||
|
var lastTypeMismatchError error
|
||||||
for {
|
for {
|
||||||
c, field, err := d.keyDecoder(d, buf, cursor)
|
c, field, err := d.keyDecoder(d, buf, cursor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -805,7 +806,15 @@ func (d *structDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsaf
|
||||||
} else {
|
} else {
|
||||||
c, err := field.dec.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+field.offset))
|
c, err := field.dec.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+field.offset))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
if _, ok := err.(*errors.UnmarshalTypeError); ok {
|
||||||
|
lastTypeMismatchError = err
|
||||||
|
c, err = skipValue(buf, cursor, depth)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cursor = c
|
cursor = c
|
||||||
seenFieldNum++
|
seenFieldNum++
|
||||||
|
@ -817,7 +826,15 @@ func (d *structDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsaf
|
||||||
} else {
|
} else {
|
||||||
c, err := field.dec.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+field.offset))
|
c, err := field.dec.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+field.offset))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
if _, ok := err.(*errors.UnmarshalTypeError); ok {
|
||||||
|
lastTypeMismatchError = err
|
||||||
|
c, err = skipValue(buf, cursor, depth)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cursor = c
|
cursor = c
|
||||||
}
|
}
|
||||||
|
@ -831,6 +848,9 @@ func (d *structDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsaf
|
||||||
cursor = skipWhiteSpace(buf, cursor)
|
cursor = skipWhiteSpace(buf, cursor)
|
||||||
if char(b, cursor) == '}' {
|
if char(b, cursor) == '}' {
|
||||||
cursor++
|
cursor++
|
||||||
|
if lastTypeMismatchError != nil {
|
||||||
|
return 0, lastTypeMismatchError
|
||||||
|
}
|
||||||
return cursor, nil
|
return cursor, nil
|
||||||
}
|
}
|
||||||
if char(b, cursor) != ',' {
|
if char(b, cursor) != ',' {
|
||||||
|
|
|
@ -406,6 +406,11 @@ func AppendMarshalJSON(ctx *RuntimeContext, code *Opcode, b []byte, v interface{
|
||||||
rv = newV
|
rv = newV
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if rv.Kind() == reflect.Ptr && rv.IsNil() {
|
||||||
|
return AppendNull(ctx, b), nil
|
||||||
|
}
|
||||||
|
|
||||||
v = rv.Interface()
|
v = rv.Interface()
|
||||||
var bb []byte
|
var bb []byte
|
||||||
if (code.Flags & MarshalerContextFlags) != 0 {
|
if (code.Flags & MarshalerContextFlags) != 0 {
|
||||||
|
|
Loading…
Reference in New Issue