commit f8ac1adb3c5dd61f87449ee9b3020e0d2836ca3a
parent 2c1c12d273d835b9270bdb62ae296366f91bc01d
Author: Salim Afiune <afiune@chef.io>
Date: Wed, 22 Aug 2018 20:01:45 +0200
Adds more test coverage
Signed-off-by: Salim Afiune <afiune@chef.io>
Diffstat:
2 files changed, 360 insertions(+), 5 deletions(-)
diff --git a/decode_interface_test.go b/decode_interface_test.go
@@ -30,6 +30,36 @@ func TestDecodeInterfaceBasic(t *testing.T) {
err: false,
},
{
+ name: "string",
+ json: `"hola amigos!"`,
+ expectedResult: interface{}("hola amigos!"),
+ err: false,
+ },
+ {
+ name: "bool-true",
+ json: `true`,
+ expectedResult: interface{}(true),
+ err: false,
+ },
+ {
+ name: "bool-false",
+ json: `false`,
+ expectedResult: interface{}(false),
+ err: false,
+ },
+ {
+ name: "null",
+ json: `null`,
+ expectedResult: interface{}(nil),
+ err: false,
+ },
+ {
+ name: "number",
+ json: `1234`,
+ expectedResult: interface{}(float64(1234)),
+ err: false,
+ },
+ {
name: "array-error",
json: `["h""o","l","a"]`,
err: true,
@@ -43,10 +73,81 @@ func TestDecodeInterfaceBasic(t *testing.T) {
errType: &json.SyntaxError{},
skipCheckResult: true,
},
+ {
+ name: "string-error",
+ json: `"hola amigos!`,
+ err: true,
+ errType: InvalidJSONError(""),
+ skipCheckResult: true,
+ },
+ {
+ name: "bool-true-error",
+ json: `truee`,
+ err: true,
+ errType: InvalidJSONError(""),
+ skipCheckResult: true,
+ },
+ {
+ name: "bool-false-error",
+ json: `fase`,
+ expectedResult: interface{}(false),
+ err: true,
+ errType: InvalidJSONError(""),
+ skipCheckResult: true,
+ },
+ {
+ name: "null-error",
+ json: `nulllll`,
+ err: true,
+ errType: InvalidJSONError(""),
+ skipCheckResult: true,
+ },
+ {
+ name: "number-error",
+ json: `1234"`,
+ err: true,
+ errType: InvalidJSONError(""),
+ skipCheckResult: true,
+ },
+ {
+ name: "unknown-error",
+ json: `?`,
+ err: true,
+ errType: InvalidJSONError(""),
+ skipCheckResult: true,
+ },
+ {
+ name: "empty-json-error",
+ json: ``,
+ err: true,
+ errType: InvalidJSONError(""),
+ skipCheckResult: true,
+ },
}
for _, testCase := range testCases {
- t.Run(testCase.name, func(t *testing.T) {
+ t.Run("DecodeInterface()"+testCase.name, func(t *testing.T) {
+ var i interface{}
+ dec := BorrowDecoder(strings.NewReader(testCase.json))
+ defer dec.Release()
+ err := dec.DecodeInterface(&i)
+ if testCase.err {
+ t.Log(err)
+ assert.NotNil(t, err, "err should not be nil")
+ if testCase.errType != nil {
+ assert.IsType(t, testCase.errType, err, "err should be of the given type")
+ }
+ return
+ }
+ assert.Nil(t, err, "err should be nil")
+ if !testCase.skipCheckResult {
+ assert.Equal(t, testCase.expectedResult, i, "value at given index should be the same as expected results")
+ }
+ })
+ }
+
+ for _, testCase := range testCases {
+ t.Run("Decode()"+testCase.name, func(t *testing.T) {
var i interface{}
dec := BorrowDecoder(strings.NewReader(testCase.json))
defer dec.Release()
@@ -67,7 +168,142 @@ func TestDecodeInterfaceBasic(t *testing.T) {
}
}
-func TestDecodeInterfaceObject(t *testing.T) {
+func TestDecodeInterfaceAsInterface(t *testing.T) {
+ testCases := []struct {
+ name string
+ json string
+ expectedResult interface{}
+ err bool
+ errType interface{}
+ skipCheckResult bool
+ }{
+ {
+ name: "basic-array",
+ json: `{
+ "testStr": "hola",
+ "testInterface": ["h","o","l","a"]
+ }`,
+ expectedResult: map[string]interface{}(
+ map[string]interface{}{
+ "testStr": "hola",
+ "testInterface": []interface{}{"h", "o", "l", "a"},
+ }),
+ err: false,
+ },
+ {
+ name: "basic-string",
+ json: `{
+ "testInterface": "漢字"
+ }`,
+ expectedResult: map[string]interface{}(
+ map[string]interface{}{
+ "testInterface": "漢字",
+ }),
+ err: false,
+ },
+ {
+ name: "basic-error",
+ json: `{
+ "testInterface": ["a""d","i","o","s"]
+ }`,
+ err: true,
+ errType: &json.SyntaxError{},
+ skipCheckResult: true,
+ },
+ {
+ name: "basic-interface",
+ json: `{
+ "testInterface": {
+ "string": "prost"
+ }
+ }`,
+ expectedResult: map[string]interface{}(
+ map[string]interface{}{
+ "testInterface": map[string]interface{}{"string": "prost"},
+ }),
+ err: false,
+ },
+ {
+ name: "complex-interface",
+ json: `{
+ "testInterface": {
+ "number": 1988,
+ "string": "prost",
+ "array": ["h","o","l","a"],
+ "object": {
+ "k": "v",
+ "a": [1,2,3]
+ },
+ "array-of-objects": [
+ {"k": "v"},
+ {"a": "b"}
+ ]
+ }
+ }`,
+ expectedResult: map[string]interface{}(
+ map[string]interface{}{
+ "testInterface": map[string]interface{}{
+ "array-of-objects": []interface{}{
+ map[string]interface{}{"k": "v"},
+ map[string]interface{}{"a": "b"},
+ },
+ "number": float64(1988),
+ "string": "prost",
+ "array": []interface{}{"h", "o", "l", "a"},
+ "object": map[string]interface{}{
+ "k": "v",
+ "a": []interface{}{float64(1), float64(2), float64(3)},
+ },
+ },
+ }),
+ err: false,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run("Decode()"+testCase.name, func(t *testing.T) {
+ var s interface{}
+ dec := BorrowDecoder(strings.NewReader(testCase.json))
+ defer dec.Release()
+ err := dec.Decode(&s)
+ if testCase.err {
+ t.Log(err)
+ assert.NotNil(t, err, "err should not be nil")
+ if testCase.errType != nil {
+ assert.IsType(t, testCase.errType, err, "err should be of the given type")
+ }
+ return
+ }
+ assert.Nil(t, err, "err should be nil")
+ if !testCase.skipCheckResult {
+ assert.Equal(t, testCase.expectedResult, s, "value at given index should be the same as expected results")
+ }
+ })
+ }
+
+ for _, testCase := range testCases {
+ t.Run("DecodeInterface()"+testCase.name, func(t *testing.T) {
+ var s interface{}
+ dec := BorrowDecoder(strings.NewReader(testCase.json))
+ defer dec.Release()
+ err := dec.DecodeInterface(&s)
+ if testCase.err {
+ t.Log(err)
+ assert.NotNil(t, err, "err should not be nil")
+ if testCase.errType != nil {
+ assert.IsType(t, testCase.errType, err, "err should be of the given type")
+ }
+ return
+ }
+ assert.Nil(t, err, "err should be nil")
+ if !testCase.skipCheckResult {
+ assert.Equal(t, testCase.expectedResult, s, "value at given index should be the same as expected results")
+ }
+ })
+ }
+}
+
+func TestDecodeAsTestObject(t *testing.T) {
testCases := []struct {
name string
json string
@@ -80,7 +316,7 @@ func TestDecodeInterfaceObject(t *testing.T) {
name: "basic-array",
json: `{
"testStr": "hola",
- "testInterface": ["h","o","l","a"],
+ "testInterface": ["h","o","l","a"]
}`,
expectedResult: testObject{
testStr: "hola",
@@ -91,7 +327,7 @@ func TestDecodeInterfaceObject(t *testing.T) {
{
name: "basic-string",
json: `{
- "testInterface": "漢字",
+ "testInterface": "漢字"
}`,
expectedResult: testObject{
testInterface: interface{}("漢字"),
@@ -99,6 +335,15 @@ func TestDecodeInterfaceObject(t *testing.T) {
err: false,
},
{
+ name: "basic-error",
+ json: `{
+ "testInterface": ["a""d","i","o","s"]
+ }`,
+ err: true,
+ errType: &json.SyntaxError{},
+ skipCheckResult: true,
+ },
+ {
name: "basic-interface",
json: `{
"testInterface": {
@@ -145,7 +390,6 @@ func TestDecodeInterfaceObject(t *testing.T) {
err: false,
},
}
-
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
s := testObject{}
@@ -167,3 +411,98 @@ func TestDecodeInterfaceObject(t *testing.T) {
})
}
}
+
+func TestUnmarshalInterface(t *testing.T) {
+ json := []byte(`{
+ "testInterface": {
+ "number": 1988,
+ "string": "prost",
+ "array": ["h","o","l","a"],
+ "object": {
+ "k": "v",
+ "a": [1,2,3]
+ },
+ "array-of-objects": [
+ {"k": "v"},
+ {"a": "b"}
+ ]
+ }
+ }`)
+ v := &testObject{}
+ err := Unmarshal(json, v)
+ assert.Nil(t, err, "Err must be nil")
+ expectedInterface := map[string]interface{}{
+ "array-of-objects": []interface{}{
+ map[string]interface{}{"k": "v"},
+ map[string]interface{}{"a": "b"},
+ },
+ "number": float64(1988),
+ "string": "prost",
+ "array": []interface{}{"h", "o", "l", "a"},
+ "object": map[string]interface{}{
+ "k": "v",
+ "a": []interface{}{float64(1), float64(2), float64(3)},
+ },
+ }
+ assert.Equal(t, expectedInterface, v.testInterface, "v.testInterface must be equal to the expected one")
+}
+
+func TestUnmarshalInterfaceError(t *testing.T) {
+ testCases := []struct {
+ name string
+ json []byte
+ }{
+ {
+ name: "basic",
+ json: []byte(`{"testInterface": {"number": 1bc4}}`),
+ },
+ {
+ name: "syntax",
+ json: []byte(`{
+ "testInterface": {
+ "array?": [1,"a", ?]
+ }
+ }`),
+ },
+ {
+ name: "complex",
+ json: []byte(`{
+ "testInterface": {
+ "number": 1988,
+ "string": "prost",
+ "array": ["h""o","l","a"],
+ "object": {
+ "k": "v",
+ "a": [1,2,3]
+ },
+ "array-of-objects": [
+ {"k": "v"},
+ {"a": "b"}
+ ]
+ }
+ }`),
+ },
+ }
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ v := &testObject{}
+ err := Unmarshal(testCase.json, v)
+ assert.NotNil(t, err, "Err must be not nil")
+ t.Log(err)
+ assert.IsType(t, &json.SyntaxError{}, err, "err should be a json.SyntaxError{}")
+ })
+ }
+}
+
+func TestDecodeInterfacePoolError(t *testing.T) {
+ result := interface{}(1)
+ dec := NewDecoder(nil)
+ dec.Release()
+ defer func() {
+ err := recover()
+ assert.NotNil(t, err, "err shouldnt be nil")
+ assert.IsType(t, InvalidUsagePooledDecoderError(""), err, "err should be of type InvalidUsagePooledDecoderError")
+ }()
+ _ = dec.DecodeInterface(&result)
+ assert.True(t, false, "should not be called as decoder should have panicked")
+}
diff --git a/decode_test.go b/decode_test.go
@@ -239,6 +239,22 @@ func TestUnmarshalAllTypes(t *testing.T) {
},
},
{
+ v: new(interface{}),
+ d: []byte(`[{"test":"test"},{"test":"test2"}]`),
+ name: "test decode interface",
+ expectations: func(err error, v interface{}, t *testing.T) {
+ assert.Nil(t, err, "err must be nil")
+ // v is a pointer to an interface{}, we need to extract the content
+ vCont := reflect.ValueOf(v).Elem().Interface()
+ vt := vCont.([]interface{})
+ assert.Len(t, vt, 2, "len of vt must be 2")
+ vt1 := vt[0].(map[string]interface{})
+ assert.Equal(t, "test", vt1["test"], "vt1['test'] must be equal to 'test'")
+ vt2 := vt[1].(map[string]interface{})
+ assert.Equal(t, "test2", vt2["test"], "vt2['test'] must be equal to 'test2'")
+ },
+ },
+ {
v: new(struct{}),
d: []byte(`{"test":"test"}`),
name: "test decode invalid type",