Initial packaging
Tim Potter
7 years ago
0 | golang-github-imdario-mergo (0.1.2+git20150606.5.61a5285-1) UNRELEASED; urgency=medium | |
1 | ||
2 | * Initial release (Closes: #802743) | |
3 | ||
4 | -- Tim Potter <tpot@hpe.com> Fri, 23 Oct 2015 15:49:38 +1100 |
0 | 9 |
0 | Source: golang-github-imdario-mergo | |
1 | Section: devel | |
2 | Priority: extra | |
3 | Maintainer: Debian Go Packaging Team <pkg-go-maintainers@lists.alioth.debian.org> | |
4 | Uploaders: Tim Potter <tpot@hpe.com> | |
5 | Build-Depends: debhelper (>= 9), | |
6 | dh-golang, | |
7 | golang-go | |
8 | Standards-Version: 3.9.6 | |
9 | Homepage: https://github.com/imdario/mergo | |
10 | Vcs-Browser: https://anonscm.debian.org/cgit/pkg-go/packages/golang-github-imdario-mergo.git | |
11 | Vcs-Git: git://anonscm.debian.org/pkg-go/packages/golang-github-imdario-mergo.git | |
12 | XS-Go-Import-Path: github.com/imdario/mergo | |
13 | ||
14 | Package: golang-github-imdario-mergo-dev | |
15 | Architecture: all | |
16 | Depends: ${shlibs:Depends}, | |
17 | ${misc:Depends}, | |
18 | golang-go | |
19 | Description: Functions to merge structs and maps in Go | |
20 | Mergo is a set of helper functions to merge structs and maps in | |
21 | the Go language. It is useful for configuration default values, | |
22 | avoiding messy if-statements in initialisation code. |
0 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ | |
1 | Upstream-Name: mergo | |
2 | Source: https://github.com/imdario/mergo | |
3 | ||
4 | Files: * | |
5 | Copyright: 2013 Dario Castañé | |
6 | 2012 The Go Authors | |
7 | License: BSD-3-clause | |
8 | ||
9 | Files: debian/* | |
10 | Copyright: 2015 Tim Potter <tpot@hpe.com> | |
11 | License: BSD-3-clause | |
12 | Comment: Debian packaging is licensed under the same terms as upstream | |
13 | ||
14 | License: BSD-3-clause | |
15 | Redistribution and use in source and binary forms, with or without | |
16 | modification, are permitted provided that the following conditions are | |
17 | met: | |
18 | . | |
19 | * Redistributions of source code must retain the above copyright | |
20 | notice, this list of conditions and the following disclaimer. | |
21 | * Redistributions in binary form must reproduce the above | |
22 | copyright notice, this list of conditions and the following disclaimer | |
23 | in the documentation and/or other materials provided with the | |
24 | distribution. | |
25 | * Neither the name of Google Inc. nor the names of its | |
26 | contributors may be used to endorse or promote products derived from | |
27 | this software without specific prior written permission. | |
28 | . | |
29 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
30 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
31 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
32 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
33 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
34 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
35 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
36 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
37 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
38 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
39 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
0 | golang-github-imdario-mergo-dev_0.1.2+git20150606.5.61a5285-1_all.deb devel extra |
0 | Package: golang-github-imdario-mergo-dev | |
1 | Source: golang-github-imdario-mergo | |
2 | Version: 0.1.2+git20150606.5.61a5285-1 | |
3 | Architecture: all | |
4 | Maintainer: Debian Go Packaging Team <pkg-go-maintainers@lists.alioth.debian.org> | |
5 | Installed-Size: 32 | |
6 | Depends: golang-go | |
7 | Section: devel | |
8 | Priority: extra | |
9 | Homepage: https://github.com/imdario/mergo | |
10 | Description: Mergo: merging Go structs and maps since 2013 | |
11 | Mergo A helper to merge structs and maps in Golang. Useful for | |
12 | configuration default values, avoiding messy if-statements. | |
13 | . | |
14 | Also a lovely comune (http://en.wikipedia.org/wiki/Mergo) (municipality) | |
15 | in the Province of Ancona in the Italian region Marche. | |
16 | . | |
17 | Mergo dall'alto Status It is ready for production use. It works fine | |
18 | after extensive use in the wild. | |
19 | . | |
20 | Build Status (https://travis-ci.org/imdario/mergo) GoDoc | |
21 | (https://godoc.org/github.com/imdario/mergo) Important note Mergo is | |
22 | intended to assign only zero value fields on destination with source | |
23 | value. Since April 6th it works like this. Before it didn't work | |
24 | properly, causing some random overwrites. After some issues and PRs | |
25 | I found it didn't merge as I designed it. Thanks to imdario/mergo#8 | |
26 | (https://github.com/imdario/mergo/pull/8) overwriting functions were | |
27 | added and the wrong behavior was clearly detected. | |
28 | . | |
29 | If you were using Mergo before April 6th 2015, please check | |
30 | your project works as intended after updating your local copy | |
31 | with go get -u github.com/imdario/mergo. I apologize for any | |
32 | issue caused by its previous behavior and any future bug that | |
33 | Mergo could cause (I hope it won't!) in existing projects after | |
34 | the change (release 0.2.0). Mergo in the wild• imdario/zas | |
35 | (https://github.com/imdario/zas)• GoogleCloudPlatform/kubernetes | |
36 | (https://github.com/GoogleCloudPlatform/kubernetes)• soniah/dnsmadeeasy | |
37 | (https://github.com/soniah/dnsmadeeasy)• EagerIO/Stout | |
38 | (https://github.com/EagerIO/Stout)• lynndylanhurley/defsynth-api | |
39 | (https://github.com/lynndylanhurley/defsynth-api)• | |
40 | russross/canvasassignments | |
41 | (https://github.com/russross/canvasassignments)• rdegges/cryptly-api | |
42 | (https://github.com/rdegges/cryptly-api)• casualjim/exeggutor | |
43 | (https://github.com/casualjim/exeggutor)• divshot/gitling | |
44 | (https://github.com/divshot/gitling)• RWJMurphy/gorl | |
45 | (https://github.com/RWJMurphy/gorl)• andrerocker/deploy42 | |
46 | (https://github.com/andrerocker/deploy42)• elwinar/rambler | |
47 | (https://github.com/elwinar/rambler)• tmaiaroto/gopartman | |
48 | (https://github.com/tmaiaroto/gopartman)• jfbus/impressionist | |
49 | (https://github.com/jfbus/impressionist)• Jmeyering/zealot | |
50 | (https://github.com/Jmeyering/zealot)• godep-migrator/rigger-host | |
51 | (https://github.com/godep-migrator/rigger-host)• | |
52 | Dronevery/MultiwaySwitch-Go | |
53 | (https://github.com/Dronevery/MultiwaySwitch-Go)• thoas/picfit | |
54 | (https://github.com/thoas/picfit)• mantasmatelis/whooplist-server | |
55 | (https://github.com/mantasmatelis/whooplist-server)• | |
56 | jnuthong/item_search | |
57 | (https://github.com/jnuthong/item_search)Installationgo get | |
58 | github.com/imdario/mergo | |
59 | . | |
60 | // use in your .go code import ( | |
61 | "github.com/imdario/mergo" | |
62 | ) Usage You can only merge same-type structs with exported fields | |
63 | initialized as zero value of their type and same-types maps. Mergo won't | |
64 | merge unexported (private) fields but will do recursively any exported | |
65 | one. Also maps will be merged recursively except for structs inside | |
66 | maps (because they are not addressable using Go reflection). if err := | |
67 | mergo.Merge(&dst, src); err != nil { | |
68 | // ... | |
69 | } | |
70 | . | |
71 | Additionally, you can map a map[string]interface{} to a struct (and | |
72 | otherwise, from struct to map), following the same restrictions as in | |
73 | Merge(). Keys are capitalized to find each corresponding exported field. | |
74 | if err := mergo.Map(&dst, srcMap); err != nil { | |
75 | // ... | |
76 | } | |
77 | . | |
78 | Warning: if you map a struct to map, it won't do it recursively. Don't | |
79 | expect Mergo to map struct members of your struct as | |
80 | map[string]interface{}. They will be just assigned as values. | |
81 | . | |
82 | More information and examples in godoc documentation | |
83 | (http://godoc.org/github.com/imdario/mergo). Nice example ```go | |
84 | package main | |
85 | . | |
86 | import ( | |
87 | "fmt" "github.com/imdario/mergo" | |
88 | ) | |
89 | . | |
90 | type Foo struct { | |
91 | A string B int64 | |
92 | } | |
93 | . | |
94 | func main() { | |
95 | src := Foo{ | |
96 | A: "one", | |
97 | } | |
98 | dest := Foo{ | |
99 | A: "two", B: 2, | |
100 | } | |
101 | . | |
102 | mergo.Merge(&dest, src) | |
103 | . | |
104 | fmt.Println(dest) // Will print // {two 2} | |
105 | . | |
106 | } ``` | |
107 | . | |
108 | Note: if test are failing due missing package, please execute: go get | |
109 | gopkg.in/yaml.v1 Contact me If I can help you, you have an idea or you | |
110 | are using Mergo in your projects, don't hesitate to drop me a line | |
111 | (or a pull request): @im_dario (https://twitter.com/im_dario) About | |
112 | Written by Dario Castañé (http://dario.im). License BSD 3-Clause | |
113 | (http://opensource.org/licenses/BSD-3-Clause) license, as Go language | |
114 | (http://golang.org/LICENSE). |
0 | cea04a95e95a86e12eeaeabffe961407 usr/share/doc/golang-github-imdario-mergo-dev/changelog.Debian.gz | |
1 | 23c76504c9f8fcdbc9cf9dace180e609 usr/share/doc/golang-github-imdario-mergo-dev/copyright | |
2 | 72d36ad766a79c6213213fe895ea689b usr/share/gocode/src/github.com/imdario/mergo/doc.go | |
3 | d93b415363bfd121b6ae4d6017d2bd20 usr/share/gocode/src/github.com/imdario/mergo/map.go | |
4 | cb00ac7e30385c86b544f5f61ff25305 usr/share/gocode/src/github.com/imdario/mergo/merge.go | |
5 | 53083cfcfcc7928978e6241303c1e0ce usr/share/gocode/src/github.com/imdario/mergo/mergo.go | |
6 | db680b3570c05f2dd24fe1d035e7c9d3 usr/share/gocode/src/github.com/imdario/mergo/mergo_test.go |
debian/golang-github-imdario-mergo-dev/usr/share/doc/golang-github-imdario-mergo-dev/changelog.Debian.gz
less
more
Binary diff not shown
+15
-0
0 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ | |
1 | Upstream-Name: mergo | |
2 | Source: https://github.com/imdario/mergo | |
3 | ||
4 | Files: * | |
5 | Copyright: 2013 Dario Castañé | |
6 | License: BSD-3-clause | |
7 | ||
8 | Files: debian/* | |
9 | Copyright: 2015 Tim Potter <tpot@hpe.com> | |
10 | License: BSD-3-clause | |
11 | Comment: Debian packaging is licensed under the same terms as upstream | |
12 | ||
13 | License: BSD-3-clause | |
14 | TODO⏎ |
+44
-0
0 | // Copyright 2013 Dario Castañé. All rights reserved. | |
1 | // Copyright 2009 The Go Authors. All rights reserved. | |
2 | // Use of this source code is governed by a BSD-style | |
3 | // license that can be found in the LICENSE file. | |
4 | ||
5 | /* | |
6 | Package mergo merges same-type structs and maps by setting default values in zero-value fields. | |
7 | ||
8 | Mergo won't merge unexported (private) fields but will do recursively any exported one. It also won't merge structs inside maps (because they are not addressable using Go reflection). | |
9 | ||
10 | Usage | |
11 | ||
12 | From my own work-in-progress project: | |
13 | ||
14 | type networkConfig struct { | |
15 | Protocol string | |
16 | Address string | |
17 | ServerType string `json: "server_type"` | |
18 | Port uint16 | |
19 | } | |
20 | ||
21 | type FssnConfig struct { | |
22 | Network networkConfig | |
23 | } | |
24 | ||
25 | var fssnDefault = FssnConfig { | |
26 | networkConfig { | |
27 | "tcp", | |
28 | "127.0.0.1", | |
29 | "http", | |
30 | 31560, | |
31 | }, | |
32 | } | |
33 | ||
34 | // Inside a function [...] | |
35 | ||
36 | if err := mergo.Merge(&config, fssnDefault); err != nil { | |
37 | log.Fatal(err) | |
38 | } | |
39 | ||
40 | // More code [...] | |
41 | ||
42 | */ | |
43 | package mergo |
+154
-0
0 | // Copyright 2014 Dario Castañé. All rights reserved. | |
1 | // Copyright 2009 The Go Authors. All rights reserved. | |
2 | // Use of this source code is governed by a BSD-style | |
3 | // license that can be found in the LICENSE file. | |
4 | ||
5 | // Based on src/pkg/reflect/deepequal.go from official | |
6 | // golang's stdlib. | |
7 | ||
8 | package mergo | |
9 | ||
10 | import ( | |
11 | "fmt" | |
12 | "reflect" | |
13 | "unicode" | |
14 | "unicode/utf8" | |
15 | ) | |
16 | ||
17 | func changeInitialCase(s string, mapper func(rune) rune) string { | |
18 | if s == "" { | |
19 | return s | |
20 | } | |
21 | r, n := utf8.DecodeRuneInString(s) | |
22 | return string(mapper(r)) + s[n:] | |
23 | } | |
24 | ||
25 | func isExported(field reflect.StructField) bool { | |
26 | r, _ := utf8.DecodeRuneInString(field.Name) | |
27 | return r >= 'A' && r <= 'Z' | |
28 | } | |
29 | ||
30 | // Traverses recursively both values, assigning src's fields values to dst. | |
31 | // The map argument tracks comparisons that have already been seen, which allows | |
32 | // short circuiting on recursive types. | |
33 | func deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int, overwrite bool) (err error) { | |
34 | if dst.CanAddr() { | |
35 | addr := dst.UnsafeAddr() | |
36 | h := 17 * addr | |
37 | seen := visited[h] | |
38 | typ := dst.Type() | |
39 | for p := seen; p != nil; p = p.next { | |
40 | if p.ptr == addr && p.typ == typ { | |
41 | return nil | |
42 | } | |
43 | } | |
44 | // Remember, remember... | |
45 | visited[h] = &visit{addr, typ, seen} | |
46 | } | |
47 | zeroValue := reflect.Value{} | |
48 | switch dst.Kind() { | |
49 | case reflect.Map: | |
50 | dstMap := dst.Interface().(map[string]interface{}) | |
51 | for i, n := 0, src.NumField(); i < n; i++ { | |
52 | srcType := src.Type() | |
53 | field := srcType.Field(i) | |
54 | if !isExported(field) { | |
55 | continue | |
56 | } | |
57 | fieldName := field.Name | |
58 | fieldName = changeInitialCase(fieldName, unicode.ToLower) | |
59 | if v, ok := dstMap[fieldName]; !ok || (isEmptyValue(reflect.ValueOf(v)) || overwrite) { | |
60 | dstMap[fieldName] = src.Field(i).Interface() | |
61 | } | |
62 | } | |
63 | case reflect.Struct: | |
64 | srcMap := src.Interface().(map[string]interface{}) | |
65 | for key := range srcMap { | |
66 | srcValue := srcMap[key] | |
67 | fieldName := changeInitialCase(key, unicode.ToUpper) | |
68 | dstElement := dst.FieldByName(fieldName) | |
69 | if dstElement == zeroValue { | |
70 | // We discard it because the field doesn't exist. | |
71 | continue | |
72 | } | |
73 | srcElement := reflect.ValueOf(srcValue) | |
74 | dstKind := dstElement.Kind() | |
75 | srcKind := srcElement.Kind() | |
76 | if srcKind == reflect.Ptr && dstKind != reflect.Ptr { | |
77 | srcElement = srcElement.Elem() | |
78 | srcKind = reflect.TypeOf(srcElement.Interface()).Kind() | |
79 | } else if dstKind == reflect.Ptr { | |
80 | // Can this work? I guess it can't. | |
81 | if srcKind != reflect.Ptr && srcElement.CanAddr() { | |
82 | srcPtr := srcElement.Addr() | |
83 | srcElement = reflect.ValueOf(srcPtr) | |
84 | srcKind = reflect.Ptr | |
85 | } | |
86 | } | |
87 | if !srcElement.IsValid() { | |
88 | continue | |
89 | } | |
90 | if srcKind == dstKind { | |
91 | if err = deepMerge(dstElement, srcElement, visited, depth+1, overwrite); err != nil { | |
92 | return | |
93 | } | |
94 | } else { | |
95 | if srcKind == reflect.Map { | |
96 | if err = deepMap(dstElement, srcElement, visited, depth+1, overwrite); err != nil { | |
97 | return | |
98 | } | |
99 | } else { | |
100 | return fmt.Errorf("type mismatch on %s field: found %v, expected %v", fieldName, srcKind, dstKind) | |
101 | } | |
102 | } | |
103 | } | |
104 | } | |
105 | return | |
106 | } | |
107 | ||
108 | // Map sets fields' values in dst from src. | |
109 | // src can be a map with string keys or a struct. dst must be the opposite: | |
110 | // if src is a map, dst must be a valid pointer to struct. If src is a struct, | |
111 | // dst must be map[string]interface{}. | |
112 | // It won't merge unexported (private) fields and will do recursively | |
113 | // any exported field. | |
114 | // If dst is a map, keys will be src fields' names in lower camel case. | |
115 | // Missing key in src that doesn't match a field in dst will be skipped. This | |
116 | // doesn't apply if dst is a map. | |
117 | // This is separated method from Merge because it is cleaner and it keeps sane | |
118 | // semantics: merging equal types, mapping different (restricted) types. | |
119 | func Map(dst, src interface{}) error { | |
120 | return _map(dst, src, false) | |
121 | } | |
122 | ||
123 | func MapWithOverwrite(dst, src interface{}) error { | |
124 | return _map(dst, src, true) | |
125 | } | |
126 | ||
127 | func _map(dst, src interface{}, overwrite bool) error { | |
128 | var ( | |
129 | vDst, vSrc reflect.Value | |
130 | err error | |
131 | ) | |
132 | if vDst, vSrc, err = resolveValues(dst, src); err != nil { | |
133 | return err | |
134 | } | |
135 | // To be friction-less, we redirect equal-type arguments | |
136 | // to deepMerge. Only because arguments can be anything. | |
137 | if vSrc.Kind() == vDst.Kind() { | |
138 | return deepMerge(vDst, vSrc, make(map[uintptr]*visit), 0, overwrite) | |
139 | } | |
140 | switch vSrc.Kind() { | |
141 | case reflect.Struct: | |
142 | if vDst.Kind() != reflect.Map { | |
143 | return ErrExpectedMapAsDestination | |
144 | } | |
145 | case reflect.Map: | |
146 | if vDst.Kind() != reflect.Struct { | |
147 | return ErrExpectedStructAsDestination | |
148 | } | |
149 | default: | |
150 | return ErrNotSupported | |
151 | } | |
152 | return deepMap(vDst, vSrc, make(map[uintptr]*visit), 0, overwrite) | |
153 | } |
+110
-0
0 | // Copyright 2013 Dario Castañé. All rights reserved. | |
1 | // Copyright 2009 The Go Authors. All rights reserved. | |
2 | // Use of this source code is governed by a BSD-style | |
3 | // license that can be found in the LICENSE file. | |
4 | ||
5 | // Based on src/pkg/reflect/deepequal.go from official | |
6 | // golang's stdlib. | |
7 | ||
8 | package mergo | |
9 | ||
10 | import ( | |
11 | "reflect" | |
12 | ) | |
13 | ||
14 | // Traverses recursively both values, assigning src's fields values to dst. | |
15 | // The map argument tracks comparisons that have already been seen, which allows | |
16 | // short circuiting on recursive types. | |
17 | func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, overwrite bool) (err error) { | |
18 | if !src.IsValid() { | |
19 | return | |
20 | } | |
21 | if dst.CanAddr() { | |
22 | addr := dst.UnsafeAddr() | |
23 | h := 17 * addr | |
24 | seen := visited[h] | |
25 | typ := dst.Type() | |
26 | for p := seen; p != nil; p = p.next { | |
27 | if p.ptr == addr && p.typ == typ { | |
28 | return nil | |
29 | } | |
30 | } | |
31 | // Remember, remember... | |
32 | visited[h] = &visit{addr, typ, seen} | |
33 | } | |
34 | switch dst.Kind() { | |
35 | case reflect.Struct: | |
36 | for i, n := 0, dst.NumField(); i < n; i++ { | |
37 | if err = deepMerge(dst.Field(i), src.Field(i), visited, depth+1, overwrite); err != nil { | |
38 | return | |
39 | } | |
40 | } | |
41 | case reflect.Map: | |
42 | for _, key := range src.MapKeys() { | |
43 | srcElement := src.MapIndex(key) | |
44 | if !srcElement.IsValid() { | |
45 | continue | |
46 | } | |
47 | dstElement := dst.MapIndex(key) | |
48 | switch reflect.TypeOf(srcElement.Interface()).Kind() { | |
49 | case reflect.Struct: | |
50 | fallthrough | |
51 | case reflect.Map: | |
52 | if err = deepMerge(dstElement, srcElement, visited, depth+1, overwrite); err != nil { | |
53 | return | |
54 | } | |
55 | } | |
56 | if !isEmptyValue(srcElement) && (overwrite || (!dstElement.IsValid() || isEmptyValue(dst))) { | |
57 | if dst.IsNil() { | |
58 | dst.Set(reflect.MakeMap(dst.Type())) | |
59 | } | |
60 | dst.SetMapIndex(key, srcElement) | |
61 | } | |
62 | } | |
63 | case reflect.Ptr: | |
64 | fallthrough | |
65 | case reflect.Interface: | |
66 | if src.IsNil() { | |
67 | break | |
68 | } else if dst.IsNil() { | |
69 | if dst.CanSet() && (overwrite || isEmptyValue(dst)) { | |
70 | dst.Set(src) | |
71 | } | |
72 | } else if err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, overwrite); err != nil { | |
73 | return | |
74 | } | |
75 | default: | |
76 | if dst.CanSet() && !isEmptyValue(src) && (overwrite || isEmptyValue(dst)) { | |
77 | dst.Set(src) | |
78 | } | |
79 | } | |
80 | return | |
81 | } | |
82 | ||
83 | // Merge sets fields' values in dst from src if they have a zero | |
84 | // value of their type. | |
85 | // dst and src must be valid same-type structs and dst must be | |
86 | // a pointer to struct. | |
87 | // It won't merge unexported (private) fields and will do recursively | |
88 | // any exported field. | |
89 | func Merge(dst, src interface{}) error { | |
90 | return merge(dst, src, false) | |
91 | } | |
92 | ||
93 | func MergeWithOverwrite(dst, src interface{}) error { | |
94 | return merge(dst, src, true) | |
95 | } | |
96 | ||
97 | func merge(dst, src interface{}, overwrite bool) error { | |
98 | var ( | |
99 | vDst, vSrc reflect.Value | |
100 | err error | |
101 | ) | |
102 | if vDst, vSrc, err = resolveValues(dst, src); err != nil { | |
103 | return err | |
104 | } | |
105 | if vDst.Type() != vSrc.Type() { | |
106 | return ErrDifferentArgumentsTypes | |
107 | } | |
108 | return deepMerge(vDst, vSrc, make(map[uintptr]*visit), 0, overwrite) | |
109 | } |
+90
-0
0 | // Copyright 2013 Dario Castañé. All rights reserved. | |
1 | // Copyright 2009 The Go Authors. All rights reserved. | |
2 | // Use of this source code is governed by a BSD-style | |
3 | // license that can be found in the LICENSE file. | |
4 | ||
5 | // Based on src/pkg/reflect/deepequal.go from official | |
6 | // golang's stdlib. | |
7 | ||
8 | package mergo | |
9 | ||
10 | import ( | |
11 | "errors" | |
12 | "reflect" | |
13 | ) | |
14 | ||
15 | // Errors reported by Mergo when it finds invalid arguments. | |
16 | var ( | |
17 | ErrNilArguments = errors.New("src and dst must not be nil") | |
18 | ErrDifferentArgumentsTypes = errors.New("src and dst must be of same type") | |
19 | ErrNotSupported = errors.New("only structs and maps are supported") | |
20 | ErrExpectedMapAsDestination = errors.New("dst was expected to be a map") | |
21 | ErrExpectedStructAsDestination = errors.New("dst was expected to be a struct") | |
22 | ) | |
23 | ||
24 | // During deepMerge, must keep track of checks that are | |
25 | // in progress. The comparison algorithm assumes that all | |
26 | // checks in progress are true when it reencounters them. | |
27 | // Visited are stored in a map indexed by 17 * a1 + a2; | |
28 | type visit struct { | |
29 | ptr uintptr | |
30 | typ reflect.Type | |
31 | next *visit | |
32 | } | |
33 | ||
34 | // From src/pkg/encoding/json. | |
35 | func isEmptyValue(v reflect.Value) bool { | |
36 | switch v.Kind() { | |
37 | case reflect.Array, reflect.Map, reflect.Slice, reflect.String: | |
38 | return v.Len() == 0 | |
39 | case reflect.Bool: | |
40 | return !v.Bool() | |
41 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | |
42 | return v.Int() == 0 | |
43 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: | |
44 | return v.Uint() == 0 | |
45 | case reflect.Float32, reflect.Float64: | |
46 | return v.Float() == 0 | |
47 | case reflect.Interface, reflect.Ptr: | |
48 | return v.IsNil() | |
49 | } | |
50 | return false | |
51 | } | |
52 | ||
53 | func resolveValues(dst, src interface{}) (vDst, vSrc reflect.Value, err error) { | |
54 | if dst == nil || src == nil { | |
55 | err = ErrNilArguments | |
56 | return | |
57 | } | |
58 | vDst = reflect.ValueOf(dst).Elem() | |
59 | if vDst.Kind() != reflect.Struct && vDst.Kind() != reflect.Map { | |
60 | err = ErrNotSupported | |
61 | return | |
62 | } | |
63 | vSrc = reflect.ValueOf(src) | |
64 | // We check if vSrc is a pointer to dereference it. | |
65 | if vSrc.Kind() == reflect.Ptr { | |
66 | vSrc = vSrc.Elem() | |
67 | } | |
68 | return | |
69 | } | |
70 | ||
71 | // Traverses recursively both values, assigning src's fields values to dst. | |
72 | // The map argument tracks comparisons that have already been seen, which allows | |
73 | // short circuiting on recursive types. | |
74 | func deeper(dst, src reflect.Value, visited map[uintptr]*visit, depth int) (err error) { | |
75 | if dst.CanAddr() { | |
76 | addr := dst.UnsafeAddr() | |
77 | h := 17 * addr | |
78 | seen := visited[h] | |
79 | typ := dst.Type() | |
80 | for p := seen; p != nil; p = p.next { | |
81 | if p.ptr == addr && p.typ == typ { | |
82 | return nil | |
83 | } | |
84 | } | |
85 | // Remember, remember... | |
86 | visited[h] = &visit{addr, typ, seen} | |
87 | } | |
88 | return // TODO refactor | |
89 | } |
+310
-0
0 | // Copyright 2013 Dario Castañé. All rights reserved. | |
1 | // Copyright 2009 The Go Authors. All rights reserved. | |
2 | // Use of this source code is governed by a BSD-style | |
3 | // license that can be found in the LICENSE file. | |
4 | ||
5 | package mergo | |
6 | ||
7 | import ( | |
8 | "reflect" | |
9 | "testing" | |
10 | ) | |
11 | ||
12 | type simpleTest struct { | |
13 | Value int | |
14 | } | |
15 | ||
16 | type complexTest struct { | |
17 | St simpleTest | |
18 | sz int | |
19 | Id string | |
20 | } | |
21 | ||
22 | type moreComplextText struct { | |
23 | Ct complexTest | |
24 | St simpleTest | |
25 | Nt simpleTest | |
26 | } | |
27 | ||
28 | type pointerTest struct { | |
29 | C *simpleTest | |
30 | } | |
31 | ||
32 | type sliceTest struct { | |
33 | S []int | |
34 | } | |
35 | ||
36 | func TestKb(t *testing.T) { | |
37 | type testStruct struct { | |
38 | Name string | |
39 | KeyValue map[string]interface{} | |
40 | } | |
41 | ||
42 | akv := make(map[string]interface{}) | |
43 | akv["Key1"] = "not value 1" | |
44 | akv["Key2"] = "value2" | |
45 | a := testStruct{} | |
46 | a.Name = "A" | |
47 | a.KeyValue = akv | |
48 | ||
49 | bkv := make(map[string]interface{}) | |
50 | bkv["Key1"] = "value1" | |
51 | bkv["Key3"] = "value3" | |
52 | b := testStruct{} | |
53 | b.Name = "B" | |
54 | b.KeyValue = bkv | |
55 | ||
56 | ekv := make(map[string]interface{}) | |
57 | ekv["Key1"] = "value1" | |
58 | ekv["Key2"] = "value2" | |
59 | ekv["Key3"] = "value3" | |
60 | expected := testStruct{} | |
61 | expected.Name = "B" | |
62 | expected.KeyValue = ekv | |
63 | ||
64 | Merge(&b, a) | |
65 | ||
66 | if !reflect.DeepEqual(b, expected) { | |
67 | t.Errorf("Actual: %#v did not match \nExpected: %#v", b, expected) | |
68 | } | |
69 | } | |
70 | ||
71 | func TestNil(t *testing.T) { | |
72 | if err := Merge(nil, nil); err != ErrNilArguments { | |
73 | t.Fail() | |
74 | } | |
75 | } | |
76 | ||
77 | func TestDifferentTypes(t *testing.T) { | |
78 | a := simpleTest{42} | |
79 | b := 42 | |
80 | if err := Merge(&a, b); err != ErrDifferentArgumentsTypes { | |
81 | t.Fail() | |
82 | } | |
83 | } | |
84 | ||
85 | func TestSimpleStruct(t *testing.T) { | |
86 | a := simpleTest{} | |
87 | b := simpleTest{42} | |
88 | if err := Merge(&a, b); err != nil { | |
89 | t.FailNow() | |
90 | } | |
91 | if a.Value != 42 { | |
92 | t.Fatalf("b not merged in properly: a.Value(%d) != b.Value(%d)", a.Value, b.Value) | |
93 | } | |
94 | if !reflect.DeepEqual(a, b) { | |
95 | t.FailNow() | |
96 | } | |
97 | } | |
98 | ||
99 | func TestComplexStruct(t *testing.T) { | |
100 | a := complexTest{} | |
101 | a.Id = "athing" | |
102 | b := complexTest{simpleTest{42}, 1, "bthing"} | |
103 | if err := Merge(&a, b); err != nil { | |
104 | t.FailNow() | |
105 | } | |
106 | if a.St.Value != 42 { | |
107 | t.Fatalf("b not merged in properly: a.St.Value(%d) != b.St.Value(%d)", a.St.Value, b.St.Value) | |
108 | } | |
109 | if a.sz == 1 { | |
110 | t.Fatalf("a's private field sz not preserved from merge: a.sz(%d) == b.sz(%d)", a.sz, b.sz) | |
111 | } | |
112 | if a.Id == b.Id { | |
113 | t.Fatalf("a's field Id merged unexpectedly: a.Id(%s) == b.Id(%s)", a.Id, b.Id) | |
114 | } | |
115 | } | |
116 | ||
117 | func TestComplexStructWithOverwrite(t *testing.T) { | |
118 | a := complexTest{simpleTest{1}, 1, "do-not-overwrite-with-empty-value"} | |
119 | b := complexTest{simpleTest{42}, 2, ""} | |
120 | ||
121 | expect := complexTest{simpleTest{42}, 1, "do-not-overwrite-with-empty-value"} | |
122 | if err := MergeWithOverwrite(&a, b); err != nil { | |
123 | t.FailNow() | |
124 | } | |
125 | ||
126 | if !reflect.DeepEqual(a, expect) { | |
127 | t.Fatalf("Test failed:\ngot :\n%#v\n\nwant :\n%#v\n\n", a, expect) | |
128 | } | |
129 | } | |
130 | ||
131 | func TestPointerStruct(t *testing.T) { | |
132 | s1 := simpleTest{} | |
133 | s2 := simpleTest{19} | |
134 | a := pointerTest{&s1} | |
135 | b := pointerTest{&s2} | |
136 | if err := Merge(&a, b); err != nil { | |
137 | t.FailNow() | |
138 | } | |
139 | if a.C.Value != b.C.Value { | |
140 | t.Fatalf("b not merged in properly: a.C.Value(%d) != b.C.Value(%d)", a.C.Value, b.C.Value) | |
141 | } | |
142 | } | |
143 | ||
144 | type embeddingStruct struct { | |
145 | embeddedStruct | |
146 | } | |
147 | ||
148 | type embeddedStruct struct { | |
149 | A string | |
150 | } | |
151 | ||
152 | func TestEmbeddedStruct(t *testing.T) { | |
153 | tests := []struct { | |
154 | src embeddingStruct | |
155 | dst embeddingStruct | |
156 | expected embeddingStruct | |
157 | }{ | |
158 | { | |
159 | src: embeddingStruct{ | |
160 | embeddedStruct{"foo"}, | |
161 | }, | |
162 | dst: embeddingStruct{ | |
163 | embeddedStruct{""}, | |
164 | }, | |
165 | expected: embeddingStruct{ | |
166 | embeddedStruct{"foo"}, | |
167 | }, | |
168 | }, | |
169 | { | |
170 | src: embeddingStruct{ | |
171 | embeddedStruct{""}, | |
172 | }, | |
173 | dst: embeddingStruct{ | |
174 | embeddedStruct{"bar"}, | |
175 | }, | |
176 | expected: embeddingStruct{ | |
177 | embeddedStruct{"bar"}, | |
178 | }, | |
179 | }, | |
180 | { | |
181 | src: embeddingStruct{ | |
182 | embeddedStruct{"foo"}, | |
183 | }, | |
184 | dst: embeddingStruct{ | |
185 | embeddedStruct{"bar"}, | |
186 | }, | |
187 | expected: embeddingStruct{ | |
188 | embeddedStruct{"bar"}, | |
189 | }, | |
190 | }, | |
191 | } | |
192 | ||
193 | for _, test := range tests { | |
194 | err := Merge(&test.dst, test.src) | |
195 | if err != nil { | |
196 | t.Errorf("unexpected error: %v", err) | |
197 | continue | |
198 | } | |
199 | if !reflect.DeepEqual(test.dst, test.expected) { | |
200 | t.Errorf("unexpected output\nexpected:\n%+v\nsaw:\n%+v\n", test.expected, test.dst) | |
201 | } | |
202 | } | |
203 | } | |
204 | ||
205 | func TestPointerStructNil(t *testing.T) { | |
206 | a := pointerTest{nil} | |
207 | b := pointerTest{&simpleTest{19}} | |
208 | if err := Merge(&a, b); err != nil { | |
209 | t.FailNow() | |
210 | } | |
211 | if a.C.Value != b.C.Value { | |
212 | t.Fatalf("b not merged in a properly: a.C.Value(%d) != b.C.Value(%d)", a.C.Value, b.C.Value) | |
213 | } | |
214 | } | |
215 | ||
216 | func TestSliceStruct(t *testing.T) { | |
217 | a := sliceTest{} | |
218 | b := sliceTest{[]int{1, 2, 3}} | |
219 | if err := Merge(&a, b); err != nil { | |
220 | t.FailNow() | |
221 | } | |
222 | if len(b.S) != 3 { | |
223 | t.FailNow() | |
224 | } | |
225 | if len(a.S) != len(b.S) { | |
226 | t.Fatalf("b not merged in a proper way %d != %d", len(a.S), len(b.S)) | |
227 | } | |
228 | ||
229 | a = sliceTest{[]int{1}} | |
230 | b = sliceTest{[]int{1, 2, 3}} | |
231 | if err := Merge(&a, b); err != nil { | |
232 | t.FailNow() | |
233 | } | |
234 | if len(a.S) != 1 { | |
235 | t.FailNow() | |
236 | } | |
237 | if len(a.S) == len(b.S) { | |
238 | t.Fatalf("b merged unexpectedly %d != %d", len(a.S), len(b.S)) | |
239 | } | |
240 | } | |
241 | ||
242 | func TestMapsWithOverwrite(t *testing.T) { | |
243 | m := map[string]simpleTest{ | |
244 | "a": simpleTest{}, // overwritten by 16 | |
245 | "b": simpleTest{42}, // not overwritten by empty value | |
246 | "c": simpleTest{13}, // overwritten by 12 | |
247 | "d": simpleTest{61}, | |
248 | } | |
249 | n := map[string]simpleTest{ | |
250 | "a": simpleTest{16}, | |
251 | "b": simpleTest{}, | |
252 | "c": simpleTest{12}, | |
253 | "e": simpleTest{14}, | |
254 | } | |
255 | expect := map[string]simpleTest{ | |
256 | "a": simpleTest{16}, | |
257 | "b": simpleTest{}, | |
258 | "c": simpleTest{12}, | |
259 | "d": simpleTest{61}, | |
260 | "e": simpleTest{14}, | |
261 | } | |
262 | ||
263 | if err := MergeWithOverwrite(&m, n); err != nil { | |
264 | t.Fatalf(err.Error()) | |
265 | } | |
266 | ||
267 | if !reflect.DeepEqual(m, expect) { | |
268 | t.Fatalf("Test failed:\ngot :\n%#v\n\nwant :\n%#v\n\n", m, expect) | |
269 | } | |
270 | } | |
271 | ||
272 | func TestMaps(t *testing.T) { | |
273 | m := map[string]simpleTest{ | |
274 | "a": simpleTest{}, | |
275 | "b": simpleTest{42}, | |
276 | "c": simpleTest{13}, | |
277 | "d": simpleTest{61}, | |
278 | } | |
279 | n := map[string]simpleTest{ | |
280 | "a": simpleTest{16}, | |
281 | "b": simpleTest{}, | |
282 | "c": simpleTest{12}, | |
283 | "e": simpleTest{14}, | |
284 | } | |
285 | expect := map[string]simpleTest{ | |
286 | "a": simpleTest{0}, | |
287 | "b": simpleTest{42}, | |
288 | "c": simpleTest{13}, | |
289 | "d": simpleTest{61}, | |
290 | "e": simpleTest{14}, | |
291 | } | |
292 | ||
293 | if err := Merge(&m, n); err != nil { | |
294 | t.Fatalf(err.Error()) | |
295 | } | |
296 | ||
297 | if !reflect.DeepEqual(m, expect) { | |
298 | t.Fatalf("Test failed:\ngot :\n%#v\n\nwant :\n%#v\n\n", m, expect) | |
299 | } | |
300 | if m["a"].Value != 0 { | |
301 | t.Fatalf(`n merged in m because I solved non-addressable map values TODO: m["a"].Value(%d) != n["a"].Value(%d)`, m["a"].Value, n["a"].Value) | |
302 | } | |
303 | if m["b"].Value != 42 { | |
304 | t.Fatalf(`n wrongly merged in m: m["b"].Value(%d) != n["b"].Value(%d)`, m["b"].Value, n["b"].Value) | |
305 | } | |
306 | if m["c"].Value != 13 { | |
307 | t.Fatalf(`n overwritten in m: m["c"].Value(%d) != n["c"].Value(%d)`, m["c"].Value, n["c"].Value) | |
308 | } | |
309 | } |
0 | dh_auto_configure | |
1 | dh_auto_build | |
2 | dh_auto_test | |
3 | dh_prep | |
4 | dh_auto_install | |
5 | dh_installdocs | |
6 | dh_installchangelogs | |
7 | dh_perl | |
8 | dh_link | |
9 | dh_strip_nondeterminism | |
10 | dh_compress | |
11 | dh_fixperms | |
12 | dh_installdeb | |
13 | dh_golang | |
14 | dh_gencontrol | |
15 | dh_md5sums | |
16 | dh_builddeb | |
17 | dh_builddeb |
0 | Index: golang-github-imdario-mergo/mergo_test.go | |
1 | =================================================================== | |
2 | --- golang-github-imdario-mergo.orig/mergo_test.go | |
3 | +++ golang-github-imdario-mergo/mergo_test.go | |
4 | @@ -6,11 +6,8 @@ | |
5 | package mergo | |
6 | ||
7 | import ( | |
8 | - "io/ioutil" | |
9 | "reflect" | |
10 | "testing" | |
11 | - | |
12 | - "gopkg.in/yaml.v1" | |
13 | ) | |
14 | ||
15 | type simpleTest struct { | |
16 | @@ -311,131 +308,3 @@ func TestMaps(t *testing.T) { | |
17 | t.Fatalf(`n overwritten in m: m["c"].Value(%d) != n["c"].Value(%d)`, m["c"].Value, n["c"].Value) | |
18 | } | |
19 | } | |
20 | - | |
21 | -func TestYAMLMaps(t *testing.T) { | |
22 | - thing := loadYAML("testdata/thing.yml") | |
23 | - license := loadYAML("testdata/license.yml") | |
24 | - ft := thing["fields"].(map[interface{}]interface{}) | |
25 | - fl := license["fields"].(map[interface{}]interface{}) | |
26 | - expectedLength := len(ft) + len(fl) | |
27 | - if err := Merge(&license, thing); err != nil { | |
28 | - t.Fatal(err.Error()) | |
29 | - } | |
30 | - currentLength := len(license["fields"].(map[interface{}]interface{})) | |
31 | - if currentLength != expectedLength { | |
32 | - t.Fatalf(`thing not merged in license properly, license must have %d elements instead of %d`, expectedLength, currentLength) | |
33 | - } | |
34 | - fields := license["fields"].(map[interface{}]interface{}) | |
35 | - if _, ok := fields["id"]; !ok { | |
36 | - t.Fatalf(`thing not merged in license properly, license must have a new id field from thing`) | |
37 | - } | |
38 | -} | |
39 | - | |
40 | -func TestTwoPointerValues(t *testing.T) { | |
41 | - a := &simpleTest{} | |
42 | - b := &simpleTest{42} | |
43 | - if err := Merge(a, b); err != nil { | |
44 | - t.Fatalf(`Boom. You crossed the streams: %s`, err) | |
45 | - } | |
46 | -} | |
47 | - | |
48 | -func TestMap(t *testing.T) { | |
49 | - a := complexTest{} | |
50 | - a.Id = "athing" | |
51 | - c := moreComplextText{a, simpleTest{}, simpleTest{}} | |
52 | - b := map[string]interface{}{ | |
53 | - "ct": map[string]interface{}{ | |
54 | - "st": map[string]interface{}{ | |
55 | - "value": 42, | |
56 | - }, | |
57 | - "sz": 1, | |
58 | - "id": "bthing", | |
59 | - }, | |
60 | - "st": &simpleTest{144}, // Mapping a reference | |
61 | - "zt": simpleTest{299}, // Mapping a missing field (zt doesn't exist) | |
62 | - "nt": simpleTest{3}, | |
63 | - } | |
64 | - if err := Map(&c, b); err != nil { | |
65 | - t.FailNow() | |
66 | - } | |
67 | - m := b["ct"].(map[string]interface{}) | |
68 | - n := m["st"].(map[string]interface{}) | |
69 | - o := b["st"].(*simpleTest) | |
70 | - p := b["nt"].(simpleTest) | |
71 | - if c.Ct.St.Value != 42 { | |
72 | - t.Fatalf("b not merged in properly: c.Ct.St.Value(%d) != b.Ct.St.Value(%d)", c.Ct.St.Value, n["value"]) | |
73 | - } | |
74 | - if c.St.Value != 144 { | |
75 | - t.Fatalf("b not merged in properly: c.St.Value(%d) != b.St.Value(%d)", c.St.Value, o.Value) | |
76 | - } | |
77 | - if c.Nt.Value != 3 { | |
78 | - t.Fatalf("b not merged in properly: c.Nt.Value(%d) != b.Nt.Value(%d)", c.St.Value, p.Value) | |
79 | - } | |
80 | - if c.Ct.sz == 1 { | |
81 | - t.Fatalf("a's private field sz not preserved from merge: c.Ct.sz(%d) == b.Ct.sz(%d)", c.Ct.sz, m["sz"]) | |
82 | - } | |
83 | - if c.Ct.Id == m["id"] { | |
84 | - t.Fatalf("a's field Id merged unexpectedly: c.Ct.Id(%s) == b.Ct.Id(%s)", c.Ct.Id, m["id"]) | |
85 | - } | |
86 | -} | |
87 | - | |
88 | -func TestSimpleMap(t *testing.T) { | |
89 | - a := simpleTest{} | |
90 | - b := map[string]interface{}{ | |
91 | - "value": 42, | |
92 | - } | |
93 | - if err := Map(&a, b); err != nil { | |
94 | - t.FailNow() | |
95 | - } | |
96 | - if a.Value != 42 { | |
97 | - t.Fatalf("b not merged in properly: a.Value(%d) != b.Value(%v)", a.Value, b["value"]) | |
98 | - } | |
99 | -} | |
100 | - | |
101 | -type pointerMapTest struct { | |
102 | - A int | |
103 | - hidden int | |
104 | - B *simpleTest | |
105 | -} | |
106 | - | |
107 | -func TestBackAndForth(t *testing.T) { | |
108 | - pt := pointerMapTest{42, 1, &simpleTest{66}} | |
109 | - m := make(map[string]interface{}) | |
110 | - if err := Map(&m, pt); err != nil { | |
111 | - t.FailNow() | |
112 | - } | |
113 | - var ( | |
114 | - v interface{} | |
115 | - ok bool | |
116 | - ) | |
117 | - if v, ok = m["a"]; v.(int) != pt.A || !ok { | |
118 | - t.Fatalf("pt not merged in properly: m[`a`](%d) != pt.A(%d)", v, pt.A) | |
119 | - } | |
120 | - if v, ok = m["b"]; !ok { | |
121 | - t.Fatalf("pt not merged in properly: B is missing in m") | |
122 | - } | |
123 | - var st *simpleTest | |
124 | - if st = v.(*simpleTest); st.Value != 66 { | |
125 | - t.Fatalf("something went wrong while mapping pt on m, B wasn't copied") | |
126 | - } | |
127 | - bpt := pointerMapTest{} | |
128 | - if err := Map(&bpt, m); err != nil { | |
129 | - t.Fatal(err) | |
130 | - } | |
131 | - if bpt.A != pt.A { | |
132 | - t.Fatalf("pt not merged in properly: bpt.A(%d) != pt.A(%d)", bpt.A, pt.A) | |
133 | - } | |
134 | - if bpt.hidden == pt.hidden { | |
135 | - t.Fatalf("pt unexpectedly merged: bpt.hidden(%d) == pt.hidden(%d)", bpt.hidden, pt.hidden) | |
136 | - } | |
137 | - if bpt.B.Value != pt.B.Value { | |
138 | - t.Fatalf("pt not merged in properly: bpt.B.Value(%d) != pt.B.Value(%d)", bpt.B.Value, pt.B.Value) | |
139 | - } | |
140 | -} | |
141 | - | |
142 | -func loadYAML(path string) (m map[string]interface{}) { | |
143 | - m = make(map[string]interface{}) | |
144 | - raw, _ := ioutil.ReadFile(path) | |
145 | - _ = yaml.Unmarshal(raw, &m) | |
146 | - return | |
147 | -} |
0 | Index: golang-github-imdario-mergo/mergo_test.go | |
1 | =================================================================== | |
2 | --- golang-github-imdario-mergo.orig/mergo_test.go | |
3 | +++ golang-github-imdario-mergo/mergo_test.go | |
4 | @@ -10,7 +10,7 @@ import ( | |
5 | "reflect" | |
6 | "testing" | |
7 | ||
8 | - "gopkg.in/yaml.v1" | |
9 | + "launchpad.net/goyaml" | |
10 | ) | |
11 | ||
12 | type simpleTest struct { | |
13 | @@ -436,6 +436,6 @@ func TestBackAndForth(t *testing.T) { | |
14 | func loadYAML(path string) (m map[string]interface{}) { | |
15 | m = make(map[string]interface{}) | |
16 | raw, _ := ioutil.ReadFile(path) | |
17 | - _ = yaml.Unmarshal(raw, &m) | |
18 | + _ = goyaml.Unmarshal(raw, &m) | |
19 | return | |
20 | } |
0 | Index: golang-github-imdario-mergo/mergo_test.go | |
1 | =================================================================== | |
2 | --- golang-github-imdario-mergo.orig/mergo_test.go | |
3 | +++ golang-github-imdario-mergo/mergo_test.go | |
4 | @@ -10,7 +10,7 @@ import ( | |
5 | "reflect" | |
6 | "testing" | |
7 | ||
8 | - "gopkg.in/yaml.v1" | |
9 | + "gopkg.in/yaml.v2" | |
10 | ) | |
11 | ||
12 | type simpleTest struct { |
0 | 0001-disable-yaml-tests.patch |
0 | 3.0 (quilt) |
5 | 5 | package mergo |
6 | 6 | |
7 | 7 | import ( |
8 | "io/ioutil" | |
9 | 8 | "reflect" |
10 | 9 | "testing" |
11 | ||
12 | "gopkg.in/yaml.v1" | |
13 | 10 | ) |
14 | 11 | |
15 | 12 | type simpleTest struct { |
310 | 307 | t.Fatalf(`n overwritten in m: m["c"].Value(%d) != n["c"].Value(%d)`, m["c"].Value, n["c"].Value) |
311 | 308 | } |
312 | 309 | } |
313 | ||
314 | func TestYAMLMaps(t *testing.T) { | |
315 | thing := loadYAML("testdata/thing.yml") | |
316 | license := loadYAML("testdata/license.yml") | |
317 | ft := thing["fields"].(map[interface{}]interface{}) | |
318 | fl := license["fields"].(map[interface{}]interface{}) | |
319 | expectedLength := len(ft) + len(fl) | |
320 | if err := Merge(&license, thing); err != nil { | |
321 | t.Fatal(err.Error()) | |
322 | } | |
323 | currentLength := len(license["fields"].(map[interface{}]interface{})) | |
324 | if currentLength != expectedLength { | |
325 | t.Fatalf(`thing not merged in license properly, license must have %d elements instead of %d`, expectedLength, currentLength) | |
326 | } | |
327 | fields := license["fields"].(map[interface{}]interface{}) | |
328 | if _, ok := fields["id"]; !ok { | |
329 | t.Fatalf(`thing not merged in license properly, license must have a new id field from thing`) | |
330 | } | |
331 | } | |
332 | ||
333 | func TestTwoPointerValues(t *testing.T) { | |
334 | a := &simpleTest{} | |
335 | b := &simpleTest{42} | |
336 | if err := Merge(a, b); err != nil { | |
337 | t.Fatalf(`Boom. You crossed the streams: %s`, err) | |
338 | } | |
339 | } | |
340 | ||
341 | func TestMap(t *testing.T) { | |
342 | a := complexTest{} | |
343 | a.Id = "athing" | |
344 | c := moreComplextText{a, simpleTest{}, simpleTest{}} | |
345 | b := map[string]interface{}{ | |
346 | "ct": map[string]interface{}{ | |
347 | "st": map[string]interface{}{ | |
348 | "value": 42, | |
349 | }, | |
350 | "sz": 1, | |
351 | "id": "bthing", | |
352 | }, | |
353 | "st": &simpleTest{144}, // Mapping a reference | |
354 | "zt": simpleTest{299}, // Mapping a missing field (zt doesn't exist) | |
355 | "nt": simpleTest{3}, | |
356 | } | |
357 | if err := Map(&c, b); err != nil { | |
358 | t.FailNow() | |
359 | } | |
360 | m := b["ct"].(map[string]interface{}) | |
361 | n := m["st"].(map[string]interface{}) | |
362 | o := b["st"].(*simpleTest) | |
363 | p := b["nt"].(simpleTest) | |
364 | if c.Ct.St.Value != 42 { | |
365 | t.Fatalf("b not merged in properly: c.Ct.St.Value(%d) != b.Ct.St.Value(%d)", c.Ct.St.Value, n["value"]) | |
366 | } | |
367 | if c.St.Value != 144 { | |
368 | t.Fatalf("b not merged in properly: c.St.Value(%d) != b.St.Value(%d)", c.St.Value, o.Value) | |
369 | } | |
370 | if c.Nt.Value != 3 { | |
371 | t.Fatalf("b not merged in properly: c.Nt.Value(%d) != b.Nt.Value(%d)", c.St.Value, p.Value) | |
372 | } | |
373 | if c.Ct.sz == 1 { | |
374 | t.Fatalf("a's private field sz not preserved from merge: c.Ct.sz(%d) == b.Ct.sz(%d)", c.Ct.sz, m["sz"]) | |
375 | } | |
376 | if c.Ct.Id == m["id"] { | |
377 | t.Fatalf("a's field Id merged unexpectedly: c.Ct.Id(%s) == b.Ct.Id(%s)", c.Ct.Id, m["id"]) | |
378 | } | |
379 | } | |
380 | ||
381 | func TestSimpleMap(t *testing.T) { | |
382 | a := simpleTest{} | |
383 | b := map[string]interface{}{ | |
384 | "value": 42, | |
385 | } | |
386 | if err := Map(&a, b); err != nil { | |
387 | t.FailNow() | |
388 | } | |
389 | if a.Value != 42 { | |
390 | t.Fatalf("b not merged in properly: a.Value(%d) != b.Value(%v)", a.Value, b["value"]) | |
391 | } | |
392 | } | |
393 | ||
394 | type pointerMapTest struct { | |
395 | A int | |
396 | hidden int | |
397 | B *simpleTest | |
398 | } | |
399 | ||
400 | func TestBackAndForth(t *testing.T) { | |
401 | pt := pointerMapTest{42, 1, &simpleTest{66}} | |
402 | m := make(map[string]interface{}) | |
403 | if err := Map(&m, pt); err != nil { | |
404 | t.FailNow() | |
405 | } | |
406 | var ( | |
407 | v interface{} | |
408 | ok bool | |
409 | ) | |
410 | if v, ok = m["a"]; v.(int) != pt.A || !ok { | |
411 | t.Fatalf("pt not merged in properly: m[`a`](%d) != pt.A(%d)", v, pt.A) | |
412 | } | |
413 | if v, ok = m["b"]; !ok { | |
414 | t.Fatalf("pt not merged in properly: B is missing in m") | |
415 | } | |
416 | var st *simpleTest | |
417 | if st = v.(*simpleTest); st.Value != 66 { | |
418 | t.Fatalf("something went wrong while mapping pt on m, B wasn't copied") | |
419 | } | |
420 | bpt := pointerMapTest{} | |
421 | if err := Map(&bpt, m); err != nil { | |
422 | t.Fatal(err) | |
423 | } | |
424 | if bpt.A != pt.A { | |
425 | t.Fatalf("pt not merged in properly: bpt.A(%d) != pt.A(%d)", bpt.A, pt.A) | |
426 | } | |
427 | if bpt.hidden == pt.hidden { | |
428 | t.Fatalf("pt unexpectedly merged: bpt.hidden(%d) == pt.hidden(%d)", bpt.hidden, pt.hidden) | |
429 | } | |
430 | if bpt.B.Value != pt.B.Value { | |
431 | t.Fatalf("pt not merged in properly: bpt.B.Value(%d) != pt.B.Value(%d)", bpt.B.Value, pt.B.Value) | |
432 | } | |
433 | } | |
434 | ||
435 | func loadYAML(path string) (m map[string]interface{}) { | |
436 | m = make(map[string]interface{}) | |
437 | raw, _ := ioutil.ReadFile(path) | |
438 | _ = yaml.Unmarshal(raw, &m) | |
439 | return | |
440 | } |