commit 50e09b5f464547dd8f2486012750a6aa5fabd9da
parent d45423fa42830f3d6379d75692aeda62215335ed
Author: Francois Parquet <francois.parquet@gmail.com>
Date: Sun, 29 Apr 2018 00:22:54 +0800
Merge pull request #11 from francoispqt/update/add-tests
Update/add tests
Diffstat:
11 files changed, 142 insertions(+), 40 deletions(-)
diff --git a/decode.go b/decode.go
@@ -13,7 +13,7 @@ import (
// If a JSON value is not appropriate for a given target type, or if a JSON number
// overflows the target type, UnmarshalArray skips that field and completes the unmarshaling as best it can.
func UnmarshalArray(data []byte, v UnmarshalerArray) error {
- dec := BorrowDecoder(nil)
+ dec := borrowDecoder(nil, 0)
defer dec.Release()
dec.data = make([]byte, len(data))
copy(dec.data, data)
@@ -35,7 +35,7 @@ func UnmarshalArray(data []byte, v UnmarshalerArray) error {
// If a JSON value is not appropriate for a given target type, or if a JSON number
// overflows the target type, UnmarshalObject skips that field and completes the unmarshaling as best it can.
func UnmarshalObject(data []byte, v UnmarshalerObject) error {
- dec := BorrowDecoder(nil)
+ dec := borrowDecoder(nil, 0)
defer dec.Release()
dec.data = make([]byte, len(data))
copy(dec.data, data)
@@ -73,53 +73,53 @@ func Unmarshal(data []byte, v interface{}) error {
var dec *Decoder
switch vt := v.(type) {
case *string:
- dec = BorrowDecoder(nil)
+ dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeString(vt)
case *int:
- dec = BorrowDecoder(nil)
+ dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeInt(vt)
case *int32:
- dec = BorrowDecoder(nil)
+ dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeInt32(vt)
case *uint32:
- dec = BorrowDecoder(nil)
+ dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeUint32(vt)
case *int64:
- dec = BorrowDecoder(nil)
+ dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeInt64(vt)
case *uint64:
- dec = BorrowDecoder(nil)
+ dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeUint64(vt)
case *float64:
- dec = BorrowDecoder(nil)
+ dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeFloat64(vt)
case *bool:
- dec = BorrowDecoder(nil)
+ dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeBool(vt)
case UnmarshalerObject:
- dec = BorrowDecoder(nil)
+ dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = make([]byte, len(data))
copy(dec.data, data)
_, err = dec.decodeObject(vt)
case UnmarshalerArray:
- dec = BorrowDecoder(nil)
+ dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = make([]byte, len(data))
copy(dec.data, data)
diff --git a/decode_array.go b/decode_array.go
@@ -71,7 +71,7 @@ func (dec *Decoder) skipArray() (int, error) {
var arraysOpen = 1
var arraysClosed = 0
// var stringOpen byte = 0
- for j := dec.cursor; j < dec.length; j++ {
+ for j := dec.cursor; j < dec.length || dec.read(); j++ {
switch dec.data[j] {
case ']':
arraysClosed++
@@ -94,7 +94,7 @@ func (dec *Decoder) skipArray() (int, error) {
// loop backward and count how many anti slash found
// to see if string is effectively escaped
ct := 1
- for i := j; i > 0; i-- {
+ for i := j - 2; i > 0; i-- {
if dec.data[i] != '\\' {
break
}
diff --git a/decode_array_test.go b/decode_array_test.go
@@ -189,3 +189,38 @@ func TestDecoderSliceDecoderAPIError(t *testing.T) {
assert.NotNil(t, err, "Err must not be nil as JSON is invalid")
assert.IsType(t, InvalidJSONError(""), err, "err message must be 'Invalid JSON'")
}
+
+func TestSkipArray(t *testing.T) {
+ testCases := []struct {
+ json string
+ expectations func(*testing.T, int, error)
+ }{
+ {
+ json: `"testbasic"]`,
+ expectations: func(t *testing.T, i int, err error) {
+ assert.Equal(t, len(`"testbasic"]`), i)
+ assert.Nil(t, err)
+ },
+ },
+ {
+ json: `"test \\\\\" escape"]`,
+ expectations: func(t *testing.T, i int, err error) {
+ assert.Equal(t, len(`"test \\\\\" escape"]`), i)
+ assert.Nil(t, err)
+ },
+ },
+ {
+ json: `"test \\\\\\"]`,
+ expectations: func(t *testing.T, i int, err error) {
+ assert.Equal(t, len(`"test \\\\\\"]`), i)
+ assert.Nil(t, err)
+ },
+ },
+ }
+
+ for _, test := range testCases {
+ dec := NewDecoder(strings.NewReader(test.json))
+ i, err := dec.skipArray()
+ test.expectations(t, i, err)
+ }
+}
diff --git a/decode_number.go b/decode_number.go
@@ -581,7 +581,7 @@ func (dec *Decoder) atoi32(start, end int) int32 {
for i := start + 1; i < end; i++ {
intv := int32(digits[dec.data[i]])
if val > maxInt32toMultiply {
- dec.err = InvalidTypeError("Overflows int321")
+ dec.err = InvalidTypeError("Overflows int32")
return 0
}
val = (val << 3) + (val << 1)
diff --git a/decode_number_test.go b/decode_number_test.go
@@ -63,6 +63,20 @@ func TestDecoderIntOverfow(t *testing.T) {
assert.NotNil(t, err, "Err must not be nil as int is overflowing")
assert.Equal(t, 0, v, "v must be equal to 0")
}
+func TestDecoderIntOverfow2(t *testing.T) {
+ json := []byte(`92233720368547758089 `)
+ var v int
+ err := Unmarshal(json, &v)
+ assert.NotNil(t, err, "Err must not be nil as int is overflowing")
+ assert.Equal(t, 0, v, "v must be equal to 0")
+}
+func TestDecoderIntOverfow3(t *testing.T) {
+ json := []byte(`92233720368547758089 `)
+ var v int
+ err := Unmarshal(json, &v)
+ assert.NotNil(t, err, "Err must not be nil as int is overflowing")
+ assert.Equal(t, 0, v, "v must be equal to 0")
+}
func TestDecoderIntPoolError(t *testing.T) {
result := int(1)
dec := NewDecoder(nil)
@@ -75,13 +89,6 @@ func TestDecoderIntPoolError(t *testing.T) {
_ = dec.DecodeInt(&result)
assert.True(t, false, "should not be called as decoder should have panicked")
}
-func TestDecoderIntOverfow2(t *testing.T) {
- json := []byte(`92233720368547758089 `)
- var v int
- err := Unmarshal(json, &v)
- assert.NotNil(t, err, "Err must not be nil as int is overflowing")
- assert.Equal(t, 0, v, "v must be equal to 0")
-}
func TestDecoderInttDecoderAPI(t *testing.T) {
var v int
dec := NewDecoder(strings.NewReader(`33`))
@@ -398,6 +405,20 @@ func TestDecoderFloatBasic(t *testing.T) {
assert.Nil(t, err, "Err must be nil")
assert.Equal(t, 100.11, v, "v must be equal to 100.11")
}
+func TestDecoderFloatBasic2(t *testing.T) {
+ json := []byte(` 100.11 `)
+ var v float64
+ err := Unmarshal(json, &v)
+ assert.Nil(t, err, "Err must be nil")
+ assert.Equal(t, 100.11, v, "v must be equal to 100.11")
+}
+func TestDecoderFloatBasic3(t *testing.T) {
+ json := []byte(` 100 `)
+ var v float64
+ err := Unmarshal(json, &v)
+ assert.Nil(t, err, "Err must be nil")
+ assert.Equal(t, float64(100), v, "v must be equal to 100.11")
+}
func TestDecoderFloatBig(t *testing.T) {
json := []byte(`89899843.3493493 `)
diff --git a/decode_object_test.go b/decode_object_test.go
@@ -154,8 +154,13 @@ func TestDecodeObjectNull(t *testing.T) {
var jsonComplex = []byte(`{
"test": "{\"test\":\"1\",\"test1\":2}",
"test2\\n": "\\\\\\\\\\\n",
- "testArrSkip": ["testString with escaped \" quotes"],
+ "testArrSkip": ["testString with escaped \\\" quotes"],
"testSkipString": "skip \\ string with \\n escaped char \" ",
+ "testSkipObject": {
+ "testSkipSubObj": {
+ "test": "test"
+ }
+ },
"testSkipNumber": 123.23,
"testBool": true,
"testSub": {
@@ -210,7 +215,7 @@ func TestDecodeObjComplex(t *testing.T) {
result := jsonObjectComplex{}
err := UnmarshalObject(jsonComplex, &result)
assert.NotNil(t, err, "err should not be as invalid type as been encountered nil")
- assert.Equal(t, `Cannot unmarshal to struct, wrong char '"' found at pos 460`, err.Error(), "err should not be as invalid type as been encountered nil")
+ assert.Equal(t, `Cannot unmarshal to struct, wrong char '"' found at pos 531`, err.Error(), "err should not be as invalid type as been encountered nil")
assert.Equal(t, `{"test":"1","test1":2}`, result.Test, "result.Test is not expected value")
assert.Equal(t, `\\\\\\n`, result.Test2, "result.Test2 is not expected value")
assert.Equal(t, 1, result.Test3, "result.test3 is not expected value")
diff --git a/encode.go b/encode.go
@@ -1,5 +1,10 @@
package gojay
+import (
+ "fmt"
+ "reflect"
+)
+
// MarshalObject returns the JSON encoding of v.
//
// It takes a struct implementing Marshaler to a JSON slice of byte
@@ -162,6 +167,8 @@ func Marshal(v interface{}) ([]byte, error) {
enc := BorrowEncoder()
defer enc.Release()
return enc.encodeFloat(float64(vt))
+ default:
+ err = InvalidMarshalError(fmt.Sprintf(invalidMarshalErrorMsg, reflect.TypeOf(vt).String()))
}
return b, err
}
diff --git a/encode_builder_test.go b/encode_builder_test.go
@@ -0,0 +1,16 @@
+package gojay
+
+import (
+ "testing"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestEncoderBuilderError(t *testing.T) {
+ enc := NewEncoder()
+ defer func() {
+ err := recover()
+ assert.NotNil(t, err, "err is not nil as we pass an invalid number to grow")
+ }()
+ enc.grow(-1)
+ assert.True(t, false, "should not be called")
+}
+\ No newline at end of file
diff --git a/encode_interface.go b/encode_interface.go
@@ -85,37 +85,37 @@ func (enc *Encoder) AddInterface(value interface{}) error {
// AddInterfaceKey adds an interface{} to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) AddInterfaceKey(key string, value interface{}) error {
- switch value.(type) {
+ switch vt := value.(type) {
case string:
- return enc.AddStringKey(key, value.(string))
+ return enc.AddStringKey(key, vt)
case bool:
- return enc.AddBoolKey(key, value.(bool))
+ return enc.AddBoolKey(key, vt)
case MarshalerArray:
return enc.AddArrayKey(key, value.(MarshalerArray))
case MarshalerObject:
return enc.AddObjectKey(key, value.(MarshalerObject))
case int:
- return enc.AddIntKey(key, value.(int))
+ return enc.AddIntKey(key, vt)
case int64:
- return enc.AddIntKey(key, int(value.(int64)))
+ return enc.AddIntKey(key, int(vt))
case int32:
- return enc.AddIntKey(key, int(value.(int32)))
+ return enc.AddIntKey(key, int(vt))
case int16:
- return enc.AddIntKey(key, int(value.(int16)))
+ return enc.AddIntKey(key, int(vt))
case int8:
- return enc.AddIntKey(key, int(value.(int8)))
+ return enc.AddIntKey(key, int(vt))
case uint64:
- return enc.AddIntKey(key, int(value.(uint64)))
+ return enc.AddIntKey(key, int(vt))
case uint32:
- return enc.AddIntKey(key, int(value.(uint32)))
+ return enc.AddIntKey(key, int(vt))
case uint16:
- return enc.AddIntKey(key, int(value.(uint16)))
+ return enc.AddIntKey(key, int(vt))
case uint8:
- return enc.AddIntKey(key, int(value.(uint8)))
+ return enc.AddIntKey(key, int(vt))
case float64:
- return enc.AddFloatKey(key, value.(float64))
+ return enc.AddFloatKey(key, vt)
case float32:
- return enc.AddFloat32Key(key, value.(float32))
+ return enc.AddFloat32Key(key, vt)
}
return nil
diff --git a/encode_interface_test.go b/encode_interface_test.go
@@ -1,6 +1,8 @@
package gojay
import (
+ "fmt"
+ "reflect"
"testing"
"github.com/stretchr/testify/assert"
@@ -53,6 +55,13 @@ var encoderTestCases = []struct {
},
},
{
+ v: uint16(100),
+ expectations: func(t *testing.T, b []byte, err error) {
+ assert.Nil(t, err, "err should be nil")
+ assert.Equal(t, "100", string(b), "string(b) should equal 100")
+ },
+ },
+ {
v: uint8(100),
expectations: func(t *testing.T, b []byte, err error) {
assert.Nil(t, err, "err should be nil")
@@ -101,6 +110,14 @@ var encoderTestCases = []struct {
assert.Equal(t, `{"testStr":"漢字","testInt":1,"testInt64":1,"testInt32":1,"testInt16":1,"testInt8":1,"testUint64":1,"testUint32":1,"testUint16":1,"testUint8":1,"testFloat64":1.1,"testFloat32":1.1,"testBool":true}`, string(b), `string(b) should equal {"testStr":"漢字","testInt":1,"testInt64":1,"testInt32":1,"testInt16":1,"testInt8":1,"testUint64":1,"testUint32":1,"testUint16":1,"testUint8":1,"testFloat64":1.1,"testFloat32":1.1,"testBool":true}`)
},
},
+ {
+ v: &struct{}{},
+ expectations: func(t *testing.T, b []byte, err error) {
+ assert.NotNil(t, err, "err should be nil")
+ assert.IsType(t, InvalidMarshalError(""), err, "err should be of type InvalidMarshalError")
+ assert.Equal(t, fmt.Sprintf(invalidMarshalErrorMsg, reflect.TypeOf(&struct{}{}).String()), err.Error(), "err message should be equal to invalidMarshalErrorMsg")
+ },
+ },
}
func TestEncoderInterfaceAllTypesDecoderAPI(t *testing.T) {
diff --git a/encode_object_test.go b/encode_object_test.go
@@ -74,11 +74,11 @@ func (t *TestEncoding) MarshalObject(enc *Encoder) {
enc.AddStringKey("test2", t.test2)
enc.AddIntKey("testInt", t.testInt)
enc.AddBoolKey("testBool", t.testBool)
- enc.AddArrayKey("testArr", t.testArr)
+ enc.AddInterfaceKey("testArr", t.testArr)
enc.AddInterfaceKey("testF64", t.testF64)
enc.AddInterfaceKey("testF32", t.testF32)
enc.AddInterfaceKey("testInterface", t.testInterface)
- enc.AddObjectKey("sub", t.sub)
+ enc.AddInterfaceKey("sub", t.sub)
}
type SubObject struct {