github.com/bilus/oya@v0.0.3-0.20190301162104-da4acbd394c6/pkg/template/scope_test.go (about) 1 package template_test 2 3 import ( 4 "encoding/gob" 5 "os" 6 "testing" 7 8 "github.com/bilus/oya/pkg/template" 9 tu "github.com/bilus/oya/testutil" 10 ) 11 12 func identity(scope template.Scope) template.Scope { 13 return scope 14 } 15 16 func mutation(scope template.Scope) template.Scope { 17 scope["bar"] = "baz" 18 return scope 19 } 20 21 func merge(scope template.Scope) template.Scope { 22 return scope.Merge(template.Scope{"bar": "baz"}) 23 } 24 25 func deepcopy(dst, src interface{}) error { 26 r, w, err := os.Pipe() 27 if err != nil { 28 return err 29 } 30 enc := gob.NewEncoder(w) 31 err = enc.Encode(src) 32 if err != nil { 33 return err 34 } 35 dec := gob.NewDecoder(r) 36 return dec.Decode(dst) 37 } 38 39 func TestScope_UpdateScopeAt(t *testing.T) { 40 testCases := []struct { 41 desc string 42 scope template.Scope 43 path string 44 f func(template.Scope) template.Scope 45 expectedScope template.Scope 46 }{ 47 { 48 desc: "empty path, return original", 49 scope: template.Scope{}, 50 path: "", 51 f: identity, 52 expectedScope: template.Scope{}, 53 }, 54 { 55 desc: "empty path, make an in-place update", 56 scope: template.Scope{}, 57 path: "", 58 f: mutation, 59 expectedScope: template.Scope{ 60 "bar": "baz", 61 }, 62 }, 63 { 64 desc: "empty path, return updated copy", 65 scope: template.Scope{}, 66 path: "", 67 f: merge, 68 expectedScope: template.Scope{ 69 "bar": "baz", 70 }, 71 }, 72 { 73 desc: "non-existent path, return original", 74 scope: template.Scope{}, 75 path: "foo", 76 f: identity, 77 expectedScope: template.Scope{ 78 "foo": template.Scope{}, 79 }, 80 }, 81 { 82 desc: "non-existent path, make an in-place update", 83 scope: template.Scope{}, 84 path: "foo", 85 f: mutation, 86 expectedScope: template.Scope{ 87 "foo": template.Scope{ 88 "bar": "baz", 89 }, 90 }, 91 }, 92 { 93 desc: "non-existent path, return updated copy", 94 scope: template.Scope{}, 95 path: "foo", 96 f: merge, 97 expectedScope: template.Scope{ 98 "foo": template.Scope{ 99 "bar": "baz", 100 }, 101 }, 102 }, 103 { 104 desc: "non-existent deep path, return original", 105 scope: template.Scope{}, 106 path: "foo.xxx.yyy", 107 f: identity, 108 expectedScope: template.Scope{ 109 "foo": template.Scope{ 110 "xxx": template.Scope{ 111 "yyy": template.Scope{}, 112 }, 113 }, 114 }, 115 }, 116 { 117 desc: "non-existent path, make an in-place update", 118 scope: template.Scope{}, 119 path: "foo.xxx.yyy", 120 f: mutation, 121 expectedScope: template.Scope{ 122 "foo": template.Scope{ 123 "xxx": template.Scope{ 124 "yyy": template.Scope{ 125 "bar": "baz", 126 }, 127 }, 128 }, 129 }, 130 }, 131 { 132 desc: "non-existent path, return updated copy", 133 scope: template.Scope{}, 134 path: "foo.xxx.yyy", 135 f: merge, 136 expectedScope: template.Scope{ 137 "foo": template.Scope{ 138 "xxx": template.Scope{ 139 "yyy": template.Scope{ 140 "bar": "baz", 141 }, 142 }, 143 }, 144 }, 145 }, 146 } 147 148 for _, tc := range testCases { 149 var scope template.Scope 150 err := deepcopy(&scope, tc.scope) // Because f can mutate it. 151 tu.AssertNoErr(t, err, "deepcopy failed") 152 err = scope.UpdateScopeAt(tc.path, tc.f) 153 tu.AssertNoErr(t, err, "UpdateScopeAt failed in test case %q", tc.desc) 154 tu.AssertObjectsEqualMsg(t, tc.expectedScope, scope, "In test case %q", tc.desc) 155 } 156 }