Suggested changes

This commit is contained in:
Phani Teja Marupaka
2020-06-07 15:13:21 -07:00
parent dc4bf03da2
commit b39c522cc1
12 changed files with 379 additions and 122 deletions

View File

@@ -33,7 +33,7 @@ items:
annotations: annotations:
app: nginx2 app: nginx2
config.kubernetes.io/index: '0' config.kubernetes.io/index: '0'
config.kubernetes.io/path: 'f1.json' config.kubernetes.io/path: 'f1.yaml'
spec: spec:
replicas: 1 replicas: 1
- kind: Service - kind: Service
@@ -42,7 +42,7 @@ items:
annotations: annotations:
app: nginx app: nginx
config.kubernetes.io/index: '1' config.kubernetes.io/index: '1'
config.kubernetes.io/path: 'f1.json' config.kubernetes.io/path: 'f1.yaml'
spec: spec:
selector: selector:
app: nginx app: nginx
@@ -77,13 +77,28 @@ items:
t.FailNow() t.FailNow()
} }
actual, err := ioutil.ReadFile(filepath.Join(d, "f1.json")) actual, err := ioutil.ReadFile(filepath.Join(d, "f1.yaml"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
expected := `'{"kind":"Deployment","metadata":{"annotations":{"app":"nginx2"},"labels":{"app":"nginx2"},"name":"foo"},"spec":{"replicas":1}}' expected := `kind: Deployment
metadata:
labels:
app: nginx2
name: foo
annotations:
app: nginx2
spec:
replicas: 1
--- ---
'{"kind":"Service","metadata":{"annotations":{"app":"nginx"},"name":"foo"},"spec":{"selector":{"app":"nginx"}}}' kind: Service
metadata:
name: foo
annotations:
app: nginx
spec:
selector:
app: nginx
` `
if !assert.Equal(t, expected, string(actual)) { if !assert.Equal(t, expected, string(actual)) {
t.FailNow() t.FailNow()
@@ -121,6 +136,60 @@ spec:
} }
} }
func TestSinkCommandJSON(t *testing.T) {
d, err := ioutil.TempDir("", "kustomize-source-test")
if !assert.NoError(t, err) {
t.FailNow()
}
defer os.RemoveAll(d)
r := commands.GetSinkRunner("")
r.Command.SetIn(bytes.NewBufferString(`apiVersion: config.kubernetes.io/v1alpha1
kind: ResourceList
items:
- kind: Deployment
metadata:
labels:
app: nginx2
name: foo
annotations:
app: nginx2
config.kubernetes.io/index: '0'
config.kubernetes.io/path: 'f1.json'
config.kubernetes.io/format: 'json'
spec:
replicas: 1
`))
r.Command.SetArgs([]string{d})
if !assert.NoError(t, r.Command.Execute()) {
t.FailNow()
}
actual, err := ioutil.ReadFile(filepath.Join(d, "f1.json"))
if !assert.NoError(t, err) {
t.FailNow()
}
expected := `{
"kind": "Deployment",
"metadata": {
"annotations": {
"app": "nginx2"
},
"labels": {
"app": "nginx2"
},
"name": "foo"
},
"spec": {
"replicas": 1
}
}
`
if !assert.Equal(t, expected, string(actual)) {
t.FailNow()
}
}
func TestSinkCommand_Stdout(t *testing.T) { func TestSinkCommand_Stdout(t *testing.T) {
d, err := ioutil.TempDir("", "kustomize-source-test") d, err := ioutil.TempDir("", "kustomize-source-test")
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
@@ -234,3 +303,57 @@ spec:
t.FailNow() t.FailNow()
} }
} }
func TestSinkCommandJSON_Stdout(t *testing.T) {
d, err := ioutil.TempDir("", "kustomize-source-test")
if !assert.NoError(t, err) {
t.FailNow()
}
defer os.RemoveAll(d)
// fmt the files
out := &bytes.Buffer{}
r := commands.GetSinkRunner("")
r.Command.SetIn(bytes.NewBufferString(`apiVersion: config.kubernetes.io/v1alpha1
kind: ResourceList
items:
- kind: Deployment
metadata:
labels:
app: nginx2
name: foo
annotations:
app: nginx2
config.kubernetes.io/index: '0'
config.kubernetes.io/format: 'json'
spec:
replicas: 1
`))
r.Command.SetOut(out)
r.Command.SetArgs([]string{})
if !assert.NoError(t, r.Command.Execute()) {
t.FailNow()
}
expected := `{
"kind": "Deployment",
"metadata": {
"annotations": {
"app": "nginx2"
},
"labels": {
"app": "nginx2"
},
"name": "foo"
},
"spec": {
"replicas": 1
}
}
`
if !assert.Equal(t, expected, out.String()) {
println(out.String())
t.FailNow()
}
}

View File

@@ -74,7 +74,7 @@ func (r *SourceRunner) runE(c *cobra.Command, args []string) error {
inputs = append(inputs, kio.LocalPackageReader{PackagePath: a, MatchFilesGlob: kio.MatchAll}) inputs = append(inputs, kio.LocalPackageReader{PackagePath: a, MatchFilesGlob: kio.MatchAll})
} }
if len(inputs) == 0 { if len(inputs) == 0 {
inputs = []kio.Reader{&kio.ByteReader{Reader: c.InOrStdin()}} inputs = []kio.Reader{&kio.ByteReader{Reader: c.InOrStdin(), AcceptJSON: true}}
} }
err := kio.Pipeline{Inputs: inputs, Outputs: outputs}.Execute() err := kio.Pipeline{Inputs: inputs, Outputs: outputs}.Execute()

View File

@@ -21,37 +21,25 @@ func TestSourceCommand(t *testing.T) {
} }
defer os.RemoveAll(d) defer os.RemoveAll(d)
err = ioutil.WriteFile(filepath.Join(d, "f1.json"), []byte(` err = ioutil.WriteFile(filepath.Join(d, "f1.yaml"), []byte(`
{ kind: Deployment
"kind": "Deployment", metadata:
"metadata": { labels:
"labels": { app: nginx2
"app": "nginx2" name: foo
}, annotations:
"name": "foo", app: nginx2
"annotations": { spec:
"app": "nginx2" replicas: 1
}
},
"spec": {
"replicas": 1
}
}
--- ---
{ kind: Service
"kind": "Service", metadata:
"metadata": { name: foo
"name": "foo", annotations:
"annotations": { app: nginx
"app": "nginx" spec:
} selector:
}, app: nginx
"spec": {
"selector": {
"app": "nginx"
}
}
}
`), 0600) `), 0600)
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
return return
@@ -98,22 +86,22 @@ kind: ResourceList
items: items:
- kind: Deployment - kind: Deployment
metadata: metadata:
annotations:
app: nginx2
config.kubernetes.io/index: '0'
config.kubernetes.io/path: 'f1.json'
labels: labels:
app: nginx2 app: nginx2
name: foo name: foo
annotations:
app: nginx2
config.kubernetes.io/index: '0'
config.kubernetes.io/path: 'f1.yaml'
spec: spec:
replicas: 1 replicas: 1
- kind: Service - kind: Service
metadata: metadata:
name: foo
annotations: annotations:
app: nginx app: nginx
config.kubernetes.io/index: '1' config.kubernetes.io/index: '1'
config.kubernetes.io/path: 'f1.json' config.kubernetes.io/path: 'f1.yaml'
name: foo
spec: spec:
selector: selector:
app: nginx app: nginx
@@ -147,6 +135,96 @@ items:
} }
} }
func TestSourceCommandJSON(t *testing.T) {
d, err := ioutil.TempDir("", "kustomize-source-test")
if !assert.NoError(t, err) {
return
}
defer os.RemoveAll(d)
err = ioutil.WriteFile(filepath.Join(d, "f1.json"), []byte(`
{
"kind": "Deployment",
"metadata": {
"labels": {
"app": "nginx2"
},
"name": "foo",
"annotations": {
"app": "nginx2"
}
},
"spec": {
"replicas": 1
}
}
`), 0600)
if !assert.NoError(t, err) {
return
}
err = ioutil.WriteFile(filepath.Join(d, "f2.json"), []byte(`
{
"apiVersion": "v1",
"kind": "Abstraction",
"metadata": {
"name": "foo",
"annotations": {
"config.kubernetes.io/function": "container:\n image: gcr.io/example/reconciler:v1\n",
"config.kubernetes.io/local-config": "true"
}
},
"spec": {
"replicas": 3
}
}
`), 0600)
if !assert.NoError(t, err) {
return
}
// fmt the files
b := &bytes.Buffer{}
r := commands.GetSourceRunner("")
r.Command.SetArgs([]string{d})
r.Command.SetOut(b)
if !assert.NoError(t, r.Command.Execute()) {
return
}
if !assert.Equal(t, `apiVersion: config.kubernetes.io/v1alpha1
kind: ResourceList
items:
- kind: Deployment
metadata:
annotations:
app: nginx2
config.kubernetes.io/format: 'json'
config.kubernetes.io/index: '0'
config.kubernetes.io/path: 'f1.json'
labels:
app: nginx2
name: foo
spec:
replicas: 1
- apiVersion: v1
kind: Abstraction
metadata:
annotations:
config.kubernetes.io/function: |
container:
image: gcr.io/example/reconciler:v1
config.kubernetes.io/local-config: "true"
config.kubernetes.io/format: 'json'
config.kubernetes.io/index: '0'
config.kubernetes.io/path: 'f2.json'
name: foo
spec:
replicas: 3
`, b.String()) {
return
}
}
func TestSourceCommand_Stdin(t *testing.T) { func TestSourceCommand_Stdin(t *testing.T) {
d, err := ioutil.TempDir("", "kustomize-source-test") d, err := ioutil.TempDir("", "kustomize-source-test")
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
@@ -210,3 +288,56 @@ items:
return return
} }
} }
func TestSourceCommandJSON_Stdin(t *testing.T) {
d, err := ioutil.TempDir("", "kustomize-source-test")
if !assert.NoError(t, err) {
return
}
defer os.RemoveAll(d)
in := bytes.NewBufferString(`
{
"kind": "Deployment",
"metadata": {
"labels": {
"app": "nginx2"
},
"name": "foo",
"annotations": {
"app": "nginx2"
}
},
"spec": {
"replicas": 1
}
}
`)
out := &bytes.Buffer{}
r := commands.GetSourceRunner("")
r.Command.SetArgs([]string{})
r.Command.SetIn(in)
r.Command.SetOut(out)
if !assert.NoError(t, r.Command.Execute()) {
return
}
if !assert.Equal(t, `apiVersion: config.kubernetes.io/v1alpha1
kind: ResourceList
items:
- kind: Deployment
metadata:
annotations:
app: nginx2
config.kubernetes.io/format: 'json'
config.kubernetes.io/index: '0'
labels:
app: nginx2
name: foo
spec:
replicas: 1
`, out.String()) {
return
}
}

View File

@@ -5,9 +5,9 @@ package kio
import ( import (
"bytes" "bytes"
"encoding/json"
"fmt" "fmt"
"io" "io"
"path/filepath"
"sort" "sort"
"strings" "strings"
@@ -103,11 +103,15 @@ type ByteReader struct {
// the read objects were originally wrapped in. // the read objects were originally wrapped in.
WrappingKind string WrappingKind string
// Path indicates file path which is being read // AcceptJSON indicates if the input json bytes should be processed
// empty if it is being read from stdin AcceptJSON bool
Path string
} }
const (
YAML = "yaml"
JSON = "json"
)
var _ Reader = &ByteReader{} var _ Reader = &ByteReader{}
func (r *ByteReader) Read() ([]*yaml.RNode, error) { func (r *ByteReader) Read() ([]*yaml.RNode, error) {
@@ -120,25 +124,31 @@ func (r *ByteReader) Read() ([]*yaml.RNode, error) {
if err != nil { if err != nil {
return nil, errors.Wrap(err) return nil, errors.Wrap(err)
} }
values := strings.Split(input.String(), "\n---\n") inputStr := input.String()
// check if json is accepted and if input bytes are in json format
if r.AcceptJSON && json.Valid([]byte(inputStr)) {
// convert json to yaml string to generate resource list object
// with appropriate format annotation
yamlValue, err := yaml.ConvertJSONToYAMLString(input.String())
if err != nil {
return nil, err
}
if r.SetAnnotations == nil {
r.SetAnnotations = map[string]string{}
}
if !r.OmitReaderAnnotations {
r.SetAnnotations[kioutil.FormatAnnotation] = JSON
}
inputStr = yamlValue
}
values := strings.Split(inputStr, "\n---\n")
index := 0 index := 0
for i := range values { for i := range values {
value := values[i] value := values[i]
if r.Path != "" {
for _, g := range JSONMatch {
if match, err := filepath.Match(g, filepath.Ext(r.Path)); err != nil {
return nil, errors.Wrap(err)
} else if match {
value, err = yaml.ConvertJSONToYamlString(value)
if err != nil {
return nil, err
}
}
}
}
decoder := yaml.NewDecoder(bytes.NewBufferString(value)) decoder := yaml.NewDecoder(bytes.NewBufferString(value))
node, err := r.decode(index, decoder) node, err := r.decode(index, decoder)
if err == io.EOF { if err == io.EOF {

View File

@@ -4,8 +4,8 @@
package kio package kio
import ( import (
"encoding/json"
"io" "io"
"path/filepath"
"sigs.k8s.io/kustomize/kyaml/errors" "sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/kio/kioutil" "sigs.k8s.io/kustomize/kyaml/kio/kioutil"
@@ -43,9 +43,6 @@ type ByteWriter struct {
// Sort if set, will cause ByteWriter to sort the the nodes before writing them. // Sort if set, will cause ByteWriter to sort the the nodes before writing them.
Sort bool Sort bool
// Path is the output file path to write to
Path string
} }
var _ Writer = ByteWriter{} var _ Writer = ByteWriter{}
@@ -137,20 +134,17 @@ func (w ByteWriter) Write(nodes []*yaml.RNode) error {
// encode encodes the input RNode to appropriate node format based on file path extension // encode encodes the input RNode to appropriate node format based on file path extension
func (w ByteWriter) encode(encoder *yaml.Encoder, node *yaml.RNode) error { func (w ByteWriter) encode(encoder *yaml.Encoder, node *yaml.RNode) error {
for _, g := range JSONMatch { _, _, format, err := kioutil.GetFileAnnotations(node)
if match, err := filepath.Match(g, filepath.Ext(w.Path)); err != nil { if !w.KeepReaderAnnotations {
_, err := node.Pipe(yaml.ClearAnnotation(kioutil.FormatAnnotation))
if err != nil {
return errors.Wrap(err) return errors.Wrap(err)
} else if match {
json, err := yaml.ConvertYamlNodeToJSONString(node)
if err != nil {
return errors.Wrap(err)
}
err = encoder.Encode(json)
if err != nil {
return errors.Wrap(err)
}
return nil
} }
} }
if err == nil && format == JSON {
je := json.NewEncoder(w.Writer)
je.SetIndent("", " ")
return errors.Wrap(je.Encode(node))
}
return encoder.Encode(node.Document()) return encoder.Encode(node.Document())
} }

View File

@@ -22,16 +22,20 @@ const (
// PathAnnotation records the path to the file the Resource was read from // PathAnnotation records the path to the file the Resource was read from
PathAnnotation AnnotationKey = "config.kubernetes.io/path" PathAnnotation AnnotationKey = "config.kubernetes.io/path"
// FormatAnnotation records the format of the resource ex: json
FormatAnnotation AnnotationKey = "config.kubernetes.io/format"
) )
func GetFileAnnotations(rn *yaml.RNode) (string, string, error) { func GetFileAnnotations(rn *yaml.RNode) (string, string, string, error) {
meta, err := rn.GetMeta() meta, err := rn.GetMeta()
if err != nil { if err != nil {
return "", "", err return "", "", "", err
} }
path := meta.Annotations[PathAnnotation] path := meta.Annotations[PathAnnotation]
index := meta.Annotations[IndexAnnotation] index := meta.Annotations[IndexAnnotation]
return path, index, nil format := meta.Annotations[FormatAnnotation]
return path, index, format, nil
} }
// ErrorIfMissingAnnotation validates the provided annotations are present on the given resources // ErrorIfMissingAnnotation validates the provided annotations are present on the given resources

View File

@@ -123,7 +123,7 @@ func (r *LocalPackageReadWriter) Write(nodes []*yaml.RNode) error {
func (r *LocalPackageReadWriter) getFiles(nodes []*yaml.RNode) (sets.String, error) { func (r *LocalPackageReadWriter) getFiles(nodes []*yaml.RNode) (sets.String, error) {
val := sets.String{} val := sets.String{}
for _, n := range nodes { for _, n := range nodes {
path, _, err := kioutil.GetFileAnnotations(n) path, _, _, err := kioutil.GetFileAnnotations(n)
if err != nil { if err != nil {
return nil, errors.Wrap(err) return nil, errors.Wrap(err)
} }
@@ -240,16 +240,31 @@ func (r *LocalPackageReader) readFile(path string, _ os.FileInfo) ([]*yaml.RNode
return nil, err return nil, err
} }
defer f.Close() defer f.Close()
rr := &ByteReader{ rr := &ByteReader{
DisableUnwrapping: true, DisableUnwrapping: true,
Reader: f, Reader: f,
OmitReaderAnnotations: r.OmitReaderAnnotations, OmitReaderAnnotations: r.OmitReaderAnnotations,
SetAnnotations: r.SetAnnotations, SetAnnotations: r.SetAnnotations,
Path: path, AcceptJSON: r.acceptJSON(path),
} }
return rr.Read() return rr.Read()
} }
// acceptJSON returns true if the input path has json ext and if the MatchFilesGlob
// has any of the JSONMatch ext
func (r *LocalPackageReader) acceptJSON(path string) bool {
for _, gm := range r.MatchFilesGlob {
for _, jm := range JSONMatch {
if filepath.Ext(path) == filepath.Ext(jm) &&
filepath.Ext(gm) == filepath.Ext(jm) {
return true
}
}
}
return false
}
// ShouldSkipFile returns true if the file should be skipped // ShouldSkipFile returns true if the file should be skipped
func (r *LocalPackageReader) ShouldSkipFile(info os.FileInfo) (bool, error) { func (r *LocalPackageReader) ShouldSkipFile(info os.FileInfo) (bool, error) {
// check if the files are in scope // check if the files are in scope

View File

@@ -98,7 +98,6 @@ func (r LocalPackageWriter) Write(nodes []*yaml.RNode) error {
Writer: f, Writer: f,
KeepReaderAnnotations: r.KeepReaderAnnotations, KeepReaderAnnotations: r.KeepReaderAnnotations,
ClearAnnotations: r.ClearAnnotations, ClearAnnotations: r.ClearAnnotations,
Path: outputPath,
} }
if err = w.Write(outputFiles[path]); err != nil { if err = w.Write(outputFiles[path]); err != nil {
return errors.Wrap(err) return errors.Wrap(err)

View File

@@ -183,7 +183,7 @@ func (sd SetterDefinition) Filter(object *yaml.RNode) (*yaml.RNode, error) {
} }
if sd.Schema != "" { if sd.Schema != "" {
schNode, err := yaml.ConvertJSONToYamlNode(sd.Schema) schNode, err := yaml.ConvertJSONToYAMLNode(sd.Schema)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -447,7 +447,7 @@ func SetAll(s *Set) kio.Filter {
return nil, errors.Wrap(err) return nil, errors.Wrap(err)
} }
if s.Count > preCount { if s.Count > preCount {
path, _, err := kioutil.GetFileAnnotations(nodes[i]) path, _, _, err := kioutil.GetFileAnnotations(nodes[i])
if err != nil { if err != nil {
return nil, errors.Wrap(err) return nil, errors.Wrap(err)
} }
@@ -457,7 +457,7 @@ func SetAll(s *Set) kio.Filter {
var nodesInUpdatedFiles []*yaml.RNode var nodesInUpdatedFiles []*yaml.RNode
// return only the nodes whose corresponding file has at least one node with input setter // return only the nodes whose corresponding file has at least one node with input setter
for i := range nodes { for i := range nodes {
path, _, err := kioutil.GetFileAnnotations(nodes[i]) path, _, _, err := kioutil.GetFileAnnotations(nodes[i])
if err != nil { if err != nil {
return nil, errors.Wrap(err) return nil, errors.Wrap(err)
} }

View File

@@ -722,9 +722,9 @@ func (rn *RNode) UnmarshalJSON(b []byte) error {
return nil return nil
} }
// ConvertJSONToYamlNode parses input json string and returns equivalent yaml node // ConvertJSONToYAMLNode parses input json string and returns equivalent yaml node
func ConvertJSONToYamlNode(jsonStr string) (*RNode, error) { func ConvertJSONToYAMLNode(jsonStr string) (*RNode, error) {
yml, err := ConvertJSONToYamlString(jsonStr) yml, err := ConvertJSONToYAMLString(jsonStr)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -735,8 +735,8 @@ func ConvertJSONToYamlNode(jsonStr string) (*RNode, error) {
return node, nil return node, nil
} }
// ConvertJSONToYamlString parses input json string and returns equivalent yaml string // ConvertJSONToYAMLString parses input json string and returns equivalent yaml string
func ConvertJSONToYamlString(jsonStr string) (string, error) { func ConvertJSONToYAMLString(jsonStr string) (string, error) {
var body map[string]interface{} var body map[string]interface{}
err := json.Unmarshal([]byte(jsonStr), &body) err := json.Unmarshal([]byte(jsonStr), &body)
if err != nil { if err != nil {
@@ -749,20 +749,6 @@ func ConvertJSONToYamlString(jsonStr string) (string, error) {
return string(yml), nil return string(yml), nil
} }
// ConvertYamlNodeToJSONString returns json string from input yaml RNode
func ConvertYamlNodeToJSONString(node *RNode) (string, error) {
nodeStr, err := node.String()
if err != nil {
return "", err
}
var body interface{}
if err := yaml.Unmarshal([]byte(nodeStr), &body); err != nil {
return "", err
}
res, err := json.Marshal(body)
return string(res), err
}
// checkKey returns true if all elems have the key // checkKey returns true if all elems have the key
func checkKey(key string, elems []*Node) bool { func checkKey(key string, elems []*Node) bool {
count := 0 count := 0

View File

@@ -147,7 +147,7 @@ hello: world
} }
} }
func TestConvertJSONToYamlNode(t *testing.T) { func TestConvertJSONToYAMLNode(t *testing.T) {
inputJSON := `{"type": "string", "maxLength": 15, "enum": ["allowedValue1", "allowedValue2"]}` inputJSON := `{"type": "string", "maxLength": 15, "enum": ["allowedValue1", "allowedValue2"]}`
expected := `enum: expected := `enum:
- allowedValue1 - allowedValue1
@@ -156,7 +156,7 @@ maxLength: 15
type: string type: string
` `
node, err := ConvertJSONToYamlNode(inputJSON) node, err := ConvertJSONToYAMLNode(inputJSON)
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
@@ -167,7 +167,7 @@ type: string
assert.Equal(t, expected, actual) assert.Equal(t, expected, actual)
} }
func TestConvertJSONToYamlString(t *testing.T) { func TestConvertJSONToYAMLString(t *testing.T) {
inputJSON := `{"type": "string", "maxLength": 15, "enum": ["allowedValue1", "allowedValue2"]}` inputJSON := `{"type": "string", "maxLength": 15, "enum": ["allowedValue1", "allowedValue2"]}`
expected := `enum: expected := `enum:
- allowedValue1 - allowedValue1
@@ -176,27 +176,22 @@ maxLength: 15
type: string type: string
` `
actual, err := ConvertJSONToYamlString(inputJSON) actual, err := ConvertJSONToYAMLString(inputJSON)
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
assert.Equal(t, expected, actual) assert.Equal(t, expected, actual)
} }
func TestConvertYamlNodeToJSONStr(t *testing.T) { // error if there are multiple json blobs in input string
yl := `enum: func TestConvertJSONToYAMLStringError(t *testing.T) {
- allowedValue1 inputJSON := `{"type": "string", "maxLength": 15, "enum": ["allowedValue1", "allowedValue2"]}
- allowedValue2 {"type": "string", "maxLength": 5, "enum": ["allowedValue2", "allowedValue3"]}`
maxLength: 15 expected := `invalid character '{' after top-level value`
type: string
` _, err := ConvertJSONToYAMLString(inputJSON)
node, err := Parse(yl) if !assert.Error(t, err) {
if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
res, err := ConvertYamlNodeToJSONString(node) assert.Equal(t, expected, err.Error())
if !assert.NoError(t, err) {
t.FailNow()
}
assert.Equal(t, `{"enum":["allowedValue1","allowedValue2"],"maxLength":15,"type":"string"}`, res)
} }