diff --git a/Makefile b/Makefile index 452f846..a6500b7 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,9 @@ build: install: build go install -ldflags "-X main.Version=${VERSION}" . +test: + go test -v ./... + create-schemas: build ./magda-cli schema create --id cse-order --name cse-order --schema-file example/schema/order.json ./magda-cli schema create --id cse-service --name cse-service --schemaFile example/schema/service.json diff --git a/pkg/adapter/payload.go b/pkg/adapter/payload.go index 526c1ac..b7e77ba 100644 --- a/pkg/adapter/payload.go +++ b/pkg/adapter/payload.go @@ -8,7 +8,6 @@ import ( "io/ioutil" "os" - "github.com/jdockerty/yaml-to-json-go/conversion" log "go.uber.org/zap" ) @@ -44,7 +43,7 @@ func LoadPayloadFromBytes(data []byte, isYAML bool) (pyld Payload, err error) { if err = yaml.Unmarshal(data, &obj); err != nil { return } - if data, err = conversion.YAMLToJSON(obj); err != nil { + if data, err = yamlToJSON(obj); err != nil { return } } @@ -52,6 +51,40 @@ func LoadPayloadFromBytes(data []byte, isYAML bool) (pyld Payload, err error) { return } +func yamlToJSON(yamlData map[interface{}]interface{}) ([]byte, error) { + cleanedYaml := cleanYaml(yamlData) + output, err := json.Marshal(cleanedYaml) + if err != nil { + return nil, fmt.Errorf("error converting yaml to json: %s", err.Error()) + } + return output, nil +} + +// fixed version from the one found in "github.com/jdockerty/yaml-to-json-go/conversion" +func cleanYaml(in map[interface{}]interface{}) map[string]interface{} { + output := make(map[string]interface{}) + for key, value := range in { + skey := key.(string) // expected to be 'string' + output[skey] = value + + mval, isMap := value.(map[interface{}]interface{}) + sval, isSlice := value.([]interface{}) + + if isMap { + output[skey] = cleanYaml(mval) + } else if isSlice { + for i, item := range sval { + mitem, isInnerMap := item.(map[interface{}]interface{}) + if isInnerMap { + sval[i] = cleanYaml(mitem) + } + // otherwise do nothing + } + } + } + return output +} + func ReplyPrinter(pld Payload, useYAML bool) (err error) { var f interface{} if err = pld.AsType(&f); err != nil { diff --git a/pkg/adapter/payload_test.go b/pkg/adapter/payload_test.go new file mode 100644 index 0000000..61399b5 --- /dev/null +++ b/pkg/adapter/payload_test.go @@ -0,0 +1,99 @@ +package adapter + +import ( + _ "fmt" + _ "regexp" + "testing" + +) + +func TestYaml(t *testing.T) { + y := ` +foo: 1 +` + p, _ := LoadPayloadFromBytes([]byte(y), true) + m, _ := p.AsObject() + switch v := m[`foo`].(type) { + default: + t.Fatalf("unexpected type %T for 'foo'", v) + case float64: + if int(v) != 1 { + t.Fatalf("Expected '1', but is '%f'", v) + } + } +} + + +func TestYamlArray(t *testing.T) { + type A struct { + Value int `json:"a"` + } + type T struct { + Foo []A `json:"foo"` + } + + y := ` +foo: + - a: 1 + - a: 2 +` + p, err := LoadPayloadFromBytes([]byte(y), true) + if err != nil { + t.Fatalf("LoadPayloadFromBytes - %v", err) + } + var res T + if err = p.AsType(&res); err != nil { + t.Fatalf("Unmarshall - %v", err) + } + + if len(res.Foo) != 2 { + t.Fatalf("Expected array of length 2, but got %v", res.Foo) + } + for i, item := range res.Foo { + if item.Value != i + 1 { + t.Fatalf("Expected item value of %d, but got %d", i + 1, item.Value) + } + } +} + +func TestYamlNested(t *testing.T) { + type B struct { + Value []int `json:"v"` + } + type A struct { + List []B `json:"b"` + } + type T struct { + Foo []A `json:"a"` + } + + y := ` +a: + - b: + - v: + - 1 + - 2 + - b: +` + p, err := LoadPayloadFromBytes([]byte(y), true) + if err != nil { + t.Fatalf("LoadPayloadFromBytes - %v", err) + } + var res T + if err = p.AsType(&res); err != nil { + t.Fatalf("Unmarshall - %v", err) + } + + if len(res.Foo) != 2 { + t.Fatalf("Expected array of length 2, but got %v", res.Foo) + } + e1 := res.Foo[0] + if len(e1.List) != 1 { + t.Fatalf("Expected array of length 1, but got %v", e1.List) + } + for i, item := range e1.List[0].Value { + if item != i + 1 { + t.Fatalf("Expected item value of %d, but got %d", i + 1, item) + } + } +}