github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/cmd/juju/action/common_test.go (about) 1 // Copyright 2014-2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 // This is necessary since it must test a recursive unexported function, 5 // i.e., the function cannot be exported via a var 6 package action 7 8 import ( 9 jc "github.com/juju/testing/checkers" 10 gc "gopkg.in/check.v1" 11 ) 12 13 type CommonSuite struct{} 14 15 var _ = gc.Suite(&CommonSuite{}) 16 17 func (s *CommonSuite) TestConform(c *gc.C) { 18 var goodInterfaceTests = []struct { 19 description string 20 inputInterface interface{} 21 expectedInterface map[string]interface{} 22 expectedError string 23 }{{ 24 description: "An interface requiring no changes.", 25 inputInterface: map[string]interface{}{ 26 "key1": "value1", 27 "key2": "value2", 28 "key3": map[string]interface{}{ 29 "foo1": "val1", 30 "foo2": "val2"}}, 31 expectedInterface: map[string]interface{}{ 32 "key1": "value1", 33 "key2": "value2", 34 "key3": map[string]interface{}{ 35 "foo1": "val1", 36 "foo2": "val2"}}, 37 }, { 38 description: "Substitute a single inner map[i]i.", 39 inputInterface: map[string]interface{}{ 40 "key1": "value1", 41 "key2": "value2", 42 "key3": map[interface{}]interface{}{ 43 "foo1": "val1", 44 "foo2": "val2"}}, 45 expectedInterface: map[string]interface{}{ 46 "key1": "value1", 47 "key2": "value2", 48 "key3": map[string]interface{}{ 49 "foo1": "val1", 50 "foo2": "val2"}}, 51 }, { 52 description: "Substitute nested inner map[i]i.", 53 inputInterface: map[string]interface{}{ 54 "key1a": "val1a", 55 "key2a": "val2a", 56 "key3a": map[interface{}]interface{}{ 57 "key1b": "val1b", 58 "key2b": map[interface{}]interface{}{ 59 "key1c": "val1c"}}}, 60 expectedInterface: map[string]interface{}{ 61 "key1a": "val1a", 62 "key2a": "val2a", 63 "key3a": map[string]interface{}{ 64 "key1b": "val1b", 65 "key2b": map[string]interface{}{ 66 "key1c": "val1c"}}}, 67 }, { 68 description: "Substitute nested map[i]i within []i.", 69 inputInterface: map[string]interface{}{ 70 "key1a": "val1a", 71 "key2a": []interface{}{5, "foo", map[string]interface{}{ 72 "key1b": "val1b", 73 "key2b": map[interface{}]interface{}{ 74 "key1c": "val1c"}}}}, 75 expectedInterface: map[string]interface{}{ 76 "key1a": "val1a", 77 "key2a": []interface{}{5, "foo", map[string]interface{}{ 78 "key1b": "val1b", 79 "key2b": map[string]interface{}{ 80 "key1c": "val1c"}}}}, 81 }, { 82 description: "An inner map[interface{}]interface{} with an int key.", 83 inputInterface: map[string]interface{}{ 84 "key1": "value1", 85 "key2": "value2", 86 "key3": map[interface{}]interface{}{ 87 "foo1": "val1", 88 5: "val2"}}, 89 expectedError: "map keyed with non-string value", 90 }, { 91 description: "An inner []interface{} containing a map[i]i with an int key.", 92 inputInterface: map[string]interface{}{ 93 "key1a": "val1b", 94 "key2a": "val2b", 95 "key3a": []interface{}{"foo1", 5, map[interface{}]interface{}{ 96 "key1b": "val1b", 97 "key2b": map[interface{}]interface{}{ 98 "key1c": "val1c", 99 5: "val2c"}}}}, 100 expectedError: "map keyed with non-string value", 101 }} 102 103 for i, test := range goodInterfaceTests { 104 c.Logf("test %d: %s", i, test.description) 105 input := test.inputInterface 106 cleansedInterfaceMap, err := conform(input) 107 if test.expectedError == "" { 108 if !c.Check(err, jc.ErrorIsNil) { 109 continue 110 } 111 c.Check(cleansedInterfaceMap, gc.DeepEquals, test.expectedInterface) 112 } else { 113 c.Check(err, gc.ErrorMatches, test.expectedError) 114 } 115 } 116 } 117 118 type insertSliceValue struct { 119 valuePath []string 120 value interface{} 121 } 122 123 func (s *CommonSuite) TestAddValueToMap(c *gc.C) { 124 for i, t := range []struct { 125 should string 126 startingMap map[string]interface{} 127 insertSlices []insertSliceValue 128 expectedMap map[string]interface{} 129 }{{ 130 should: "insert a couple of values", 131 startingMap: map[string]interface{}{ 132 "foo": "bar", 133 "bar": map[string]interface{}{ 134 "baz": "bo", 135 "bur": "bor", 136 }, 137 }, 138 insertSlices: []insertSliceValue{ 139 { 140 valuePath: []string{"well", "now"}, 141 value: 5, 142 }, 143 { 144 valuePath: []string{"foo"}, 145 value: "kek", 146 }, 147 }, 148 expectedMap: map[string]interface{}{ 149 "foo": "kek", 150 "bar": map[string]interface{}{ 151 "baz": "bo", 152 "bur": "bor", 153 }, 154 "well": map[string]interface{}{ 155 "now": 5, 156 }, 157 }, 158 }} { 159 c.Logf("test %d: should %s", i, t.should) 160 for _, sVal := range t.insertSlices { 161 addValueToMap(sVal.valuePath, sVal.value, t.startingMap) 162 } 163 // note addValueToMap mutates target. 164 c.Check(t.startingMap, jc.DeepEquals, t.expectedMap) 165 } 166 }