diff --git a/datamodel/high/v3/document.go b/datamodel/high/v3/document.go index 73823d8..90c83d9 100644 --- a/datamodel/high/v3/document.go +++ b/datamodel/high/v3/document.go @@ -16,8 +16,8 @@ import ( "github.com/pb33f/libopenapi/datamodel/high/base" low "github.com/pb33f/libopenapi/datamodel/low/v3" "github.com/pb33f/libopenapi/index" + "github.com/pb33f/libopenapi/json" "github.com/pb33f/libopenapi/orderedmap" - "github.com/pb33f/libopenapi/utils" "gopkg.in/yaml.v3" ) @@ -172,8 +172,9 @@ func (d *Document) RenderWithIndention(indent int) []byte { // RenderJSON will return a JSON representation of the Document object as a byte slice. func (d *Document) RenderJSON(indention string) []byte { - yamlData, _ := yaml.Marshal(d) - dat, _ := utils.ConvertYAMLtoJSONPretty(yamlData, "", indention) + nb := high.NewNodeBuilder(d, d.low) + + dat, _ := json.YAMLNodeToJSON(nb.Render(), indention) return dat } diff --git a/document_test.go b/document_test.go index dd328d3..c879870 100644 --- a/document_test.go +++ b/document_test.go @@ -147,98 +147,24 @@ info: assert.Equal(t, ymlModified, string(serial)) } -func TestDocument_RoundTrip(t *testing.T) { - orig := `openapi: 3.1.0 -info: - title: "The magic API" - description: | - A multi-line description - of the API. That should be retained. -tags: - - name: "Burgers" -security: - - oauth2: [] -paths: - "/test": - parameters: - - $ref: "#/components/parameters/completed_since" - post: - tags: - - "Burgers" - operationId: "test" - requestBody: - description: Callback payload - content: - 'application/json': - schema: - type: string - responses: - "200": - description: "OK" - content: - application/json: - schema: - type: object - properties: - data: - $ref: "#/components/schemas/test" - arr: - type: array - items: - $ref: "#/components/schemas/test" - callbacks: - BurgerCallback: - x-break-everything: please - "{$request.query.queryUrl}": - post: - requestBody: - description: Callback payload - content: - application/json: - schema: - type: string - responses: - '200': - description: callback successfully processes -components: - schemas: - test: - type: string - parameters: - completed_since: - in: query - name: completed_since - required: false - explode: false - schema: - example: 2012-02-22T02:06:58.158Z - format: date-time - type: string - links: - LocateBurger: - operationId: locateBurger - parameters: - burgerId: '$response.body#/id' - description: Go and get a tasty burger - securitySchemes: - oauth2: - description: |- - We require that applications designed to access the Asana API on behalf of multiple users implement OAuth 2.0. - Asana supports the Authorization Code Grant flow. - flows: - authorizationCode: - authorizationUrl: https://app.asana.com/-/oauth_authorize - refreshUrl: https://app.asana.com/-/oauth_token - scopes: - default: Provides access to all endpoints documented in our API reference. If no scopes are requested, this scope is assumed by default. - email: Provides access to the user’s email through the OpenID Connect user info endpoint. - openid: Provides access to OpenID Connect ID tokens and the OpenID Connect user info endpoint. - profile: Provides access to the user’s name and profile photo through the OpenID Connect user info endpoint. - tokenUrl: https://app.asana.com/-/oauth_token - type: oauth2 -` +func TestDocument_RoundTrip_JSON(t *testing.T) { + bs, _ := os.ReadFile("test_specs/roundtrip.json") - doc, err := NewDocument([]byte(orig)) + doc, err := NewDocument(bs) + require.NoError(t, err) + + m, errs := doc.BuildV3Model() + require.Empty(t, errs) + + out := m.Model.RenderJSON(" ") + + assert.Equal(t, string(bs), string(out)) +} + +func TestDocument_RoundTrip_YAML(t *testing.T) { + bs, _ := os.ReadFile("test_specs/roundtrip.yaml") + + doc, err := NewDocument(bs) require.NoError(t, err) _, errs := doc.BuildV3Model() @@ -247,7 +173,23 @@ components: out, err := doc.Render() require.NoError(t, err) - assert.Equal(t, orig, string(out)) + assert.Equal(t, string(bs), string(out)) +} + +func TestDocument_RoundTrip_YAML_To_JSON(t *testing.T) { + y, _ := os.ReadFile("test_specs/roundtrip.yaml") + j, _ := os.ReadFile("test_specs/roundtrip.json") + + doc, err := NewDocument(y) + require.NoError(t, err) + + m, errs := doc.BuildV3Model() + require.Empty(t, errs) + + out := m.Model.RenderJSON(" ") + require.NoError(t, err) + + assert.Equal(t, string(j), string(out)) } func TestDocument_RenderAndReload_ChangeCheck_Burgershop(t *testing.T) { diff --git a/json/json.go b/json/json.go new file mode 100644 index 0000000..e73aa56 --- /dev/null +++ b/json/json.go @@ -0,0 +1,89 @@ +package json + +import ( + "encoding/json" + "fmt" + + "github.com/pb33f/libopenapi/orderedmap" + "gopkg.in/yaml.v3" +) + +// YAMLNodeToJSON converts yaml/json stored in a yaml.Node to json ordered matching the original yaml/json +// +// NOTE: The limitation is this won't work with YAML that is not compatible with JSON, ie yaml with anchors or complex map keys +func YAMLNodeToJSON(node *yaml.Node, indentation string) ([]byte, error) { + v, err := handleYAMLNode(node) + if err != nil { + return nil, err + } + + return json.MarshalIndent(v, "", indentation) +} + +func handleYAMLNode(node *yaml.Node) (any, error) { + switch node.Kind { + case yaml.DocumentNode: + return handleYAMLNode(node.Content[0]) + case yaml.SequenceNode: + return handleSequenceNode(node) + case yaml.MappingNode: + return handleMappingNode(node) + case yaml.ScalarNode: + return handleScalarNode(node) + case yaml.AliasNode: + panic("currently unsupported") + default: + return nil, fmt.Errorf("unknown node kind: %v", node.Kind) + } +} + +func handleMappingNode(node *yaml.Node) (any, error) { + m := orderedmap.New[string, yaml.Node]() + + if err := node.Decode(m); err != nil { + return nil, err + } + + v := orderedmap.New[string, any]() + for pair := orderedmap.First(m); pair != nil; pair = pair.Next() { + n := pair.Value() + vv, err := handleYAMLNode(&n) + if err != nil { + return nil, err + } + + v.Set(pair.Key(), vv) + } + + return v, nil +} + +func handleSequenceNode(node *yaml.Node) (any, error) { + var s []yaml.Node + + if err := node.Decode(&s); err != nil { + return nil, err + } + + v := make([]any, len(s)) + for i, n := range s { + vv, err := handleYAMLNode(&n) + if err != nil { + return nil, err + } + + v[i] = vv + } + + return v, nil +} + +func handleScalarNode(node *yaml.Node) (any, error) { + var v any + + if err := node.Decode(&v); err != nil { + return nil, err + } + + return v, nil +} diff --git a/json/json_test.go b/json/json_test.go new file mode 100644 index 0000000..211b3f8 --- /dev/null +++ b/json/json_test.go @@ -0,0 +1,87 @@ +package json_test + +import ( + "testing" + + "github.com/pb33f/libopenapi/json" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gopkg.in/yaml.v3" +) + +func TestYAMLNodeToJSON(t *testing.T) { + y := `root: + key1: scalar1 + key2: + - scalar2 + - subkey1: scalar3 + subkey2: + - 1 + - 2 + - + - scalar4 + - scalar5 + key3: true` + + var v yaml.Node + + err := yaml.Unmarshal([]byte(y), &v) + require.NoError(t, err) + + j, err := json.YAMLNodeToJSON(&v, " ") + require.NoError(t, err) + + assert.Equal(t, `{ + "root": { + "key1": "scalar1", + "key2": [ + "scalar2", + { + "subkey1": "scalar3", + "subkey2": [ + 1, + 2 + ] + }, + [ + "scalar4", + "scalar5" + ] + ], + "key3": true + } +}`, string(j)) +} + +func TestYAMLNodeToJSON_FromJSON(t *testing.T) { + j := `{ + "root": { + "key1": "scalar1", + "key2": [ + "scalar2", + { + "subkey1": "scalar3", + "subkey2": [ + 1, + 2 + ] + }, + [ + "scalar4", + "scalar5" + ] + ], + "key3": true + } +}` + + var v yaml.Node + + err := yaml.Unmarshal([]byte(j), &v) + require.NoError(t, err) + + o, err := json.YAMLNodeToJSON(&v, " ") + require.NoError(t, err) + + assert.Equal(t, j, string(o)) +} diff --git a/test_specs/roundtrip.json b/test_specs/roundtrip.json new file mode 100644 index 0000000..77d941b --- /dev/null +++ b/test_specs/roundtrip.json @@ -0,0 +1,137 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "The magic API", + "description": "A multi-line description\nof the API. That should be retained.\n" + }, + "tags": [ + { + "name": "Burgers" + } + ], + "security": [ + { + "oauth2": [] + } + ], + "paths": { + "/test": { + "parameters": [ + { + "$ref": "#/components/parameters/completed_since" + } + ], + "post": { + "tags": [ + "Burgers" + ], + "operationId": "test", + "requestBody": { + "description": "Callback payload", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/test" + }, + "arr": { + "type": "array", + "items": { + "$ref": "#/components/schemas/test" + } + } + } + } + } + } + } + }, + "callbacks": { + "BurgerCallback": { + "x-break-everything": "please", + "{$request.query.queryUrl}": { + "post": { + "requestBody": { + "description": "Callback payload", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + }, + "responses": { + "200": { + "description": "callback successfully processes" + } + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "test": { + "type": "string" + } + }, + "parameters": { + "completed_since": { + "in": "query", + "name": "completed_since", + "required": false, + "explode": false, + "schema": { + "example": "2012-02-22T02:06:58.158Z", + "format": "date-time", + "type": "string" + } + } + }, + "links": { + "LocateBurger": { + "operationId": "locateBurger", + "parameters": { + "burgerId": "$response.body#/id" + }, + "description": "Go and get a tasty burger" + } + }, + "securitySchemes": { + "oauth2": { + "description": "We require that applications designed to access the Asana API on behalf of multiple users implement OAuth 2.0.\nAsana supports the Authorization Code Grant flow.", + "flows": { + "authorizationCode": { + "authorizationUrl": "https://app.asana.com/-/oauth_authorize", + "refreshUrl": "https://app.asana.com/-/oauth_token", + "scopes": { + "default": "Provides access to all endpoints documented in our API reference. If no scopes are requested, this scope is assumed by default.", + "email": "Provides access to the user’s email through the OpenID Connect user info endpoint.", + "openid": "Provides access to OpenID Connect ID tokens and the OpenID Connect user info endpoint.", + "profile": "Provides access to the user’s name and profile photo through the OpenID Connect user info endpoint." + }, + "tokenUrl": "https://app.asana.com/-/oauth_token" + } + }, + "type": "oauth2" + } + } + } +} \ No newline at end of file diff --git a/test_specs/roundtrip.yaml b/test_specs/roundtrip.yaml new file mode 100644 index 0000000..36b78cb --- /dev/null +++ b/test_specs/roundtrip.yaml @@ -0,0 +1,88 @@ +openapi: 3.1.0 +info: + title: "The magic API" + description: | + A multi-line description + of the API. That should be retained. +tags: + - name: "Burgers" +security: + - oauth2: [] +paths: + "/test": + parameters: + - $ref: "#/components/parameters/completed_since" + post: + tags: + - "Burgers" + operationId: "test" + requestBody: + description: Callback payload + content: + 'application/json': + schema: + type: string + responses: + "200": + description: "OK" + content: + application/json: + schema: + type: object + properties: + data: + $ref: "#/components/schemas/test" + arr: + type: array + items: + $ref: "#/components/schemas/test" + callbacks: + BurgerCallback: + x-break-everything: please + "{$request.query.queryUrl}": + post: + requestBody: + description: Callback payload + content: + application/json: + schema: + type: string + responses: + '200': + description: callback successfully processes +components: + schemas: + test: + type: string + parameters: + completed_since: + in: query + name: completed_since + required: false + explode: false + schema: + example: 2012-02-22T02:06:58.158Z + format: date-time + type: string + links: + LocateBurger: + operationId: locateBurger + parameters: + burgerId: '$response.body#/id' + description: Go and get a tasty burger + securitySchemes: + oauth2: + description: |- + We require that applications designed to access the Asana API on behalf of multiple users implement OAuth 2.0. + Asana supports the Authorization Code Grant flow. + flows: + authorizationCode: + authorizationUrl: https://app.asana.com/-/oauth_authorize + refreshUrl: https://app.asana.com/-/oauth_token + scopes: + default: Provides access to all endpoints documented in our API reference. If no scopes are requested, this scope is assumed by default. + email: Provides access to the user’s email through the OpenID Connect user info endpoint. + openid: Provides access to OpenID Connect ID tokens and the OpenID Connect user info endpoint. + profile: Provides access to the user’s name and profile photo through the OpenID Connect user info endpoint. + tokenUrl: https://app.asana.com/-/oauth_token + type: oauth2 diff --git a/utils/utils.go b/utils/utils.go index 1370241..67a205a 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -92,7 +92,6 @@ func FindLastChildNodeWithLevel(node *yaml.Node, level int) *yaml.Node { // BuildPath will construct a JSONPath from a base and an array of strings. func BuildPath(basePath string, segs []string) string { - path := strings.Join(segs, ".") // trim that last period. @@ -174,7 +173,6 @@ func ConvertInterfaceArrayToStringArray(raw interface{}) []string { // ExtractValueFromInterfaceMap pulls out an unknown value from a map using a string key func ExtractValueFromInterfaceMap(name string, raw interface{}) interface{} { - if propMap, ok := raw.(map[string]interface{}); ok { if props, okn := propMap[name].([]interface{}); okn { return props @@ -249,8 +247,7 @@ func FindKeyNodeTop(key string, nodes []*yaml.Node) (keyNode *yaml.Node, valueNo // FindKeyNode is a non-recursive search of a *yaml.Node Content for a child node with a key. // Returns the key and value func FindKeyNode(key string, nodes []*yaml.Node) (keyNode *yaml.Node, valueNode *yaml.Node) { - - //numNodes := len(nodes) + // numNodes := len(nodes) for i, v := range nodes { if i%2 == 0 && key == v.Value { if len(nodes) <= i+1 { @@ -337,15 +334,17 @@ func FindExtensionNodes(nodes []*yaml.Node) []*ExtensionNode { return extensions } -var ObjectLabel = "object" -var IntegerLabel = "integer" -var NumberLabel = "number" -var StringLabel = "string" -var BinaryLabel = "binary" -var ArrayLabel = "array" -var BooleanLabel = "boolean" -var SchemaSource = "https://json-schema.org/draft/2020-12/schema" -var SchemaId = "https://pb33f.io/openapi-changes/schema" +var ( + ObjectLabel = "object" + IntegerLabel = "integer" + NumberLabel = "number" + StringLabel = "string" + BinaryLabel = "binary" + ArrayLabel = "array" + BooleanLabel = "boolean" + SchemaSource = "https://json-schema.org/draft/2020-12/schema" + SchemaId = "https://pb33f.io/openapi-changes/schema" +) func MakeTagReadable(node *yaml.Node) string { switch node.Tag { @@ -465,7 +464,6 @@ func IsNodeBoolValue(node *yaml.Node) bool { } func IsNodeRefValue(node *yaml.Node) (bool, *yaml.Node, string) { - if node == nil { return false, nil, "" } @@ -483,7 +481,7 @@ func IsNodeRefValue(node *yaml.Node) (bool, *yaml.Node, string) { // FixContext will clean up a JSONpath string to be correctly traversable. func FixContext(context string) string { tokens := strings.Split(context, ".") - var cleaned = []string{} + cleaned := []string{} for i, t := range tokens { if v, err := strconv.Atoi(t); err == nil { @@ -543,19 +541,6 @@ func ConvertYAMLtoJSON(yamlData []byte) ([]byte, error) { return jsonData, nil } -// ConvertYAMLtoJSONPretty will do exactly what you think it will. It will deserialize YAML into serialized JSON. -// However, this version will apply prefix/indentation to the JSON. -func ConvertYAMLtoJSONPretty(yamlData []byte, prefix string, indent string) ([]byte, error) { - var decodedYaml map[string]interface{} - err := yaml.Unmarshal(yamlData, &decodedYaml) - if err != nil { - return nil, err - } - // if the data can be decoded, it can be encoded (that's my view anyway). no need for an error check. - jsonData, _ := json.MarshalIndent(decodedYaml, prefix, indent) - return jsonData, nil -} - // IsHttpVerb will check if an operation is valid or not. func IsHttpVerb(verb string) bool { verbs := []string{"get", "post", "put", "patch", "delete", "options", "trace", "head"} @@ -568,8 +553,10 @@ func IsHttpVerb(verb string) bool { } // define bracket name expression -var bracketNameExp = regexp.MustCompile(`^(\w+)\[(\w+)\]$`) -var pathCharExp = regexp.MustCompile(`[%=;~.]`) +var ( + bracketNameExp = regexp.MustCompile(`^(\w+)\[(\w+)\]$`) + pathCharExp = regexp.MustCompile(`[%=;~.]`) +) func ConvertComponentIdIntoFriendlyPathSearch(id string) (string, string) { segs := strings.Split(id, "/") @@ -638,7 +625,6 @@ func ConvertComponentIdIntoPath(id string) (string, string) { } func RenderCodeSnippet(startNode *yaml.Node, specData []string, before, after int) string { - buf := new(strings.Builder) startLine := startNode.Line - before diff --git a/utils/utils_test.go b/utils/utils_test.go index 028deca..97a53b8 100644 --- a/utils/utils_test.go +++ b/utils/utils_test.go @@ -13,9 +13,7 @@ type petstore []byte var once sync.Once -var ( - psBytes petstore -) +var psBytes petstore func getPetstore() petstore { once.Do(func() { @@ -101,13 +99,11 @@ func TestFindLastChildNode_TooDeep(t *testing.T) { } func TestBuildPath(t *testing.T) { - assert.Equal(t, "$.fresh.fish.and.chicken.nuggets", BuildPath("$.fresh.fish", []string{"and", "chicken", "nuggets"})) } func TestBuildPath_WithTrailingPeriod(t *testing.T) { - assert.Equal(t, "$.fresh.fish.and.chicken.nuggets", BuildPath("$.fresh.fish", []string{"and", "chicken", "nuggets", ""})) } @@ -259,7 +255,6 @@ func TestFindFirstKeyNode_TooDeep(t *testing.T) { } func TestFindFirstKeyNode_ValueIsKey(t *testing.T) { - a := &yaml.Node{ Value: "chicken", } @@ -299,7 +294,6 @@ func TestFindKeyNodeTopSingleNode(t *testing.T) { c, k := FindKeyNodeTop("chicken", []*yaml.Node{a}) assert.Equal(t, "chicken", c.Value) assert.Equal(t, "chicken", k.Value) - } func TestFindKeyNodeTop_NotFound(t *testing.T) { @@ -318,7 +312,6 @@ func TestFindKeyNode(t *testing.T) { } func TestFindKeyNodeOffByOne(t *testing.T) { - k, v := FindKeyNode("key", []*yaml.Node{ { Value: "key", @@ -331,7 +324,6 @@ func TestFindKeyNodeOffByOne(t *testing.T) { } func TestFindKeyNode_ValueIsKey(t *testing.T) { - a := &yaml.Node{ Value: "chicken", } @@ -363,11 +355,9 @@ func TestFindKeyNode_ValueIsKey(t *testing.T) { c, d = FindKeyNode("pie", []*yaml.Node{b, a}) assert.Equal(t, "nuggets", c.Value) assert.Equal(t, "pie", d.Value) - } func TestFindExtensionNodes(t *testing.T) { - a := &yaml.Node{ Value: "x-coffee", } @@ -380,11 +370,9 @@ func TestFindExtensionNodes(t *testing.T) { exts := FindExtensionNodes(c.Content) assert.Len(t, exts, 1) assert.Equal(t, "required", exts[0].Value.Value) - } func TestFindKeyNodeFull(t *testing.T) { - a := &yaml.Node{ Value: "fish", } @@ -399,7 +387,6 @@ func TestFindKeyNodeFull(t *testing.T) { } func TestFindKeyNodeFull_MapValueIsLastNode(t *testing.T) { - f := &yaml.Node{ Value: "cheese", } @@ -416,7 +403,6 @@ func TestFindKeyNodeFull_MapValueIsLastNode(t *testing.T) { } func TestFindKeyNodeFull_Map(t *testing.T) { - f := &yaml.Node{ Value: "cheese", } @@ -433,11 +419,9 @@ func TestFindKeyNodeFull_Map(t *testing.T) { assert.Equal(t, "deserts", c.Value) assert.Equal(t, "cheese", d.Value) assert.Equal(t, "cake", e.Value) - } func TestFindKeyNodeFull_Array(t *testing.T) { - f := &yaml.Node{ Value: "cheese", } @@ -454,7 +438,6 @@ func TestFindKeyNodeFull_Array(t *testing.T) { assert.Equal(t, "deserts", c.Value) assert.Equal(t, "cheese", d.Value) assert.Equal(t, "cheese", e.Value) - } func TestFindKeyNodeFull_Nothing(t *testing.T) { @@ -659,19 +642,6 @@ func TestConvertYAMLtoJSON(t *testing.T) { assert.Nil(t, str) } -func TestConvertYAMLtoJSONPretty(t *testing.T) { - str, err := ConvertYAMLtoJSONPretty([]byte("hello: there"), "", " ") - assert.NoError(t, err) - assert.NotNil(t, str) - assert.Equal(t, "{\n \"hello\": \"there\"\n}", string(str)) - -} - -func TestConvertYAMLtoJSONPrettyError(t *testing.T) { - _, err := ConvertYAMLtoJSONPretty([]byte("BAD"), "", " ") - assert.Error(t, err) -} - func TestIsHttpVerb(t *testing.T) { assert.True(t, IsHttpVerb("get")) assert.True(t, IsHttpVerb("post")) @@ -688,7 +658,6 @@ func TestConvertComponentIdIntoFriendlyPathSearch_SuperCrazy(t *testing.T) { segment, path := ConvertComponentIdIntoFriendlyPathSearch("#/paths/~1crazy~1ass~1references/get/responses/404/content/application~1xml;%20charset=utf-8/schema") assert.Equal(t, "$.paths['/crazy/ass/references'].get.responses['404'].content['application/xml; charset=utf-8'].schema", path) assert.Equal(t, "schema", segment) - } func TestConvertComponentIdIntoFriendlyPathSearch_Crazy(t *testing.T) { @@ -777,7 +746,6 @@ func TestDetectCase(t *testing.T) { } func TestIsNodeRefValue(t *testing.T) { - f := &yaml.Node{ Value: "$ref", } @@ -794,11 +762,9 @@ func TestIsNodeRefValue(t *testing.T) { assert.True(t, ref) assert.Equal(t, "$ref", node.Value) assert.Equal(t, "'#/somewhere/out-there'", val) - } func TestIsNodeAlias(t *testing.T) { - yml := `things: &anchorA - Stuff @@ -812,11 +778,9 @@ thangs: *anchorA` assert.True(t, a) assert.Len(t, ref.Content, 2) - } func TestNodeAlias(t *testing.T) { - yml := `things: &anchorA - Stuff @@ -829,7 +793,6 @@ thangs: *anchorA` ref := NodeAlias(node.Content[0].Content[3]) assert.Len(t, ref.Content, 2) - } func TestNodeAlias_Nil(t *testing.T) { @@ -838,14 +801,11 @@ func TestNodeAlias_Nil(t *testing.T) { } func TestNodeAlias_IsNodeAlias_Nil(t *testing.T) { - _, isAlias := IsNodeAlias(nil) assert.False(t, isAlias) - } func TestNodeAlias_IsNodeAlias_False(t *testing.T) { - yml := `things: - Stuff - Junk @@ -856,11 +816,9 @@ thangs: none` _, isAlias := IsNodeAlias(node.Content[0].Content[3]) assert.False(t, isAlias) - } func TestCheckForMergeNodes(t *testing.T) { - yml := `x-common-definitions: life_cycle_types: &life_cycle_types_def type: string @@ -880,7 +838,6 @@ func TestCheckForMergeNodes(t *testing.T) { assert.Equal(t, "The type of life cycle", descriptionVal.Value) assert.Len(t, enumVal.Content, 3) - } func TestCheckForMergeNodes_Empty_NoPanic(t *testing.T) { @@ -888,7 +845,6 @@ func TestCheckForMergeNodes_Empty_NoPanic(t *testing.T) { } func TestIsNodeRefValue_False(t *testing.T) { - f := &yaml.Node{ Value: "woof", } @@ -908,7 +864,6 @@ func TestIsNodeRefValue_False(t *testing.T) { } func TestIsNodeRefValue_Nil(t *testing.T) { - ref, node, val := IsNodeRefValue(nil) assert.False(t, ref) @@ -921,7 +876,6 @@ func TestCheckEnumForDuplicates_Success(t *testing.T) { var rootNode yaml.Node _ = yaml.Unmarshal([]byte(yml), &rootNode) assert.Len(t, CheckEnumForDuplicates(rootNode.Content[0].Content), 0) - } func TestCheckEnumForDuplicates_Fail(t *testing.T) { @@ -929,7 +883,6 @@ func TestCheckEnumForDuplicates_Fail(t *testing.T) { var rootNode yaml.Node _ = yaml.Unmarshal([]byte(yml), &rootNode) assert.Len(t, CheckEnumForDuplicates(rootNode.Content[0].Content), 1) - } func TestCheckEnumForDuplicates_FailMultiple(t *testing.T) {