diff --git a/Makefile b/Makefile index bbbee12..cbaee81 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ sources := $(wildcard cmd/dyff/*.go internal/cmd/*.go pkg/v1/dyff/*.go) .PHONY: all clean vet fmt lint gocyclo misspell ginkgo test install build -all: test build +all: clean test build clean: @rm -rf binaries internal/cmd/cmd.coverprofile pkg/v1/dyff/dyff.coverprofile diff --git a/go.mod b/go.mod index e1295f0..d1ca5ad 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/homeport/dyff require ( github.com/homeport/gonvenience v1.7.6 - github.com/homeport/ytbx v1.0.1 + github.com/homeport/ytbx v1.1.0 github.com/lucasb-eyer/go-colorful v1.0.2 github.com/mitchellh/hashstructure v1.0.0 github.com/onsi/ginkgo v1.8.0 diff --git a/go.sum b/go.sum index 4cd4360..a416f09 100644 --- a/go.sum +++ b/go.sum @@ -1,43 +1,74 @@ +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/homeport/gonvenience v1.7.0/go.mod h1:G2NH1mGKb2RtQ/xy7Axv5Tnnwzq4yE6NoYyINd1Lvuk= +github.com/gorilla/mux v1.7.1 h1:Dw4jY2nghMMRsh1ol8dv1axHkDwMQK2DHerMNJsIpJU= +github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/homeport/gonvenience v1.7.6 h1:XJIykzrxOLZkOYwk2mj61YnWbIM+47XWrYJ3BSOMbAg= github.com/homeport/gonvenience v1.7.6/go.mod h1:G2NH1mGKb2RtQ/xy7Axv5Tnnwzq4yE6NoYyINd1Lvuk= -github.com/homeport/ytbx v1.0.1/go.mod h1:YygYRuIWr0dsa1CNYubBrMX4xCZFItPDv+MTFqGKOoo= +github.com/homeport/ytbx v1.1.0 h1:bCdqpYmfRmf1cGxDVBehYcNPcZny8QwerZr1CVzLS4c= +github.com/homeport/ytbx v1.1.0/go.mod h1:9/FNhmRziSycuVWlT+SFkpk4vs4sb7iIcW50PwQawaA= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/lucasb-eyer/go-colorful v0.0.0-20180526135729-345fbb3dbcdb/go.mod h1:NXg0ArsFk0Y01623LgUqoqcouGDB+PwCCQlrwrG6xJ4= +github.com/lucasb-eyer/go-colorful v1.0.2 h1:mCMFu6PgSozg9tDNMMK3g18oJBX7oYGrC09mS6CXfO4= github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s= +github.com/mattn/go-ciede2000 v0.0.0-20170301095244-782e8c62fec3 h1:BXxTozrOU8zgC5dkpn3J6NTRdoP+hjok/e+ACr4Hibk= github.com/mattn/go-ciede2000 v0.0.0-20170301095244-782e8c62fec3/go.mod h1:x1uk6vxTiVuNt6S5R2UYgdhpj3oKojXvOXauHZ7dEnI= +github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936 h1:kw1v0NlnN+GZcU8Ma8CLF2Zzgjfx95gs3/GN3vYAPpo= github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk= +github.com/mitchellh/hashstructure v1.0.0 h1:ZkRJX1CyOoTkar7p/mLS5TZU4nJ1Rn/F8u9dGS02Q3Y= github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e h1:T5PdfK/M1xyrHwynxMIVMWLS7f/qHwfslZphxtGnw7s= github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e/go.mod h1:XDKHRm5ThF8YJjx001LtgelzsoaEcvnA7lVWz9EeX3g= +github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74 h1:JwtAtbp7r/7QSyGz8mKUbYJBg2+6Cd7OjM8o/GNOcVo= github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74/go.mod h1:RmMWU37GKR2s6pgrIEB4ixgpVCt/cf7dnJv3fuH1J1c= +golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85 h1:et7+NAX3lLIk5qUCTA9QelBjGE/NkhzYw/mhnr0s7nI= golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35 h1:YAFjXN64LMvktoUZH9zgY4lGc/msGN7HQfoSuKCgaDU= golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0/go.mod h1:OdE7CF6DbADk7lN8LIKRzRJTTZXIjtWgA5THM5lhBAw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/internal/cmd/root.go b/internal/cmd/root.go index f9b6089..28e64d7 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -163,7 +163,7 @@ func (w *OutputWriter) write(writer io.Writer, filename string) error { for _, document := range inputFile.Documents { if w.Restructure { - document = dyff.RestructureObject(document) + document = ytbx.RestructureObject(document) } switch { diff --git a/pkg/v1/dyff/core.go b/pkg/v1/dyff/core.go index 3ffad52..4b519c3 100644 --- a/pkg/v1/dyff/core.go +++ b/pkg/v1/dyff/core.go @@ -425,7 +425,7 @@ func getValueByKey(mapslice yaml.MapSlice, key string) (interface{}, error) { } } - if names, err := ListStringKeys(mapslice); err == nil { + if names, err := ytbx.ListStringKeys(mapslice); err == nil { return nil, fmt.Errorf("no key '%s' found in map, available keys are: %s", key, strings.Join(names, ", ")) } diff --git a/pkg/v1/dyff/output_human.go b/pkg/v1/dyff/output_human.go index 7f18035..a22d3d7 100644 --- a/pkg/v1/dyff/output_human.go +++ b/pkg/v1/dyff/output_human.go @@ -153,7 +153,7 @@ func (report *HumanReport) generateHumanDetailOutputAddition(detail Detail) (str output.WriteString(bunt.Colorize(fmt.Sprintf("%c %s added:\n", ADDITION, text.Plural(len(detail.To.(yaml.MapSlice)), "map entry", "map entries")), bunt.ModificationYellow)) } - yamlOutput, err := yamlStringInGreenishColors(RestructureObject(detail.To)) + yamlOutput, err := yamlStringInGreenishColors(ytbx.RestructureObject(detail.To)) if err != nil { return "", err } @@ -174,7 +174,7 @@ func (report *HumanReport) generateHumanDetailOutputRemoval(detail Detail) (stri output.WriteString(bunt.Colorize(fmt.Sprintf("%c %s removed:\n", REMOVAL, text.Plural(len(detail.From.(yaml.MapSlice)), "map entry", "map entries")), bunt.ModificationYellow)) } - yamlOutput, err := yamlStringInRedishColors(RestructureObject(detail.From)) + yamlOutput, err := yamlStringInRedishColors(ytbx.RestructureObject(detail.From)) if err != nil { return "", err } diff --git a/pkg/v1/dyff/restructure.go b/pkg/v1/dyff/restructure.go deleted file mode 100644 index a5efd3f..0000000 --- a/pkg/v1/dyff/restructure.go +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright © 2019 The Homeport Team -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package dyff - -import ( - "fmt" - - yaml "gopkg.in/yaml.v2" -) - -var knownKeyOrders = [][]string{ - {"name", "director_uuid", "releases", "stemcells", "update", "instance_groups", "addons"}, // https://bosh.io/docs/manifest-v2.html - {"name", "director_uuid", "releases", "instance_groups", "networks", "resource_pools", "compilation"}, // Random actual example ... - {"jobs", "resources", "resource_types"}, // https://concourse-ci.org/pipelines.html - {"name", "type", "source"}, // https://concourse-ci.org/resources.html - {"get"}, // https://concourse-ci.org/steps.html - {"put"}, // https://concourse-ci.org/steps.html - {"task"}, // https://concourse-ci.org/steps.html - {"name"}, // Universal default #1 ... name should always be first - {"key"}, // Universal default #2 ... key should always be first - {"id"}, // Universal default #3 ... id should always be first -} - -func lookupMap(list []string) map[string]int { - result := make(map[string]int, len(list)) - for idx, entry := range list { - result[entry] = idx - } - - return result -} - -func hasAll(keys, list []string) bool { - counter := 0 - target := len(list) - - lookup := lookupMap(keys) - for _, key := range list { - if _, ok := lookup[key]; ok { - counter++ - - if counter == target { - return true - } - } - } - - return false -} - -func reorderMapsliceKeys(input yaml.MapSlice, keys []string) yaml.MapSlice { - // Add all keys from the input MapSlice that are not part of the ordered keys list - lookup := lookupMap(keys) - for _, mapitem := range input { - key := mapitem.Key.(string) - if _, ok := lookup[key]; !ok { - keys = append(keys, key) - } - } - - // Rebuild a new YAML MapSlice key by key using in provided keys list for the order - result := yaml.MapSlice{} - for _, key := range keys { - // It is safe to ignore the error field here since we know what keys there are - value, _ := getValueByKey(input, key) - result = append(result, yaml.MapItem{ - Key: key, - Value: value, - }) - } - - return result -} - -func getSuitableReorderFunction(keys []string) func(yaml.MapSlice) yaml.MapSlice { - for _, candidate := range knownKeyOrders { - if hasAll(keys, candidate) { - return func(input yaml.MapSlice) yaml.MapSlice { - return reorderMapsliceKeys(input, candidate) - } - } - } - - return nil -} - -// ListStringKeys returns a list of the keys of the YAML MapSlice (map). Only string keys are supported. Other types will result in an error. -func ListStringKeys(mapslice yaml.MapSlice) ([]string, error) { - keys := make([]string, len(mapslice)) - for i, mapitem := range mapslice { - switch mapitem.Key.(type) { - case string: - keys[i] = mapitem.Key.(string) - - default: - return nil, fmt.Errorf("provided mapslice mapitem contains non-string key: %#v", mapitem.Key) - } - } - - return keys, nil -} - -// RestructureObject takes an object and traverses down any sub elements such as list entries or map values to recursively call restructure itself. On YAML MapSlices (maps), it will use a look-up mechanism to decide if the order of key in that map needs to be rearranged to meet some known established human order. -func RestructureObject(obj interface{}) interface{} { - switch val := obj.(type) { - case yaml.MapSlice: - // Restructure the YAML MapSlice keys - if keys, err := ListStringKeys(val); err == nil { - if fn := getSuitableReorderFunction(keys); fn != nil { - val = fn(val) - } - } - - // Restructure the values of the respective keys of this YAML MapSlice - for _, mapitem := range val { - mapitem.Value = RestructureObject(mapitem.Value) - } - - return val - - case []interface{}: - for i := range val { - val[i] = RestructureObject(val[i]) - } - return val - - default: - return obj - } -} diff --git a/pkg/v1/dyff/restructure_test.go b/pkg/v1/dyff/restructure_test.go deleted file mode 100644 index 6516ae8..0000000 --- a/pkg/v1/dyff/restructure_test.go +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright © 2019 The Homeport Team -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package dyff_test - -import ( - . "github.com/homeport/dyff/pkg/v1/dyff" - yaml "gopkg.in/yaml.v2" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -var _ = Describe("Restructure", func() { - Context("YAML MapSlice key reorderings of the MapSlice itself", func() { - It("should restructure Concourse root level keys", func() { - input := yml("{ groups: [], jobs: [], resources: [], resource_types: [] }") - output := RestructureObject(input).(yaml.MapSlice) - - keys, err := ListStringKeys(output) - Expect(err).To(BeNil()) - Expect(keys).To(BeEquivalentTo([]string{"jobs", "resources", "resource_types", "groups"})) - }) - - It("should restructure Concourse resource and resource_type keys", func() { - input := yml("{ source: {}, name: {}, type: {}, privileged: {} }") - output := RestructureObject(input).(yaml.MapSlice) - - keys, err := ListStringKeys(output) - Expect(err).To(BeNil()) - Expect(keys).To(BeEquivalentTo([]string{"name", "type", "source", "privileged"})) - }) - }) - - Context("YAML MapSlice key reorderings of the MapSlice values", func() { - It("should restructure Concourse resource keys as part as part of a MapSlice value", func() { - input := yml("{ resources: [ { privileged: false, source: { branch: foo, paths: [] }, name: myname, type: mytype } ] }") - output := RestructureObject(input).(yaml.MapSlice) - - value := output[0].Value.([]interface{}) - obj := value[0].(yaml.MapSlice) - - keys, err := ListStringKeys(obj) - Expect(err).To(BeNil()) - Expect(keys).To(BeEquivalentTo([]string{"name", "type", "source", "privileged"})) - }) - }) -})