mirror of https://github.com/goccy/go-json.git
Add test cases
This commit is contained in:
parent
7dd33b9060
commit
e0b5ba8df4
|
@ -43,13 +43,32 @@ func Compact(buf *bytes.Buffer, src []byte, escape bool) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func compact(dst, src []byte, escape bool) ([]byte, error) {
|
func compact(dst, src []byte, escape bool) ([]byte, error) {
|
||||||
buf, _, err := compactValue(dst, src, 0, escape)
|
buf, cursor, err := compactValue(dst, src, 0, escape)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if err := validateEndBuf(src, cursor); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return buf, nil
|
return buf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func validateEndBuf(src []byte, cursor int64) error {
|
||||||
|
for {
|
||||||
|
switch src[cursor] {
|
||||||
|
case ' ', '\t', '\n', '\r':
|
||||||
|
cursor++
|
||||||
|
continue
|
||||||
|
case nul:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return errors.ErrSyntax(
|
||||||
|
fmt.Sprintf("invalid character '%c' after top-level value", src[cursor]),
|
||||||
|
cursor+1,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func skipWhiteSpace(buf []byte, cursor int64) int64 {
|
func skipWhiteSpace(buf []byte, cursor int64) int64 {
|
||||||
LOOP:
|
LOOP:
|
||||||
if isWhiteSpace[buf[cursor]] {
|
if isWhiteSpace[buf[cursor]] {
|
||||||
|
@ -90,12 +109,9 @@ func compactValue(dst, src []byte, cursor int64, escape bool) ([]byte, int64, er
|
||||||
}
|
}
|
||||||
|
|
||||||
func compactObject(dst, src []byte, cursor int64, escape bool) ([]byte, int64, error) {
|
func compactObject(dst, src []byte, cursor int64, escape bool) ([]byte, int64, error) {
|
||||||
switch src[cursor] {
|
if src[cursor] == '{' {
|
||||||
case 'n':
|
|
||||||
return compactNull(dst, src, cursor)
|
|
||||||
case '{':
|
|
||||||
dst = append(dst, '{')
|
dst = append(dst, '{')
|
||||||
default:
|
} else {
|
||||||
return nil, 0, errors.ErrExpected("expected { character for object value", cursor)
|
return nil, 0, errors.ErrExpected("expected { character for object value", cursor)
|
||||||
}
|
}
|
||||||
cursor = skipWhiteSpace(src, cursor+1)
|
cursor = skipWhiteSpace(src, cursor+1)
|
||||||
|
@ -135,12 +151,9 @@ func compactObject(dst, src []byte, cursor int64, escape bool) ([]byte, int64, e
|
||||||
}
|
}
|
||||||
|
|
||||||
func compactArray(dst, src []byte, cursor int64, escape bool) ([]byte, int64, error) {
|
func compactArray(dst, src []byte, cursor int64, escape bool) ([]byte, int64, error) {
|
||||||
switch src[cursor] {
|
if src[cursor] == '[' {
|
||||||
case 'n':
|
|
||||||
return compactNull(dst, src, cursor)
|
|
||||||
case '[':
|
|
||||||
dst = append(dst, '[')
|
dst = append(dst, '[')
|
||||||
default:
|
} else {
|
||||||
return nil, 0, errors.ErrExpected("expected [ character for array value", cursor)
|
return nil, 0, errors.ErrExpected("expected [ character for array value", cursor)
|
||||||
}
|
}
|
||||||
cursor = skipWhiteSpace(src, cursor+1)
|
cursor = skipWhiteSpace(src, cursor+1)
|
||||||
|
|
|
@ -26,10 +26,13 @@ func Indent(buf *bytes.Buffer, src []byte, prefix, indentStr string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func doIndent(dst, src []byte, prefix, indentStr string, escape bool) ([]byte, error) {
|
func doIndent(dst, src []byte, prefix, indentStr string, escape bool) ([]byte, error) {
|
||||||
buf, _, err := indentValue(dst, src, 0, 0, []byte(prefix), []byte(indentStr), escape)
|
buf, cursor, err := indentValue(dst, src, 0, 0, []byte(prefix), []byte(indentStr), escape)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if err := validateEndBuf(src, cursor); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return buf, nil
|
return buf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,12 +81,9 @@ func indentObject(
|
||||||
prefix []byte,
|
prefix []byte,
|
||||||
indentBytes []byte,
|
indentBytes []byte,
|
||||||
escape bool) ([]byte, int64, error) {
|
escape bool) ([]byte, int64, error) {
|
||||||
switch src[cursor] {
|
if src[cursor] == '{' {
|
||||||
case 'n':
|
|
||||||
return compactNull(dst, src, cursor)
|
|
||||||
case '{':
|
|
||||||
dst = append(dst, '{')
|
dst = append(dst, '{')
|
||||||
default:
|
} else {
|
||||||
return nil, 0, errors.ErrExpected("expected { character for object value", cursor)
|
return nil, 0, errors.ErrExpected("expected { character for object value", cursor)
|
||||||
}
|
}
|
||||||
cursor = skipWhiteSpace(src, cursor+1)
|
cursor = skipWhiteSpace(src, cursor+1)
|
||||||
|
@ -139,12 +139,9 @@ func indentArray(
|
||||||
prefix []byte,
|
prefix []byte,
|
||||||
indentBytes []byte,
|
indentBytes []byte,
|
||||||
escape bool) ([]byte, int64, error) {
|
escape bool) ([]byte, int64, error) {
|
||||||
switch src[cursor] {
|
if src[cursor] == '[' {
|
||||||
case 'n':
|
|
||||||
return compactNull(dst, src, cursor)
|
|
||||||
case '[':
|
|
||||||
dst = append(dst, '[')
|
dst = append(dst, '[')
|
||||||
default:
|
} else {
|
||||||
return nil, 0, errors.ErrExpected("expected [ character for array value", cursor)
|
return nil, 0, errors.ErrExpected("expected [ character for array value", cursor)
|
||||||
}
|
}
|
||||||
cursor = skipWhiteSpace(src, cursor+1)
|
cursor = skipWhiteSpace(src, cursor+1)
|
||||||
|
|
61
json_test.go
61
json_test.go
|
@ -2,6 +2,7 @@ package json_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
stdjson "encoding/json"
|
||||||
"math"
|
"math"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
@ -81,9 +82,34 @@ func TestCompact(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t.Run("invalid", func(t *testing.T) {
|
t.Run("invalid", func(t *testing.T) {
|
||||||
|
for _, src := range []string{
|
||||||
|
`invalid`,
|
||||||
|
`}`,
|
||||||
|
`]`,
|
||||||
|
`{"a":1}}`,
|
||||||
|
`{"a" 1}`,
|
||||||
|
`{"a": 1 "b": 2}`,
|
||||||
|
`["a" "b"]`,
|
||||||
|
`"\`,
|
||||||
|
`{"a":"\\""}`,
|
||||||
|
`tr`,
|
||||||
|
`{"a": tru, "b": 1}`,
|
||||||
|
`fal`,
|
||||||
|
`{"a": fals, "b": 1}`,
|
||||||
|
`nu`,
|
||||||
|
`{"a": nul, "b": 1}`,
|
||||||
|
`1.234.567`,
|
||||||
|
`[nul]`,
|
||||||
|
`{} 1`,
|
||||||
|
} {
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
if err := json.Compact(&buf, []byte(`invalid`)); err == nil {
|
if err := stdjson.Compact(&buf, []byte(src)); err == nil {
|
||||||
t.Fatal(err)
|
t.Fatal("invalid test case")
|
||||||
|
}
|
||||||
|
buf.Reset()
|
||||||
|
if err := json.Compact(&buf, []byte(src)); err == nil {
|
||||||
|
t.Fatalf("%q: expected error", src)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -125,6 +151,37 @@ func TestIndent(t *testing.T) {
|
||||||
t.Errorf("Indent(%#q) = %#q, want %#q", tt.compact, s, tt.indent)
|
t.Errorf("Indent(%#q) = %#q, want %#q", tt.compact, s, tt.indent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
t.Run("invalid", func(t *testing.T) {
|
||||||
|
for _, src := range []string{
|
||||||
|
`invalid`,
|
||||||
|
`}`,
|
||||||
|
`]`,
|
||||||
|
`{"a":1}}`,
|
||||||
|
`{"a" 1}`,
|
||||||
|
`{"a": 1 "b": 2}`,
|
||||||
|
`["a" "b"]`,
|
||||||
|
`"\`,
|
||||||
|
`{"a":"\\""}`,
|
||||||
|
`tr`,
|
||||||
|
`{"a": tru, "b": 1}`,
|
||||||
|
`fal`,
|
||||||
|
`{"a": fals, "b": 1}`,
|
||||||
|
`nu`,
|
||||||
|
`{"a": nul, "b": 1}`,
|
||||||
|
`1.234.567`,
|
||||||
|
`[nul]`,
|
||||||
|
`{} 1`,
|
||||||
|
} {
|
||||||
|
buf.Reset()
|
||||||
|
if err := stdjson.Indent(&buf, []byte(src), "", " "); err == nil {
|
||||||
|
t.Fatal("invalid test case")
|
||||||
|
}
|
||||||
|
buf.Reset()
|
||||||
|
if err := json.Indent(&buf, []byte(src), "", " "); err == nil {
|
||||||
|
t.Fatalf("%q: expected error", src)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests of a large random structure.
|
// Tests of a large random structure.
|
||||||
|
|
Loading…
Reference in New Issue