diff --git a/datamodel/high/node_builder.go b/datamodel/high/node_builder.go index 925f2b8..19eb1b3 100644 --- a/datamodel/high/node_builder.go +++ b/datamodel/high/node_builder.go @@ -321,12 +321,10 @@ func (n *NodeBuilder) AddYAMLNode(parent *yaml.Node, entry *NodeEntry) *yaml.Nod break case reflect.Float64: - precision := -1 if entry.StringValue != "" && strings.Contains(entry.StringValue, ".") { precision = len(strings.Split(fmt.Sprint(entry.StringValue), ".")[1]) } - val := strconv.FormatFloat(value.(float64), 'f', precision, 64) valueNode = utils.CreateFloatNode(val) valueNode.Line = line diff --git a/utils/utils.go b/utils/utils.go index d686c49..b733425 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -1,307 +1,331 @@ package utils import ( - "encoding/json" - "fmt" - "net/url" - "regexp" - "strconv" - "strings" + "encoding/json" + "fmt" + "net/url" + "regexp" + "strconv" + "strings" - "github.com/vmware-labs/yaml-jsonpath/pkg/yamlpath" - "gopkg.in/yaml.v3" + "github.com/vmware-labs/yaml-jsonpath/pkg/yamlpath" + "gopkg.in/yaml.v3" ) type Case int8 const ( - // OpenApi3 is used by all OpenAPI 3+ docs - OpenApi3 = "openapi" + // OpenApi3 is used by all OpenAPI 3+ docs + OpenApi3 = "openapi" - // OpenApi2 is used by all OpenAPI 2 docs, formerly known as swagger. - OpenApi2 = "swagger" + // OpenApi2 is used by all OpenAPI 2 docs, formerly known as swagger. + OpenApi2 = "swagger" - // AsyncApi is used by akk AsyncAPI docs, all versions. - AsyncApi = "asyncapi" + // AsyncApi is used by akk AsyncAPI docs, all versions. + AsyncApi = "asyncapi" - PascalCase Case = iota - CamelCase - ScreamingSnakeCase - SnakeCase - KebabCase - ScreamingKebabCase - RegularCase - UnknownCase + PascalCase Case = iota + CamelCase + ScreamingSnakeCase + SnakeCase + KebabCase + ScreamingKebabCase + RegularCase + UnknownCase ) // FindNodes will find a node based on JSONPath, it accepts raw yaml/json as input. func FindNodes(yamlData []byte, jsonPath string) ([]*yaml.Node, error) { - jsonPath = FixContext(jsonPath) + jsonPath = FixContext(jsonPath) - var node yaml.Node - yaml.Unmarshal(yamlData, &node) + var node yaml.Node + yaml.Unmarshal(yamlData, &node) - path, err := yamlpath.NewPath(jsonPath) - if err != nil { - return nil, err - } - results, _ := path.Find(&node) - return results, nil + path, err := yamlpath.NewPath(jsonPath) + if err != nil { + return nil, err + } + results, _ := path.Find(&node) + return results, nil } +// FindLastChildNode will find the last node in a tree, based on a starting node. +// Deprecated: This function is deprecated, use FindLastChildNodeWithLevel instead. +// this has the potential to cause a stack overflow, so use with caution. It will be removed later. func FindLastChildNode(node *yaml.Node) *yaml.Node { - s := len(node.Content) - 1 - if s < 0 { - s = 0 - } - if len(node.Content) > 0 && len(node.Content[s].Content) > 0 { - return FindLastChildNode(node.Content[s]) - } else { - if len(node.Content) > 0 { - return node.Content[s] - } - return node - } + s := len(node.Content) - 1 + if s < 0 { + s = 0 + } + if len(node.Content) > 0 && len(node.Content[s].Content) > 0 { + return FindLastChildNode(node.Content[s]) + } else { + if len(node.Content) > 0 { + return node.Content[s] + } + return node + } +} + +// FindLastChildNodeWithLevel will find the last node in a tree, based on a starting node. +// Will stop searching after 100 levels, because that's just silly, we probably have a loop. +func FindLastChildNodeWithLevel(node *yaml.Node, level int) *yaml.Node { + if level > 100 { + return node // we've gone too far, give up. + } + s := len(node.Content) - 1 + if s < 0 { + s = 0 + } + if len(node.Content) > 0 && len(node.Content[s].Content) > 0 { + level++ + return FindLastChildNodeWithLevel(node.Content[s], level) + } else { + if len(node.Content) > 0 { + return node.Content[s] + } + return 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, ".") + path := strings.Join(segs, ".") - // trim that last period. - if len(path) > 0 && path[len(path)-1] == '.' { - path = path[:len(path)-1] - } - return fmt.Sprintf("%s.%s", basePath, path) + // trim that last period. + if len(path) > 0 && path[len(path)-1] == '.' { + path = path[:len(path)-1] + } + return fmt.Sprintf("%s.%s", basePath, path) } // FindNodesWithoutDeserializing will find a node based on JSONPath, without deserializing from yaml/json func FindNodesWithoutDeserializing(node *yaml.Node, jsonPath string) ([]*yaml.Node, error) { - jsonPath = FixContext(jsonPath) + jsonPath = FixContext(jsonPath) - path, err := yamlpath.NewPath(jsonPath) - if err != nil { - return nil, err - } - results, _ := path.Find(node) - return results, nil + path, err := yamlpath.NewPath(jsonPath) + if err != nil { + return nil, err + } + results, _ := path.Find(node) + return results, nil } // ConvertInterfaceIntoStringMap will convert an unknown input into a string map. func ConvertInterfaceIntoStringMap(context interface{}) map[string]string { - converted := make(map[string]string) - if context != nil { - if v, ok := context.(map[string]interface{}); ok { - for k, n := range v { - if s, okB := n.(string); okB { - converted[k] = s - } - } - } - if v, ok := context.(map[string]string); ok { - for k, n := range v { - converted[k] = n - } - } - } - return converted + converted := make(map[string]string) + if context != nil { + if v, ok := context.(map[string]interface{}); ok { + for k, n := range v { + if s, okB := n.(string); okB { + converted[k] = s + } + } + } + if v, ok := context.(map[string]string); ok { + for k, n := range v { + converted[k] = n + } + } + } + return converted } // ConvertInterfaceToStringArray will convert an unknown input map type into a string array/slice func ConvertInterfaceToStringArray(raw interface{}) []string { - if vals, ok := raw.(map[string]interface{}); ok { - var s []string - for _, v := range vals { - if g, y := v.([]interface{}); y { - for _, q := range g { - s = append(s, fmt.Sprint(q)) - } - } - } - return s - } - if vals, ok := raw.(map[string][]string); ok { - var s []string - for _, v := range vals { - s = append(s, v...) - } - return s - } - return nil + if vals, ok := raw.(map[string]interface{}); ok { + var s []string + for _, v := range vals { + if g, y := v.([]interface{}); y { + for _, q := range g { + s = append(s, fmt.Sprint(q)) + } + } + } + return s + } + if vals, ok := raw.(map[string][]string); ok { + var s []string + for _, v := range vals { + s = append(s, v...) + } + return s + } + return nil } // ConvertInterfaceArrayToStringArray will convert an unknown interface array type, into a string slice func ConvertInterfaceArrayToStringArray(raw interface{}) []string { - if vals, ok := raw.([]interface{}); ok { - s := make([]string, len(vals)) - for i, v := range vals { - s[i] = fmt.Sprint(v) - } - return s - } - if vals, ok := raw.([]string); ok { - return vals - } - return nil + if vals, ok := raw.([]interface{}); ok { + s := make([]string, len(vals)) + for i, v := range vals { + s[i] = fmt.Sprint(v) + } + return s + } + if vals, ok := raw.([]string); ok { + return vals + } + return nil } // 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 - } else { - return propMap[name] - } - } - if propMap, ok := raw.(map[string][]string); ok { - return propMap[name] - } + if propMap, ok := raw.(map[string]interface{}); ok { + if props, okn := propMap[name].([]interface{}); okn { + return props + } else { + return propMap[name] + } + } + if propMap, ok := raw.(map[string][]string); ok { + return propMap[name] + } - return nil + return nil } // FindFirstKeyNode will locate the first key and value yaml.Node based on a key. func FindFirstKeyNode(key string, nodes []*yaml.Node, depth int) (keyNode *yaml.Node, valueNode *yaml.Node) { - if depth > 40 { - return nil, nil - } - for i, v := range nodes { - if key != "" && key == v.Value { - if i+1 >= len(nodes) { - return v, nodes[i] // this is the node we need. - } - return v, nodes[i+1] // next node is what we need. - } - if len(v.Content) > 0 { - depth++ - x, y := FindFirstKeyNode(key, v.Content, depth) - if x != nil && y != nil { - return x, y - } - } - } - return nil, nil + if depth > 40 { + return nil, nil + } + for i, v := range nodes { + if key != "" && key == v.Value { + if i+1 >= len(nodes) { + return v, nodes[i] // this is the node we need. + } + return v, nodes[i+1] // next node is what we need. + } + if len(v.Content) > 0 { + depth++ + x, y := FindFirstKeyNode(key, v.Content, depth) + if x != nil && y != nil { + return x, y + } + } + } + return nil, nil } // KeyNodeResult is a result from a KeyNodeSearch performed by the FindAllKeyNodesWithPath type KeyNodeResult struct { - KeyNode *yaml.Node - ValueNode *yaml.Node - Parent *yaml.Node - Path []yaml.Node + KeyNode *yaml.Node + ValueNode *yaml.Node + Parent *yaml.Node + Path []yaml.Node } // KeyNodeSearch keeps a track of everything we have found on our adventure down the trees. type KeyNodeSearch struct { - Key string - Ignore []string - Results []*KeyNodeResult - AllowExtensions bool + Key string + Ignore []string + Results []*KeyNodeResult + AllowExtensions bool } // FindKeyNodeTop is a non-recursive search of top level nodes for a key, will not look at content. // Returns the key and value func FindKeyNodeTop(key string, nodes []*yaml.Node) (keyNode *yaml.Node, valueNode *yaml.Node) { - for i, v := range nodes { - if i%2 != 0 { - continue - } - if strings.ToLower(key) == strings.ToLower(v.Value) { - return v, nodes[i+1] // next node is what we need. - } - } - return nil, nil + for i, v := range nodes { + if i%2 != 0 { + continue + } + if strings.ToLower(key) == strings.ToLower(v.Value) { + return v, nodes[i+1] // next node is what we need. + } + } + return nil, nil } // 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) - for i, v := range nodes { - if i%2 == 0 && key == v.Value { - return v, nodes[i+1] // next node is what we need. - } - for x, j := range v.Content { - if key == j.Value { - if IsNodeMap(v) { - if x+1 == len(v.Content) { - return v, v.Content[x] - } - return v, v.Content[x+1] // next node is what we need. + //numNodes := len(nodes) + for i, v := range nodes { + if i%2 == 0 && key == v.Value { + return v, nodes[i+1] // next node is what we need. + } + for x, j := range v.Content { + if key == j.Value { + if IsNodeMap(v) { + if x+1 == len(v.Content) { + return v, v.Content[x] + } + return v, v.Content[x+1] // next node is what we need. - } - if IsNodeArray(v) { - return v, v.Content[x] - } - } - } - } - return nil, nil + } + if IsNodeArray(v) { + return v, v.Content[x] + } + } + } + } + return nil, nil } // FindKeyNodeFull is an overloaded version of FindKeyNode. This version however returns keys, labels and values. // generally different things are required from different node trees, so depending on what this function is looking at // it will return different things. func FindKeyNodeFull(key string, nodes []*yaml.Node) (keyNode *yaml.Node, labelNode *yaml.Node, valueNode *yaml.Node) { - for i := range nodes { - if i%2 == 0 && key == nodes[i].Value { - return nodes[i], nodes[i], nodes[i+1] // next node is what we need. - } - } - for _, v := range nodes { - for x := range v.Content { - if key == v.Content[x].Value { - if IsNodeMap(v) { - if x+1 == len(v.Content) { - return v, v.Content[x], v.Content[x] - } - return v, v.Content[x], v.Content[x+1] - } - if IsNodeArray(v) { - return v, v.Content[x], v.Content[x] - } - } - } - } - return nil, nil, nil + for i := range nodes { + if i%2 == 0 && key == nodes[i].Value { + return nodes[i], nodes[i], nodes[i+1] // next node is what we need. + } + } + for _, v := range nodes { + for x := range v.Content { + if key == v.Content[x].Value { + if IsNodeMap(v) { + if x+1 == len(v.Content) { + return v, v.Content[x], v.Content[x] + } + return v, v.Content[x], v.Content[x+1] + } + if IsNodeArray(v) { + return v, v.Content[x], v.Content[x] + } + } + } + } + return nil, nil, nil } // FindKeyNodeFullTop is an overloaded version of FindKeyNodeFull. This version only looks at the top // level of the node and not the children. func FindKeyNodeFullTop(key string, nodes []*yaml.Node) (keyNode *yaml.Node, labelNode *yaml.Node, valueNode *yaml.Node) { - for i := range nodes { - if i%2 != 0 { - continue - } - if i%2 == 0 && key == nodes[i].Value { - return nodes[i], nodes[i], nodes[i+1] // next node is what we need. - } - } - return nil, nil, nil + for i := range nodes { + if i%2 != 0 { + continue + } + if i%2 == 0 && key == nodes[i].Value { + return nodes[i], nodes[i], nodes[i+1] // next node is what we need. + } + } + return nil, nil, nil } type ExtensionNode struct { - Key *yaml.Node - Value *yaml.Node + Key *yaml.Node + Value *yaml.Node } func FindExtensionNodes(nodes []*yaml.Node) []*ExtensionNode { - var extensions []*ExtensionNode - for i, v := range nodes { - if i%2 == 0 && strings.HasPrefix(v.Value, "x-") { - if i+1 < len(nodes) { - extensions = append(extensions, &ExtensionNode{ - Key: v, - Value: nodes[i+1], - }) - } - } - } - return extensions + var extensions []*ExtensionNode + for i, v := range nodes { + if i%2 == 0 && strings.HasPrefix(v.Value, "x-") { + if i+1 < len(nodes) { + extensions = append(extensions, &ExtensionNode{ + Key: v, + Value: nodes[i+1], + }) + } + } + } + return extensions } var ObjectLabel = "object" @@ -315,299 +339,296 @@ var SchemaSource = "https://json-schema.org/draft/2020-12/schema" var SchemaId = "https://pb33f.io/openapi-changes/schema" func MakeTagReadable(node *yaml.Node) string { - switch node.Tag { - case "!!map": - return ObjectLabel - case "!!seq": - return ArrayLabel - case "!!str": - return StringLabel - case "!!int": - return IntegerLabel - case "!!float": - return NumberLabel - case "!!bool": - return BooleanLabel - } - return "unknown" + switch node.Tag { + case "!!map": + return ObjectLabel + case "!!seq": + return ArrayLabel + case "!!str": + return StringLabel + case "!!int": + return IntegerLabel + case "!!float": + return NumberLabel + case "!!bool": + return BooleanLabel + } + return "unknown" } // IsNodeMap checks if the node is a map type func IsNodeMap(node *yaml.Node) bool { - if node == nil { - return false - } - return node.Tag == "!!map" + if node == nil { + return false + } + return node.Tag == "!!map" } // IsNodePolyMorphic will return true if the node contains polymorphic keys. func IsNodePolyMorphic(node *yaml.Node) bool { - for i, v := range node.Content { - if i%2 == 0 { - if v.Value == "anyOf" || v.Value == "oneOf" || v.Value == "allOf" { - return true - } - } - } - return false + for i, v := range node.Content { + if i%2 == 0 { + if v.Value == "anyOf" || v.Value == "oneOf" || v.Value == "allOf" { + return true + } + } + } + return false } // IsNodeArray checks if a node is an array type func IsNodeArray(node *yaml.Node) bool { - if node == nil { - return false - } - return node.Tag == "!!seq" + if node == nil { + return false + } + return node.Tag == "!!seq" } // IsNodeStringValue checks if a node is a string value func IsNodeStringValue(node *yaml.Node) bool { - if node == nil { - return false - } - return node.Tag == "!!str" + if node == nil { + return false + } + return node.Tag == "!!str" } // IsNodeIntValue will check if a node is an int value func IsNodeIntValue(node *yaml.Node) bool { - if node == nil { - return false - } - return node.Tag == "!!int" + if node == nil { + return false + } + return node.Tag == "!!int" } // IsNodeFloatValue will check is a node is a float value. func IsNodeFloatValue(node *yaml.Node) bool { - if node == nil { - return false - } - return node.Tag == "!!float" + if node == nil { + return false + } + return node.Tag == "!!float" } // IsNodeBoolValue will check is a node is a bool func IsNodeBoolValue(node *yaml.Node) bool { - if node == nil { - return false - } - return node.Tag == "!!bool" + if node == nil { + return false + } + return node.Tag == "!!bool" } func IsNodeRefValue(node *yaml.Node) (bool, *yaml.Node, string) { - for i, r := range node.Content { - if i%2 == 0 { - if r.Value == "$ref" { - return true, r, node.Content[i+1].Value - } - } - } - return false, nil, "" + for i, r := range node.Content { + if i%2 == 0 { + if r.Value == "$ref" { + return true, r, node.Content[i+1].Value + } + } + } + return false, nil, "" } // FixContext will clean up a JSONpath string to be correctly traversable. func FixContext(context string) string { - tokens := strings.Split(context, ".") - var cleaned = []string{} + tokens := strings.Split(context, ".") + var cleaned = []string{} - for i, t := range tokens { - if v, err := strconv.Atoi(t); err == nil { - if v < 200 { // codes start here - if cleaned[i-1] != "" { - cleaned[i-1] += fmt.Sprintf("[%v]", t) - } - } else { - cleaned = append(cleaned, t) - } - continue - } - cleaned = append(cleaned, strings.ReplaceAll(t, "(root)", "$")) - } + for i, t := range tokens { + if v, err := strconv.Atoi(t); err == nil { + if v < 200 { // codes start here + if cleaned[i-1] != "" { + cleaned[i-1] += fmt.Sprintf("[%v]", t) + } + } else { + cleaned = append(cleaned, t) + } + continue + } + cleaned = append(cleaned, strings.ReplaceAll(t, "(root)", "$")) + } - return strings.Join(cleaned, ".") + return strings.Join(cleaned, ".") } // IsJSON will tell you if a string is JSON or not. func IsJSON(testString string) bool { - if testString == "" { - return false - } - runes := []rune(strings.TrimSpace(testString)) - if runes[0] == '{' && runes[len(runes)-1] == '}' { - return true - } - return false + if testString == "" { + return false + } + runes := []rune(strings.TrimSpace(testString)) + if runes[0] == '{' && runes[len(runes)-1] == '}' { + return true + } + return false } // IsYAML will tell you if a string is YAML or not. func IsYAML(testString string) bool { - if testString == "" { - return false - } - if IsJSON(testString) { - return false - } - var n interface{} - err := yaml.Unmarshal([]byte(testString), &n) - if err != nil { - return false - } - _, err = yaml.Marshal(n) - return err == nil + if testString == "" { + return false + } + if IsJSON(testString) { + return false + } + var n interface{} + err := yaml.Unmarshal([]byte(testString), &n) + if err != nil { + return false + } + _, err = yaml.Marshal(n) + return err == nil } // ConvertYAMLtoJSON will do exactly what you think it will. It will deserialize YAML into serialized JSON. func ConvertYAMLtoJSON(yamlData []byte) ([]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.Marshal(decodedYaml) - return jsonData, nil + 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.Marshal(decodedYaml) + 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"} - for _, v := range verbs { - if verb == v { - return true - } - } - return false + verbs := []string{"get", "post", "put", "patch", "delete", "options", "trace", "head"} + for _, v := range verbs { + if verb == v { + return true + } + } + return false } func ConvertComponentIdIntoFriendlyPathSearch(id string) (string, string) { - segs := strings.Split(id, "/") - name, _ := url.QueryUnescape(strings.ReplaceAll(segs[len(segs)-1], "~1", "/")) - var cleaned []string + segs := strings.Split(id, "/") + name, _ := url.QueryUnescape(strings.ReplaceAll(segs[len(segs)-1], "~1", "/")) + var cleaned []string - // check for strange spaces, chars and if found, wrap them up, clean them and create a new cleaned path. - for i := range segs { - reg, _ := regexp.MatchString("[%=;~.]", segs[i]) - if reg { - segs[i], _ = url.QueryUnescape(strings.ReplaceAll(segs[i], "~1", "/")) - segs[i] = fmt.Sprintf("['%s']", segs[i]) - if len(cleaned) > 0 { - cleaned[len(cleaned)-1] = fmt.Sprintf("%s%s", segs[i-1], segs[i]) - continue - } - } else { - intVal, err := strconv.ParseInt(segs[i], 10, 32) - if err == nil && intVal <= 99 { - segs[i] = fmt.Sprintf("[%d]", intVal) - cleaned[len(cleaned)-1] = fmt.Sprintf("%s%s", cleaned[len(cleaned)-1], segs[i]) - continue - } - if err == nil && intVal > 99 { - segs[i] = fmt.Sprintf("['%d']", intVal) - cleaned[len(cleaned)-1] = fmt.Sprintf("%s%s", cleaned[len(cleaned)-1], segs[i]) - continue - } - cleaned = append(cleaned, segs[i]) - } - } - _, err := strconv.ParseInt(name, 10, 32) - var replaced string - if err != nil { - replaced = strings.ReplaceAll(fmt.Sprintf("%s", - strings.Join(cleaned, ".")), "#", "$") - } else { - replaced = strings.ReplaceAll(fmt.Sprintf("%s", - strings.Join(cleaned, ".")), "#", "$") - } + // check for strange spaces, chars and if found, wrap them up, clean them and create a new cleaned path. + for i := range segs { + reg, _ := regexp.MatchString("[%=;~.]", segs[i]) + if reg { + segs[i], _ = url.QueryUnescape(strings.ReplaceAll(segs[i], "~1", "/")) + segs[i] = fmt.Sprintf("['%s']", segs[i]) + if len(cleaned) > 0 { + cleaned[len(cleaned)-1] = fmt.Sprintf("%s%s", segs[i-1], segs[i]) + continue + } + } else { + intVal, err := strconv.ParseInt(segs[i], 10, 32) + if err == nil && intVal <= 99 { + segs[i] = fmt.Sprintf("[%d]", intVal) + cleaned[len(cleaned)-1] = fmt.Sprintf("%s%s", cleaned[len(cleaned)-1], segs[i]) + continue + } + if err == nil && intVal > 99 { + segs[i] = fmt.Sprintf("['%d']", intVal) + cleaned[len(cleaned)-1] = fmt.Sprintf("%s%s", cleaned[len(cleaned)-1], segs[i]) + continue + } + cleaned = append(cleaned, segs[i]) + } + } + _, err := strconv.ParseInt(name, 10, 32) + var replaced string + if err != nil { + replaced = strings.ReplaceAll(fmt.Sprintf("%s", + strings.Join(cleaned, ".")), "#", "$") + } else { + replaced = strings.ReplaceAll(fmt.Sprintf("%s", + strings.Join(cleaned, ".")), "#", "$") + } - if len(replaced) > 0 { - if replaced[0] != '$' { - replaced = fmt.Sprintf("$%s", replaced) - } - } - return name, replaced + if len(replaced) > 0 { + if replaced[0] != '$' { + replaced = fmt.Sprintf("$%s", replaced) + } + } + return name, replaced } func ConvertComponentIdIntoPath(id string) (string, string) { - segs := strings.Split(id, "/") - name := segs[len(segs)-1] + segs := strings.Split(id, "/") + name := segs[len(segs)-1] - return name, strings.ReplaceAll(fmt.Sprintf("%s.%s", - strings.Join(segs[:len(segs)-1], "."), name), "#", "$") + return name, strings.ReplaceAll(fmt.Sprintf("%s.%s", + strings.Join(segs[:len(segs)-1], "."), name), "#", "$") } func RenderCodeSnippet(startNode *yaml.Node, specData []string, before, after int) string { - buf := new(strings.Builder) + buf := new(strings.Builder) - startLine := startNode.Line - before - endLine := startNode.Line + after + startLine := startNode.Line - before + endLine := startNode.Line + after - if startLine < 0 { - startLine = 0 - } + if startLine < 0 { + startLine = 0 + } - if endLine >= len(specData) { - endLine = len(specData) - 1 - } + if endLine >= len(specData) { + endLine = len(specData) - 1 + } - delta := endLine - startLine + delta := endLine - startLine - for i := 0; i < delta; i++ { - l := startLine + i - if l < len(specData) { - line := specData[l] - buf.WriteString(fmt.Sprintf("%s\n", line)) - } - } + for i := 0; i < delta; i++ { + l := startLine + i + if l < len(specData) { + line := specData[l] + buf.WriteString(fmt.Sprintf("%s\n", line)) + } + } - return buf.String() + return buf.String() } func DetectCase(input string) Case { - trim := strings.TrimSpace(input) - if trim == "" { - return UnknownCase - } + trim := strings.TrimSpace(input) + if trim == "" { + return UnknownCase + } - pascalCase := regexp.MustCompile("^[A-Z][a-z]+(?:[A-Z][a-z]+)*$") - camelCase := regexp.MustCompile("^[a-z]+(?:[A-Z][a-z]+)*$") - screamingSnakeCase := regexp.MustCompile("^[A-Z]+(_[A-Z]+)*$") - snakeCase := regexp.MustCompile("^[a-z]+(_[a-z]+)*$") - kebabCase := regexp.MustCompile("^[a-z]+(-[a-z]+)*$") - screamingKebabCase := regexp.MustCompile("^[A-Z]+(-[A-Z]+)*$") - if pascalCase.MatchString(trim) { - return PascalCase - } - if camelCase.MatchString(trim) { - return CamelCase - } - if screamingSnakeCase.MatchString(trim) { - return ScreamingSnakeCase - } - if snakeCase.MatchString(trim) { - return SnakeCase - } - if kebabCase.MatchString(trim) { - return KebabCase - } - if screamingKebabCase.MatchString(trim) { - return ScreamingKebabCase - } - return RegularCase + pascalCase := regexp.MustCompile("^[A-Z][a-z]+(?:[A-Z][a-z]+)*$") + camelCase := regexp.MustCompile("^[a-z]+(?:[A-Z][a-z]+)*$") + screamingSnakeCase := regexp.MustCompile("^[A-Z]+(_[A-Z]+)*$") + snakeCase := regexp.MustCompile("^[a-z]+(_[a-z]+)*$") + kebabCase := regexp.MustCompile("^[a-z]+(-[a-z]+)*$") + screamingKebabCase := regexp.MustCompile("^[A-Z]+(-[A-Z]+)*$") + if pascalCase.MatchString(trim) { + return PascalCase + } + if camelCase.MatchString(trim) { + return CamelCase + } + if screamingSnakeCase.MatchString(trim) { + return ScreamingSnakeCase + } + if snakeCase.MatchString(trim) { + return SnakeCase + } + if kebabCase.MatchString(trim) { + return KebabCase + } + if screamingKebabCase.MatchString(trim) { + return ScreamingKebabCase + } + return RegularCase } // CheckEnumForDuplicates will check an array of nodes to check if there are any duplicate values. func CheckEnumForDuplicates(seq []*yaml.Node) []*yaml.Node { - var res []*yaml.Node - seen := make(map[string]*yaml.Node) + var res []*yaml.Node + seen := make(map[string]*yaml.Node) - for _, enum := range seq { - if seen[enum.Value] != nil { - res = append(res, enum) - continue - } - seen[enum.Value] = enum - } - return res + for _, enum := range seq { + if seen[enum.Value] != nil { + res = append(res, enum) + continue + } + seen[enum.Value] = enum + } + return res } - - - diff --git a/utils/utils_test.go b/utils/utils_test.go index f430d3e..57ec358 100644 --- a/utils/utils_test.go +++ b/utils/utils_test.go @@ -1,11 +1,11 @@ package utils import ( - "github.com/stretchr/testify/assert" - "gopkg.in/yaml.v3" - "io/ioutil" - "sync" - "testing" + "github.com/stretchr/testify/assert" + "gopkg.in/yaml.v3" + "io/ioutil" + "sync" + "testing" ) type petstore []byte @@ -13,745 +13,770 @@ type petstore []byte var once sync.Once var ( - psBytes petstore + psBytes petstore ) func getPetstore() petstore { - once.Do(func() { - psBytes, _ = ioutil.ReadFile("../test_specs/petstorev3.json") - }) - return psBytes + once.Do(func() { + psBytes, _ = ioutil.ReadFile("../test_specs/petstorev3.json") + }) + return psBytes } func TestRenderCodeSnippet(t *testing.T) { - code := []string{"hey", "ho", "let's", "go!"} - startNode := &yaml.Node{ - Line: 1, - } - rendered := RenderCodeSnippet(startNode, code, 1, 3) - assert.Equal(t, "hey\nho\nlet's\n", rendered) + code := []string{"hey", "ho", "let's", "go!"} + startNode := &yaml.Node{ + Line: 1, + } + rendered := RenderCodeSnippet(startNode, code, 1, 3) + assert.Equal(t, "hey\nho\nlet's\n", rendered) } func TestRenderCodeSnippet_BelowStart(t *testing.T) { - code := []string{"hey", "ho", "let's", "go!"} - startNode := &yaml.Node{ - Line: 0, - } - rendered := RenderCodeSnippet(startNode, code, 1, 3) - assert.Equal(t, "hey\nho\nlet's\n", rendered) + code := []string{"hey", "ho", "let's", "go!"} + startNode := &yaml.Node{ + Line: 0, + } + rendered := RenderCodeSnippet(startNode, code, 1, 3) + assert.Equal(t, "hey\nho\nlet's\n", rendered) } func TestFindNodes(t *testing.T) { - nodes, err := FindNodes(getPetstore(), "$.info.contact") - assert.NoError(t, err) - assert.NotNil(t, nodes) - assert.Len(t, nodes, 1) + nodes, err := FindNodes(getPetstore(), "$.info.contact") + assert.NoError(t, err) + assert.NotNil(t, nodes) + assert.Len(t, nodes, 1) } func TestFindNodes_BadPath(t *testing.T) { - nodes, err := FindNodes(getPetstore(), "I am not valid") - assert.Error(t, err) - assert.Nil(t, nodes) + nodes, err := FindNodes(getPetstore(), "I am not valid") + assert.Error(t, err) + assert.Nil(t, nodes) } func TestFindLastChildNode(t *testing.T) { - nodes, _ := FindNodes(getPetstore(), "$.info") - lastNode := FindLastChildNode(nodes[0]) - assert.Equal(t, "1.0.11", lastNode.Value) // should be the version. + nodes, _ := FindNodes(getPetstore(), "$.info") + lastNode := FindLastChildNode(nodes[0]) + assert.Equal(t, "1.0.11", lastNode.Value) // should be the version. + lastNodeDouble := FindLastChildNodeWithLevel(nodes[0], 0) + assert.Equal(t, lastNode, lastNodeDouble) } func TestFindLastChildNode_WithKids(t *testing.T) { - nodes, _ := FindNodes(getPetstore(), "$.paths./pet") - lastNode := FindLastChildNode(nodes[0]) - assert.Equal(t, "read:pets", lastNode.Value) + nodes, _ := FindNodes(getPetstore(), "$.paths./pet") + lastNode := FindLastChildNode(nodes[0]) + lastNodeDouble := FindLastChildNodeWithLevel(nodes[0], 0) + assert.Equal(t, lastNode, lastNodeDouble) + assert.Equal(t, "read:pets", lastNode.Value) } func TestFindLastChildNode_NotFound(t *testing.T) { - node := &yaml.Node{ - Value: "same", - } - lastNode := FindLastChildNode(node) - assert.Equal(t, "same", lastNode.Value) // should be the same node + node := &yaml.Node{ + Value: "same", + } + lastNode := FindLastChildNode(node) + assert.Equal(t, "same", lastNode.Value) // should be the same node + lastNodeDouble := FindLastChildNodeWithLevel(node, 0) + assert.Equal(t, lastNode, lastNodeDouble) +} + +func genLoop(count int) *yaml.Node { + if count > 200 { + return nil + } + count++ + return &yaml.Node{ + Value: "same", + Content: []*yaml.Node{ + genLoop(count), + }, + } +} + +func TestFindLastChildNode_TooDeep(t *testing.T) { + node := genLoop(0) + lastNodeDouble := FindLastChildNodeWithLevel(node, 0) + assert.NotNil(t, lastNodeDouble) } func TestBuildPath(t *testing.T) { - assert.Equal(t, "$.fresh.fish.and.chicken.nuggets", - BuildPath("$.fresh.fish", []string{"and", "chicken", "nuggets"})) + 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", ""})) + assert.Equal(t, "$.fresh.fish.and.chicken.nuggets", + BuildPath("$.fresh.fish", []string{"and", "chicken", "nuggets", ""})) } func TestFindNodesWithoutDeserializing(t *testing.T) { - root, _ := FindNodes(getPetstore(), "$") - nodes, err := FindNodesWithoutDeserializing(root[0], "$.info.contact") - assert.NoError(t, err) - assert.NotNil(t, nodes) - assert.Len(t, nodes, 1) + root, _ := FindNodes(getPetstore(), "$") + nodes, err := FindNodesWithoutDeserializing(root[0], "$.info.contact") + assert.NoError(t, err) + assert.NotNil(t, nodes) + assert.Len(t, nodes, 1) } func TestFindNodesWithoutDeserializing_InvalidPath(t *testing.T) { - root, _ := FindNodes(getPetstore(), "$") - nodes, err := FindNodesWithoutDeserializing(root[0], "I love a good curry") - assert.Error(t, err) - assert.Nil(t, nodes) + root, _ := FindNodes(getPetstore(), "$") + nodes, err := FindNodesWithoutDeserializing(root[0], "I love a good curry") + assert.Error(t, err) + assert.Nil(t, nodes) } func TestConvertInterfaceIntoStringMap(t *testing.T) { - var d interface{} - n := make(map[string]string) - n["melody"] = "baby girl" - d = n - parsed := ConvertInterfaceIntoStringMap(d) - assert.Equal(t, "baby girl", parsed["melody"]) + var d interface{} + n := make(map[string]string) + n["melody"] = "baby girl" + d = n + parsed := ConvertInterfaceIntoStringMap(d) + assert.Equal(t, "baby girl", parsed["melody"]) } func TestConvertInterfaceIntoStringMap_NoType(t *testing.T) { - var d interface{} - n := make(map[string]interface{}) - n["melody"] = "baby girl" - d = n - parsed := ConvertInterfaceIntoStringMap(d) - assert.Equal(t, "baby girl", parsed["melody"]) + var d interface{} + n := make(map[string]interface{}) + n["melody"] = "baby girl" + d = n + parsed := ConvertInterfaceIntoStringMap(d) + assert.Equal(t, "baby girl", parsed["melody"]) } func TestConvertInterfaceToStringArray(t *testing.T) { - var d interface{} - n := make(map[string][]string) - n["melody"] = []string{"melody", "is", "my", "baby"} - d = n - parsed := ConvertInterfaceToStringArray(d) - assert.Equal(t, "baby", parsed[3]) + var d interface{} + n := make(map[string][]string) + n["melody"] = []string{"melody", "is", "my", "baby"} + d = n + parsed := ConvertInterfaceToStringArray(d) + assert.Equal(t, "baby", parsed[3]) } func TestConvertInterfaceToStringArray_NoType(t *testing.T) { - var d interface{} - m := make([]interface{}, 4) - n := make(map[string]interface{}) - m[0] = "melody" - m[1] = "is" - m[2] = "my" - m[3] = "baby" - n["melody"] = m - d = n - parsed := ConvertInterfaceToStringArray(d) - assert.Equal(t, "baby", parsed[3]) + var d interface{} + m := make([]interface{}, 4) + n := make(map[string]interface{}) + m[0] = "melody" + m[1] = "is" + m[2] = "my" + m[3] = "baby" + n["melody"] = m + d = n + parsed := ConvertInterfaceToStringArray(d) + assert.Equal(t, "baby", parsed[3]) } func TestConvertInterfaceToStringArray_Invalid(t *testing.T) { - var d interface{} - d = "I am a carrot" - parsed := ConvertInterfaceToStringArray(d) - assert.Nil(t, parsed) + var d interface{} + d = "I am a carrot" + parsed := ConvertInterfaceToStringArray(d) + assert.Nil(t, parsed) } func TestConvertInterfaceArrayToStringArray(t *testing.T) { - var d interface{} - m := []string{"maddox", "is", "my", "little", "champion"} - d = m - parsed := ConvertInterfaceArrayToStringArray(d) - assert.Equal(t, "little", parsed[3]) + var d interface{} + m := []string{"maddox", "is", "my", "little", "champion"} + d = m + parsed := ConvertInterfaceArrayToStringArray(d) + assert.Equal(t, "little", parsed[3]) } func TestConvertInterfaceArrayToStringArray_NoType(t *testing.T) { - var d interface{} - m := make([]interface{}, 4) - m[0] = "melody" - m[1] = "is" - m[2] = "my" - m[3] = "baby" - d = m - parsed := ConvertInterfaceArrayToStringArray(d) - assert.Equal(t, "baby", parsed[3]) + var d interface{} + m := make([]interface{}, 4) + m[0] = "melody" + m[1] = "is" + m[2] = "my" + m[3] = "baby" + d = m + parsed := ConvertInterfaceArrayToStringArray(d) + assert.Equal(t, "baby", parsed[3]) } func TestConvertInterfaceArrayToStringArray_Invalid(t *testing.T) { - var d interface{} - d = "weed is good" - parsed := ConvertInterfaceArrayToStringArray(d) - assert.Nil(t, parsed) + var d interface{} + d = "weed is good" + parsed := ConvertInterfaceArrayToStringArray(d) + assert.Nil(t, parsed) } func TestExtractValueFromInterfaceMap(t *testing.T) { - var d interface{} - m := make(map[string][]string) - m["melody"] = []string{"is", "my", "baby"} - d = m - parsed := ExtractValueFromInterfaceMap("melody", d) - assert.Equal(t, "baby", parsed.([]string)[2]) + var d interface{} + m := make(map[string][]string) + m["melody"] = []string{"is", "my", "baby"} + d = m + parsed := ExtractValueFromInterfaceMap("melody", d) + assert.Equal(t, "baby", parsed.([]string)[2]) } func TestExtractValueFromInterfaceMap_NoType(t *testing.T) { - var d interface{} - m := make(map[string]interface{}) - n := make([]interface{}, 3) - n[0] = "maddy" - n[1] = "the" - n[2] = "champion" - m["maddy"] = n - d = m - parsed := ExtractValueFromInterfaceMap("maddy", d) - assert.Equal(t, "champion", parsed.([]interface{})[2]) + var d interface{} + m := make(map[string]interface{}) + n := make([]interface{}, 3) + n[0] = "maddy" + n[1] = "the" + n[2] = "champion" + m["maddy"] = n + d = m + parsed := ExtractValueFromInterfaceMap("maddy", d) + assert.Equal(t, "champion", parsed.([]interface{})[2]) } func TestExtractValueFromInterfaceMap_Flat(t *testing.T) { - var d interface{} - m := make(map[string]interface{}) - m["maddy"] = "niblet" - d = m - parsed := ExtractValueFromInterfaceMap("maddy", d) - assert.Equal(t, "niblet", parsed.(interface{})) + var d interface{} + m := make(map[string]interface{}) + m["maddy"] = "niblet" + d = m + parsed := ExtractValueFromInterfaceMap("maddy", d) + assert.Equal(t, "niblet", parsed.(interface{})) } func TestExtractValueFromInterfaceMap_NotFound(t *testing.T) { - var d interface{} - d = "not a map" - parsed := ExtractValueFromInterfaceMap("melody", d) - assert.Nil(t, parsed) + var d interface{} + d = "not a map" + parsed := ExtractValueFromInterfaceMap("melody", d) + assert.Nil(t, parsed) } func TestFindFirstKeyNode(t *testing.T) { - nodes, _ := FindNodes(getPetstore(), "$") - key, value := FindFirstKeyNode("operationId", nodes, 0) - assert.NotNil(t, key) - assert.NotNil(t, value) - assert.Equal(t, 55, key.Line) + nodes, _ := FindNodes(getPetstore(), "$") + key, value := FindFirstKeyNode("operationId", nodes, 0) + assert.NotNil(t, key) + assert.NotNil(t, value) + assert.Equal(t, 55, key.Line) } func TestFindFirstKeyNode_NotFound(t *testing.T) { - nodes, _ := FindNodes(getPetstore(), "$") - key, value := FindFirstKeyNode("i-do-not-exist-in-the-doc", nodes, 0) - assert.Nil(t, key) - assert.Nil(t, value) + nodes, _ := FindNodes(getPetstore(), "$") + key, value := FindFirstKeyNode("i-do-not-exist-in-the-doc", nodes, 0) + assert.Nil(t, key) + assert.Nil(t, value) } func TestFindFirstKeyNode_TooDeep(t *testing.T) { - a, b := FindFirstKeyNode("", nil, 900) - assert.Nil(t, a) - assert.Nil(t, b) + a, b := FindFirstKeyNode("", nil, 900) + assert.Nil(t, a) + assert.Nil(t, b) } func TestFindFirstKeyNode_ValueIsKey(t *testing.T) { - a := &yaml.Node{ - Value: "chicken", - } + a := &yaml.Node{ + Value: "chicken", + } - b := &yaml.Node{ - Value: "nuggets", - Content: []*yaml.Node{a}, - } + b := &yaml.Node{ + Value: "nuggets", + Content: []*yaml.Node{a}, + } - c, d := FindFirstKeyNode("nuggets", []*yaml.Node{b}, 0) - assert.NotNil(t, c) - assert.NotNil(t, d) - assert.Equal(t, c, d) + c, d := FindFirstKeyNode("nuggets", []*yaml.Node{b}, 0) + assert.NotNil(t, c) + assert.NotNil(t, d) + assert.Equal(t, c, d) } func TestFindFirstKeyNode_Map(t *testing.T) { - nodes, _ := FindNodes(getPetstore(), "$") - key, value := FindFirstKeyNode("pet", nodes, 0) - assert.NotNil(t, key) - assert.NotNil(t, value) - assert.Equal(t, 27, key.Line) + nodes, _ := FindNodes(getPetstore(), "$") + key, value := FindFirstKeyNode("pet", nodes, 0) + assert.NotNil(t, key) + assert.NotNil(t, value) + assert.Equal(t, 27, key.Line) } func TestFindKeyNodeTop(t *testing.T) { - nodes, _ := FindNodes(getPetstore(), "$") - k, v := FindKeyNodeTop("info", nodes[0].Content) - assert.NotNil(t, k) - assert.NotNil(t, v) - assert.Equal(t, 3, k.Line) + nodes, _ := FindNodes(getPetstore(), "$") + k, v := FindKeyNodeTop("info", nodes[0].Content) + assert.NotNil(t, k) + assert.NotNil(t, v) + assert.Equal(t, 3, k.Line) } func TestFindKeyNodeTop_NotFound(t *testing.T) { - nodes, _ := FindNodes(getPetstore(), "$") - k, v := FindKeyNodeTop("i am a giant potato", nodes[0].Content) - assert.Nil(t, k) - assert.Nil(t, v) + nodes, _ := FindNodes(getPetstore(), "$") + k, v := FindKeyNodeTop("i am a giant potato", nodes[0].Content) + assert.Nil(t, k) + assert.Nil(t, v) } func TestFindKeyNode(t *testing.T) { - nodes, _ := FindNodes(getPetstore(), "$") - k, v := FindKeyNode("/pet", nodes[0].Content) - assert.NotNil(t, k) - assert.NotNil(t, v) - assert.Equal(t, 47, k.Line) + nodes, _ := FindNodes(getPetstore(), "$") + k, v := FindKeyNode("/pet", nodes[0].Content) + assert.NotNil(t, k) + assert.NotNil(t, v) + assert.Equal(t, 47, k.Line) } func TestFindKeyNode_ValueIsKey(t *testing.T) { - a := &yaml.Node{ - Value: "chicken", - } + a := &yaml.Node{ + Value: "chicken", + } - b := &yaml.Node{ - Tag: "!!map", - Value: "nuggets", - Content: []*yaml.Node{a}, - } + b := &yaml.Node{ + Tag: "!!map", + Value: "nuggets", + Content: []*yaml.Node{a}, + } - c, d := FindKeyNode("nuggets", []*yaml.Node{b, a}) - assert.Equal(t, "nuggets", c.Value) - assert.Equal(t, "chicken", d.Value) + c, d := FindKeyNode("nuggets", []*yaml.Node{b, a}) + assert.Equal(t, "nuggets", c.Value) + assert.Equal(t, "chicken", d.Value) - e := &yaml.Node{ - Value: "pizza", - } - f := &yaml.Node{ - Value: "pie", - } - b.Content = append(b.Content, e, f) + e := &yaml.Node{ + Value: "pizza", + } + f := &yaml.Node{ + Value: "pie", + } + b.Content = append(b.Content, e, f) - c, d = FindKeyNode("pie", []*yaml.Node{b, a}) - assert.Equal(t, "nuggets", c.Value) - assert.Equal(t, "pie", d.Value) + c, d = FindKeyNode("pie", []*yaml.Node{b, a}) + assert.Equal(t, "nuggets", c.Value) + assert.Equal(t, "pie", d.Value) - b.Tag = "!!seq" + b.Tag = "!!seq" - c, d = FindKeyNode("pie", []*yaml.Node{b, a}) - assert.Equal(t, "nuggets", c.Value) - assert.Equal(t, "pie", d.Value) + 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", - } - b := &yaml.Node{ - Value: "required", - } - c := &yaml.Node{ - Content: []*yaml.Node{a, b}, - } - exts := FindExtensionNodes(c.Content) - assert.Len(t, exts, 1) - assert.Equal(t, "required", exts[0].Value.Value) + a := &yaml.Node{ + Value: "x-coffee", + } + b := &yaml.Node{ + Value: "required", + } + c := &yaml.Node{ + Content: []*yaml.Node{a, b}, + } + 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", - } - b := &yaml.Node{ - Value: "paste", - } + a := &yaml.Node{ + Value: "fish", + } + b := &yaml.Node{ + Value: "paste", + } - c, d, e := FindKeyNodeFull("fish", []*yaml.Node{a, b}) - assert.Equal(t, "fish", c.Value) - assert.Equal(t, "fish", d.Value) - assert.Equal(t, "paste", e.Value) + c, d, e := FindKeyNodeFull("fish", []*yaml.Node{a, b}) + assert.Equal(t, "fish", c.Value) + assert.Equal(t, "fish", d.Value) + assert.Equal(t, "paste", e.Value) } func TestFindKeyNodeFull_MapValueIsLastNode(t *testing.T) { - f := &yaml.Node{ - Value: "cheese", - } - h := &yaml.Node{ - Tag: "!!map", - Value: "deserts", // this is invalid btw, but helps with mechanical understanding - Content: []*yaml.Node{f}, - } + f := &yaml.Node{ + Value: "cheese", + } + h := &yaml.Node{ + Tag: "!!map", + Value: "deserts", // this is invalid btw, but helps with mechanical understanding + Content: []*yaml.Node{f}, + } - c, d, e := FindKeyNodeFull("cheese", []*yaml.Node{h}) - assert.Equal(t, "deserts", c.Value) - assert.Equal(t, "cheese", d.Value) - assert.Equal(t, "cheese", e.Value) + c, d, e := FindKeyNodeFull("cheese", []*yaml.Node{h}) + assert.Equal(t, "deserts", c.Value) + assert.Equal(t, "cheese", d.Value) + assert.Equal(t, "cheese", e.Value) } func TestFindKeyNodeFull_Map(t *testing.T) { - f := &yaml.Node{ - Value: "cheese", - } - g := &yaml.Node{ - Value: "cake", - } - h := &yaml.Node{ - Tag: "!!map", - Value: "deserts", // this is invalid btw, but helps with mechanical understanding - Content: []*yaml.Node{f, g}, - } + f := &yaml.Node{ + Value: "cheese", + } + g := &yaml.Node{ + Value: "cake", + } + h := &yaml.Node{ + Tag: "!!map", + Value: "deserts", // this is invalid btw, but helps with mechanical understanding + Content: []*yaml.Node{f, g}, + } - c, d, e := FindKeyNodeFull("cheese", []*yaml.Node{h}) - assert.Equal(t, "deserts", c.Value) - assert.Equal(t, "cheese", d.Value) - assert.Equal(t, "cake", e.Value) + c, d, e := FindKeyNodeFull("cheese", []*yaml.Node{h}) + 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", - } - g := &yaml.Node{ - Value: "cake", - } - h := &yaml.Node{ - Tag: "!!seq", - Value: "deserts", // this is invalid btw, but helps with mechanical understanding - Content: []*yaml.Node{f, g}, - } + f := &yaml.Node{ + Value: "cheese", + } + g := &yaml.Node{ + Value: "cake", + } + h := &yaml.Node{ + Tag: "!!seq", + Value: "deserts", // this is invalid btw, but helps with mechanical understanding + Content: []*yaml.Node{f, g}, + } - c, d, e := FindKeyNodeFull("cheese", []*yaml.Node{h}) - assert.Equal(t, "deserts", c.Value) - assert.Equal(t, "cheese", d.Value) - assert.Equal(t, "cheese", e.Value) + c, d, e := FindKeyNodeFull("cheese", []*yaml.Node{h}) + assert.Equal(t, "deserts", c.Value) + assert.Equal(t, "cheese", d.Value) + assert.Equal(t, "cheese", e.Value) } func TestFindKeyNodeFull_Nothing(t *testing.T) { - c, d, e := FindKeyNodeFull("cheese", []*yaml.Node{}) - assert.Nil(t, c) - assert.Nil(t, d) - assert.Nil(t, e) + c, d, e := FindKeyNodeFull("cheese", []*yaml.Node{}) + assert.Nil(t, c) + assert.Nil(t, d) + assert.Nil(t, e) } func TestFindKeyNode_NotFound(t *testing.T) { - nodes, _ := FindNodes(getPetstore(), "$") - k, v := FindKeyNode("I am not anything at all", nodes[0].Content) - assert.Nil(t, k) - assert.Nil(t, v) + nodes, _ := FindNodes(getPetstore(), "$") + k, v := FindKeyNode("I am not anything at all", nodes[0].Content) + assert.Nil(t, k) + assert.Nil(t, v) } func TestFindKeyFullNodeTop(t *testing.T) { - a := &yaml.Node{ - Value: "fish", - } - b := &yaml.Node{ - Value: "paste", - } + a := &yaml.Node{ + Value: "fish", + } + b := &yaml.Node{ + Value: "paste", + } - c, d, e := FindKeyNodeFullTop("fish", []*yaml.Node{a, b}) - assert.Equal(t, "fish", c.Value) - assert.Equal(t, "fish", d.Value) - assert.Equal(t, "paste", e.Value) + c, d, e := FindKeyNodeFullTop("fish", []*yaml.Node{a, b}) + assert.Equal(t, "fish", c.Value) + assert.Equal(t, "fish", d.Value) + assert.Equal(t, "paste", e.Value) } func TestFindKeyFullNode_NotFound(t *testing.T) { - a := &yaml.Node{ - Value: "fish", - } - b := &yaml.Node{ - Value: "paste", - } + a := &yaml.Node{ + Value: "fish", + } + b := &yaml.Node{ + Value: "paste", + } - c, d, e := FindKeyNodeFullTop("lemons", []*yaml.Node{a, b}) - assert.Nil(t, c) - assert.Nil(t, d) - assert.Nil(t, e) + c, d, e := FindKeyNodeFullTop("lemons", []*yaml.Node{a, b}) + assert.Nil(t, c) + assert.Nil(t, d) + assert.Nil(t, e) } func TestMakeTagReadable(t *testing.T) { - n := &yaml.Node{ - Tag: "!!map", - } - assert.Equal(t, ObjectLabel, MakeTagReadable(n)) - n.Tag = "!!seq" - assert.Equal(t, ArrayLabel, MakeTagReadable(n)) - n.Tag = "!!str" - assert.Equal(t, StringLabel, MakeTagReadable(n)) - n.Tag = "!!int" - assert.Equal(t, IntegerLabel, MakeTagReadable(n)) - n.Tag = "!!float" - assert.Equal(t, NumberLabel, MakeTagReadable(n)) - n.Tag = "!!bool" - assert.Equal(t, BooleanLabel, MakeTagReadable(n)) - n.Tag = "mr potato man is here" - assert.Equal(t, "unknown", MakeTagReadable(n)) + n := &yaml.Node{ + Tag: "!!map", + } + assert.Equal(t, ObjectLabel, MakeTagReadable(n)) + n.Tag = "!!seq" + assert.Equal(t, ArrayLabel, MakeTagReadable(n)) + n.Tag = "!!str" + assert.Equal(t, StringLabel, MakeTagReadable(n)) + n.Tag = "!!int" + assert.Equal(t, IntegerLabel, MakeTagReadable(n)) + n.Tag = "!!float" + assert.Equal(t, NumberLabel, MakeTagReadable(n)) + n.Tag = "!!bool" + assert.Equal(t, BooleanLabel, MakeTagReadable(n)) + n.Tag = "mr potato man is here" + assert.Equal(t, "unknown", MakeTagReadable(n)) } func TestIsNodeMap(t *testing.T) { - n := &yaml.Node{ - Tag: "!!map", - } - assert.True(t, IsNodeMap(n)) - n.Tag = "!!pizza" - assert.False(t, IsNodeMap(n)) + n := &yaml.Node{ + Tag: "!!map", + } + assert.True(t, IsNodeMap(n)) + n.Tag = "!!pizza" + assert.False(t, IsNodeMap(n)) } func TestIsNodeMap_Nil(t *testing.T) { - assert.False(t, IsNodeMap(nil)) + assert.False(t, IsNodeMap(nil)) } func TestIsNodePolyMorphic(t *testing.T) { - n := &yaml.Node{ - Content: []*yaml.Node{ - { - Value: "anyOf", - }, - }, - } - assert.True(t, IsNodePolyMorphic(n)) - n.Content[0].Value = "cakes" - assert.False(t, IsNodePolyMorphic(n)) + n := &yaml.Node{ + Content: []*yaml.Node{ + { + Value: "anyOf", + }, + }, + } + assert.True(t, IsNodePolyMorphic(n)) + n.Content[0].Value = "cakes" + assert.False(t, IsNodePolyMorphic(n)) } func TestIsNodeArray(t *testing.T) { - n := &yaml.Node{ - Tag: "!!seq", - } - assert.True(t, IsNodeArray(n)) - n.Tag = "!!pizza" - assert.False(t, IsNodeArray(n)) + n := &yaml.Node{ + Tag: "!!seq", + } + assert.True(t, IsNodeArray(n)) + n.Tag = "!!pizza" + assert.False(t, IsNodeArray(n)) } func TestIsNodeArray_Nil(t *testing.T) { - assert.False(t, IsNodeArray(nil)) + assert.False(t, IsNodeArray(nil)) } func TestIsNodeStringValue(t *testing.T) { - n := &yaml.Node{ - Tag: "!!str", - } - assert.True(t, IsNodeStringValue(n)) - n.Tag = "!!pizza" - assert.False(t, IsNodeStringValue(n)) + n := &yaml.Node{ + Tag: "!!str", + } + assert.True(t, IsNodeStringValue(n)) + n.Tag = "!!pizza" + assert.False(t, IsNodeStringValue(n)) } func TestIsNodeStringValue_Nil(t *testing.T) { - assert.False(t, IsNodeStringValue(nil)) + assert.False(t, IsNodeStringValue(nil)) } func TestIsNodeIntValue(t *testing.T) { - n := &yaml.Node{ - Tag: "!!int", - } - assert.True(t, IsNodeIntValue(n)) - n.Tag = "!!pizza" - assert.False(t, IsNodeIntValue(n)) + n := &yaml.Node{ + Tag: "!!int", + } + assert.True(t, IsNodeIntValue(n)) + n.Tag = "!!pizza" + assert.False(t, IsNodeIntValue(n)) } func TestIsNodeIntValue_Nil(t *testing.T) { - assert.False(t, IsNodeIntValue(nil)) + assert.False(t, IsNodeIntValue(nil)) } func TestIsNodeFloatValue(t *testing.T) { - n := &yaml.Node{ - Tag: "!!float", - } - assert.True(t, IsNodeFloatValue(n)) - n.Tag = "!!pizza" - assert.False(t, IsNodeFloatValue(n)) + n := &yaml.Node{ + Tag: "!!float", + } + assert.True(t, IsNodeFloatValue(n)) + n.Tag = "!!pizza" + assert.False(t, IsNodeFloatValue(n)) } func TestIsNodeFloatValue_Nil(t *testing.T) { - assert.False(t, IsNodeFloatValue(nil)) + assert.False(t, IsNodeFloatValue(nil)) } func TestIsNodeBoolValue(t *testing.T) { - n := &yaml.Node{ - Tag: "!!bool", - } - assert.True(t, IsNodeBoolValue(n)) - n.Tag = "!!pizza" - assert.False(t, IsNodeBoolValue(n)) + n := &yaml.Node{ + Tag: "!!bool", + } + assert.True(t, IsNodeBoolValue(n)) + n.Tag = "!!pizza" + assert.False(t, IsNodeBoolValue(n)) } func TestIsNodeBoolValue_Nil(t *testing.T) { - assert.False(t, IsNodeBoolValue(nil)) + assert.False(t, IsNodeBoolValue(nil)) } func TestFixContext(t *testing.T) { - assert.Equal(t, "$.nuggets[12].name", FixContext("(root).nuggets.12.name")) + assert.Equal(t, "$.nuggets[12].name", FixContext("(root).nuggets.12.name")) } func TestFixContext_HttpCode(t *testing.T) { - assert.Equal(t, "$.nuggets.404.name", FixContext("(root).nuggets.404.name")) + assert.Equal(t, "$.nuggets.404.name", FixContext("(root).nuggets.404.name")) } func TestIsJSON(t *testing.T) { - assert.True(t, IsJSON("{'hello':'there'}")) - assert.False(t, IsJSON("potato shoes")) - assert.False(t, IsJSON("")) + assert.True(t, IsJSON("{'hello':'there'}")) + assert.False(t, IsJSON("potato shoes")) + assert.False(t, IsJSON("")) } func TestIsYAML(t *testing.T) { - assert.True(t, IsYAML("hello:\n there:\n my-name: is quobix")) - assert.True(t, IsYAML("potato shoes")) - assert.False(t, IsYAML("{'hello':'there'}")) - assert.False(t, IsYAML("")) - assert.False(t, IsYAML("8908: hello: yeah: \n12309812: :123")) + assert.True(t, IsYAML("hello:\n there:\n my-name: is quobix")) + assert.True(t, IsYAML("potato shoes")) + assert.False(t, IsYAML("{'hello':'there'}")) + assert.False(t, IsYAML("")) + assert.False(t, IsYAML("8908: hello: yeah: \n12309812: :123")) } func TestConvertYAMLtoJSON(t *testing.T) { - str, err := ConvertYAMLtoJSON([]byte("hello: there")) - assert.NoError(t, err) - assert.NotNil(t, str) - assert.Equal(t, "{\"hello\":\"there\"}", string(str)) + str, err := ConvertYAMLtoJSON([]byte("hello: there")) + assert.NoError(t, err) + assert.NotNil(t, str) + assert.Equal(t, "{\"hello\":\"there\"}", string(str)) - str, err = ConvertYAMLtoJSON([]byte("gonna: break: you:\nyeah:yeah:yeah")) - assert.Error(t, err) - assert.Nil(t, str) + str, err = ConvertYAMLtoJSON([]byte("gonna: break: you:\nyeah:yeah:yeah")) + assert.Error(t, err) + assert.Nil(t, str) } func TestIsHttpVerb(t *testing.T) { - assert.True(t, IsHttpVerb("get")) - assert.True(t, IsHttpVerb("post")) - assert.False(t, IsHttpVerb("nuggets")) + assert.True(t, IsHttpVerb("get")) + assert.True(t, IsHttpVerb("post")) + assert.False(t, IsHttpVerb("nuggets")) } func TestConvertComponentIdIntoFriendlyPathSearch(t *testing.T) { - segment, path := ConvertComponentIdIntoFriendlyPathSearch("#/chicken/chips/pizza/cake") - assert.Equal(t, "$.chicken.chips.pizza.cake", path) - assert.Equal(t, "cake", segment) + segment, path := ConvertComponentIdIntoFriendlyPathSearch("#/chicken/chips/pizza/cake") + assert.Equal(t, "$.chicken.chips.pizza.cake", path) + assert.Equal(t, "cake", segment) } 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) + 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) { - segment, path := ConvertComponentIdIntoFriendlyPathSearch("#/components/schemas/gpg-key/properties/subkeys/example/0/expires_at") - assert.Equal(t, "$.components.schemas.gpg-key.properties.subkeys.example[0].expires_at", path) - assert.Equal(t, "expires_at", segment) + segment, path := ConvertComponentIdIntoFriendlyPathSearch("#/components/schemas/gpg-key/properties/subkeys/example/0/expires_at") + assert.Equal(t, "$.components.schemas.gpg-key.properties.subkeys.example[0].expires_at", path) + assert.Equal(t, "expires_at", segment) } func TestConvertComponentIdIntoFriendlyPathSearch_Simple(t *testing.T) { - segment, path := ConvertComponentIdIntoFriendlyPathSearch("#/~1fresh~1pizza/get") - assert.Equal(t, "$['/fresh/pizza'].get", path) - assert.Equal(t, "get", segment) + segment, path := ConvertComponentIdIntoFriendlyPathSearch("#/~1fresh~1pizza/get") + assert.Equal(t, "$['/fresh/pizza'].get", path) + assert.Equal(t, "get", segment) } func TestConvertComponentIdIntoFriendlyPathSearch_Params(t *testing.T) { - segment, path := ConvertComponentIdIntoFriendlyPathSearch("#/why/0") - assert.Equal(t, "$.why[0]", path) - assert.Equal(t, "0", segment) + segment, path := ConvertComponentIdIntoFriendlyPathSearch("#/why/0") + assert.Equal(t, "$.why[0]", path) + assert.Equal(t, "0", segment) } func TestConvertComponentIdIntoFriendlyPathSearch_Crazy_Github(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) + 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_DigitalOcean(t *testing.T) { - segment, path := ConvertComponentIdIntoFriendlyPathSearch("#/paths/~1v2~1customers~1my~1invoices~1%7Binvoice_uuid%7D/get/parameters/0") - assert.Equal(t, "$.paths['/v2/customers/my/invoices/{invoice_uuid}'].get.parameters[0]", path) - assert.Equal(t, "0", segment) + segment, path := ConvertComponentIdIntoFriendlyPathSearch("#/paths/~1v2~1customers~1my~1invoices~1%7Binvoice_uuid%7D/get/parameters/0") + assert.Equal(t, "$.paths['/v2/customers/my/invoices/{invoice_uuid}'].get.parameters[0]", path) + assert.Equal(t, "0", segment) } func TestConvertComponentIdIntoFriendlyPathSearch_Crazy_DigitalOcean_More(t *testing.T) { - segment, path := ConvertComponentIdIntoFriendlyPathSearch("#/paths/~1v2~1certificates/post/responses/201/content/application~1json/examples/Custom%20Certificate") - assert.Equal(t, "$.paths['/v2/certificates'].post.responses['201'].content['application/json'].examples['Custom Certificate']", path) - assert.Equal(t, "Custom Certificate", segment) + segment, path := ConvertComponentIdIntoFriendlyPathSearch("#/paths/~1v2~1certificates/post/responses/201/content/application~1json/examples/Custom%20Certificate") + assert.Equal(t, "$.paths['/v2/certificates'].post.responses['201'].content['application/json'].examples['Custom Certificate']", path) + assert.Equal(t, "Custom Certificate", segment) } func TestConvertComponentIdIntoFriendlyPathSearch_CrazyShort(t *testing.T) { - segment, path := ConvertComponentIdIntoFriendlyPathSearch("#/paths/~1crazy~1ass~1references") - assert.Equal(t, "$.paths['/crazy/ass/references']", path) - assert.Equal(t, "/crazy/ass/references", segment) + segment, path := ConvertComponentIdIntoFriendlyPathSearch("#/paths/~1crazy~1ass~1references") + assert.Equal(t, "$.paths['/crazy/ass/references']", path) + assert.Equal(t, "/crazy/ass/references", segment) } func TestConvertComponentIdIntoFriendlyPathSearch_Short(t *testing.T) { - segment, path := ConvertComponentIdIntoFriendlyPathSearch("/~1crazy~1ass~1references") - assert.Equal(t, "$['/crazy/ass/references']", path) - assert.Equal(t, "/crazy/ass/references", segment) + segment, path := ConvertComponentIdIntoFriendlyPathSearch("/~1crazy~1ass~1references") + assert.Equal(t, "$['/crazy/ass/references']", path) + assert.Equal(t, "/crazy/ass/references", segment) } func TestConvertComponentIdIntoFriendlyPathSearch_Array(t *testing.T) { - segment, path := ConvertComponentIdIntoFriendlyPathSearch("#/paths/~1crazy~1ass~1references/get/parameters/0") - assert.Equal(t, "$.paths['/crazy/ass/references'].get.parameters[0]", path) - assert.Equal(t, "0", segment) + segment, path := ConvertComponentIdIntoFriendlyPathSearch("#/paths/~1crazy~1ass~1references/get/parameters/0") + assert.Equal(t, "$.paths['/crazy/ass/references'].get.parameters[0]", path) + assert.Equal(t, "0", segment) } func TestConvertComponentIdIntoFriendlyPathSearch_HTTPCode(t *testing.T) { - segment, path := ConvertComponentIdIntoFriendlyPathSearch("#/paths/~1crazy~1ass~1references/get/responses/404") - assert.Equal(t, "$.paths['/crazy/ass/references'].get.responses['404']", path) - assert.Equal(t, "404", segment) + segment, path := ConvertComponentIdIntoFriendlyPathSearch("#/paths/~1crazy~1ass~1references/get/responses/404") + assert.Equal(t, "$.paths['/crazy/ass/references'].get.responses['404']", path) + assert.Equal(t, "404", segment) } func TestConvertComponentIdIntoPath(t *testing.T) { - segment, path := ConvertComponentIdIntoPath("#/chicken/chips/pizza/cake") - assert.Equal(t, "$.chicken.chips.pizza.cake", path) - assert.Equal(t, "cake", segment) + segment, path := ConvertComponentIdIntoPath("#/chicken/chips/pizza/cake") + assert.Equal(t, "$.chicken.chips.pizza.cake", path) + assert.Equal(t, "cake", segment) } func TestDetectCase(t *testing.T) { - assert.Equal(t, PascalCase, DetectCase("PizzaPie")) - assert.Equal(t, CamelCase, DetectCase("anyoneForTennis")) - assert.Equal(t, ScreamingSnakeCase, DetectCase("I_LOVE_BEER")) - assert.Equal(t, ScreamingKebabCase, DetectCase("I-LOVE-BURGERS")) - assert.Equal(t, SnakeCase, DetectCase("snakes_on_a_plane")) - assert.Equal(t, KebabCase, DetectCase("chicken-be-be-beef-or-pork")) - assert.Equal(t, RegularCase, DetectCase("kebab-TimeIn_london-TOWN")) - assert.Equal(t, UnknownCase, DetectCase("")) + assert.Equal(t, PascalCase, DetectCase("PizzaPie")) + assert.Equal(t, CamelCase, DetectCase("anyoneForTennis")) + assert.Equal(t, ScreamingSnakeCase, DetectCase("I_LOVE_BEER")) + assert.Equal(t, ScreamingKebabCase, DetectCase("I-LOVE-BURGERS")) + assert.Equal(t, SnakeCase, DetectCase("snakes_on_a_plane")) + assert.Equal(t, KebabCase, DetectCase("chicken-be-be-beef-or-pork")) + assert.Equal(t, RegularCase, DetectCase("kebab-TimeIn_london-TOWN")) + assert.Equal(t, UnknownCase, DetectCase("")) } func TestIsNodeRefValue(t *testing.T) { - f := &yaml.Node{ - Value: "$ref", - } - g := &yaml.Node{ - Value: "'#/somewhere/out-there'", - } - h := &yaml.Node{ - Tag: "!!map", - Content: []*yaml.Node{f, g}, - } + f := &yaml.Node{ + Value: "$ref", + } + g := &yaml.Node{ + Value: "'#/somewhere/out-there'", + } + h := &yaml.Node{ + Tag: "!!map", + Content: []*yaml.Node{f, g}, + } - ref, node, val := IsNodeRefValue(h) + ref, node, val := IsNodeRefValue(h) - assert.True(t, ref) - assert.Equal(t, "$ref", node.Value) - assert.Equal(t, "'#/somewhere/out-there'", val) + assert.True(t, ref) + assert.Equal(t, "$ref", node.Value) + assert.Equal(t, "'#/somewhere/out-there'", val) } func TestIsNodeRefValue_False(t *testing.T) { - f := &yaml.Node{ - Value: "woof", - } - g := &yaml.Node{ - Value: "dog", - } - h := &yaml.Node{ - Tag: "!!map", - Content: []*yaml.Node{f, g}, - } + f := &yaml.Node{ + Value: "woof", + } + g := &yaml.Node{ + Value: "dog", + } + h := &yaml.Node{ + Tag: "!!map", + Content: []*yaml.Node{f, g}, + } - ref, node, val := IsNodeRefValue(h) + ref, node, val := IsNodeRefValue(h) - assert.False(t, ref) - assert.Nil(t, node) - assert.Empty(t, val) + assert.False(t, ref) + assert.Nil(t, node) + assert.Empty(t, val) } func TestCheckEnumForDuplicates_Success(t *testing.T) { - yml := "- yes\n- no\n- crisps" - var rootNode yaml.Node - yaml.Unmarshal([]byte(yml), &rootNode) - assert.Len(t, CheckEnumForDuplicates(rootNode.Content[0].Content), 0) + yml := "- yes\n- no\n- crisps" + var rootNode yaml.Node + yaml.Unmarshal([]byte(yml), &rootNode) + assert.Len(t, CheckEnumForDuplicates(rootNode.Content[0].Content), 0) } func TestCheckEnumForDuplicates_Fail(t *testing.T) { - yml := "- yes\n- no\n- crisps\n- no" - var rootNode yaml.Node - yaml.Unmarshal([]byte(yml), &rootNode) - assert.Len(t, CheckEnumForDuplicates(rootNode.Content[0].Content), 1) + yml := "- yes\n- no\n- crisps\n- no" + var rootNode yaml.Node + yaml.Unmarshal([]byte(yml), &rootNode) + assert.Len(t, CheckEnumForDuplicates(rootNode.Content[0].Content), 1) } func TestCheckEnumForDuplicates_FailMultiple(t *testing.T) { - yml := "- yes\n- no\n- crisps\n- no\n- rice\n- yes\n- no" + yml := "- yes\n- no\n- crisps\n- no\n- rice\n- yes\n- no" - var rootNode yaml.Node - yaml.Unmarshal([]byte(yml), &rootNode) - assert.Len(t, CheckEnumForDuplicates(rootNode.Content[0].Content), 3) + var rootNode yaml.Node + yaml.Unmarshal([]byte(yml), &rootNode) + assert.Len(t, CheckEnumForDuplicates(rootNode.Content[0].Content), 3) }