Fixed unmarshalling json input into `interface{}` type (#1832)

## Changes
Fixed unmarshalling json input into `interface{}` type

Commands like `api post` support free form request input, so it should
be unmarshaled correctly

## Tests
Added regression test + E2E test pass
This commit is contained in:
Andrew Nester 2024-10-15 14:10:02 +02:00 committed by GitHub
parent ab20624206
commit 0753dfe2f4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 24 additions and 14 deletions

View File

@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"os"
"reflect"
"github.com/databricks/cli/libs/diag"
"github.com/databricks/cli/libs/dyn/convert"
@ -63,11 +64,24 @@ func (j *JsonFlag) Unmarshal(v any) diag.Diagnostics {
return diags.Extend(diag.FromErr(err))
}
// Finally unmarshal the normalized data to the output.
// It will fill in the ForceSendFields field if the struct contains it.
err = marshal.Unmarshal(data, v)
if err != nil {
return diags.Extend(diag.FromErr(err))
kind := reflect.ValueOf(v).Kind()
if kind == reflect.Ptr {
kind = reflect.ValueOf(v).Elem().Kind()
}
if kind == reflect.Struct {
// Finally unmarshal the normalized data to the output.
// It will fill in the ForceSendFields field if the struct contains it.
err = marshal.Unmarshal(data, v)
if err != nil {
return diags.Extend(diag.FromErr(err))
}
} else {
// If the output is not a struct, just unmarshal the data to the output.
err = json.Unmarshal(data, v)
if err != nil {
return diags.Extend(diag.FromErr(err))
}
}
return diags

View File

@ -13,10 +13,6 @@ import (
"github.com/stretchr/testify/require"
)
type requestType struct {
Foo string `json:"foo"`
}
func TestJsonFlagEmpty(t *testing.T) {
var body JsonFlag
@ -35,13 +31,13 @@ func TestJsonFlagInline(t *testing.T) {
err := body.Set(`{"foo": "bar"}`)
assert.NoError(t, err)
var request requestType
var request any
diags := body.Unmarshal(&request)
assert.NoError(t, diags.Error())
assert.Empty(t, diags)
assert.Equal(t, "JSON (14 bytes)", body.String())
assert.Equal(t, requestType{"bar"}, request)
assert.Equal(t, map[string]any{"foo": "bar"}, request)
}
func TestJsonFlagError(t *testing.T) {
@ -50,7 +46,7 @@ func TestJsonFlagError(t *testing.T) {
err := body.Set(`{"foo":`)
assert.NoError(t, err)
var request requestType
var request any
diags := body.Unmarshal(&request)
assert.EqualError(t, diags.Error(), "error decoding JSON at (inline):1:8: unexpected end of JSON input")
assert.Equal(t, "JSON (7 bytes)", body.String())
@ -58,7 +54,7 @@ func TestJsonFlagError(t *testing.T) {
func TestJsonFlagFile(t *testing.T) {
var body JsonFlag
var request requestType
var request any
var fpath string
var payload = []byte(`{"foo": "bar"}`)
@ -78,7 +74,7 @@ func TestJsonFlagFile(t *testing.T) {
assert.NoError(t, diags.Error())
assert.Empty(t, diags)
assert.Equal(t, requestType{"bar"}, request)
assert.Equal(t, map[string]any{"foo": "bar"}, request)
}
const jsonData = `