github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/juju/common/format_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package common_test 5 6 import ( 7 "time" 8 9 "github.com/juju/testing" 10 jc "github.com/juju/testing/checkers" 11 gc "gopkg.in/check.v1" 12 13 "github.com/juju/juju/cmd/juju/common" 14 ) 15 16 type FormatTimeSuite struct{} 17 18 var _ = gc.Suite(&FormatTimeSuite{}) 19 20 func (s *FormatTimeSuite) TestFormatTime(c *gc.C) { 21 now := time.Now().Round(time.Second) 22 utcFormat := "2006-01-02 15:04:05Z" 23 localFormat := "02 Jan 2006 15:04:05Z07:00" 24 var tests = []struct { 25 description string 26 input time.Time 27 isoTime bool 28 outputFormat string 29 output string 30 }{ 31 { 32 description: "ISOTime conforms to the correct layout", 33 input: now, 34 isoTime: true, 35 outputFormat: utcFormat, 36 output: now.UTC().Format(utcFormat), 37 }, 38 { 39 description: "Time conforms to the correct layout", 40 input: now, 41 isoTime: false, 42 outputFormat: localFormat, 43 output: now.Local().Format(localFormat), 44 }, 45 } 46 for i, test := range tests { 47 c.Logf("test %d: %s", i, test.description) 48 formatted := common.FormatTime(&test.input, test.isoTime) 49 parsed, err := time.Parse(test.outputFormat, formatted) 50 c.Assert(err, jc.ErrorIsNil) 51 c.Assert(parsed, jc.DeepEquals, test.input) 52 } 53 } 54 55 type FormatTimeAsTimestampSuite struct{} 56 57 var _ = gc.Suite(&FormatTimeAsTimestampSuite{}) 58 59 func (s *FormatTimeAsTimestampSuite) TestFormatTimeAsTimestamp(c *gc.C) { 60 now := time.Now().Round(time.Second) 61 utcFormat := "15:04:05" 62 localFormat := "15:04:05Z07:00" 63 var tests = []struct { 64 description string 65 input time.Time 66 isoTime bool 67 outputFormat string 68 output string 69 }{ 70 { 71 description: "ISOTime conforms to the correct layout", 72 input: now, 73 isoTime: true, 74 outputFormat: utcFormat, 75 output: now.UTC().Format(utcFormat), 76 }, 77 { 78 description: "Time conforms to the correct layout", 79 input: now, 80 isoTime: false, 81 outputFormat: localFormat, 82 output: now.UTC().Format(localFormat), 83 }, 84 } 85 for i, test := range tests { 86 c.Logf("test %d: %s", i, test.description) 87 formatted := common.FormatTimeAsTimestamp(&test.input, test.isoTime) 88 parsed, err := time.Parse(test.outputFormat, formatted) 89 c.Assert(err, jc.ErrorIsNil) 90 91 expected := test.input.Local() 92 if test.isoTime { 93 expected = test.input.UTC() 94 } 95 c.Assert(parsed.Format(test.outputFormat), jc.DeepEquals, expected.Format(test.outputFormat)) 96 } 97 } 98 99 type ConformSuite struct{} 100 101 var _ = gc.Suite(&ConformSuite{}) 102 103 func (s *ConformSuite) TestConformYAML(c *gc.C) { 104 var goodInterfaceTests = []struct { 105 description string 106 inputInterface interface{} 107 expectedInterface map[string]interface{} 108 expectedError string 109 }{{ 110 description: "An interface requiring no changes.", 111 inputInterface: map[string]interface{}{ 112 "key1": "value1", 113 "key2": "value2", 114 "key3": map[string]interface{}{ 115 "foo1": "val1", 116 "foo2": "val2"}}, 117 expectedInterface: map[string]interface{}{ 118 "key1": "value1", 119 "key2": "value2", 120 "key3": map[string]interface{}{ 121 "foo1": "val1", 122 "foo2": "val2"}}, 123 }, { 124 description: "Substitute a single inner map[i]i.", 125 inputInterface: map[string]interface{}{ 126 "key1": "value1", 127 "key2": "value2", 128 "key3": map[interface{}]interface{}{ 129 "foo1": "val1", 130 "foo2": "val2"}}, 131 expectedInterface: map[string]interface{}{ 132 "key1": "value1", 133 "key2": "value2", 134 "key3": map[string]interface{}{ 135 "foo1": "val1", 136 "foo2": "val2"}}, 137 }, { 138 description: "Substitute nested inner map[i]i.", 139 inputInterface: map[string]interface{}{ 140 "key1a": "val1a", 141 "key2a": "val2a", 142 "key3a": map[interface{}]interface{}{ 143 "key1b": "val1b", 144 "key2b": map[interface{}]interface{}{ 145 "key1c": "val1c"}}}, 146 expectedInterface: map[string]interface{}{ 147 "key1a": "val1a", 148 "key2a": "val2a", 149 "key3a": map[string]interface{}{ 150 "key1b": "val1b", 151 "key2b": map[string]interface{}{ 152 "key1c": "val1c"}}}, 153 }, { 154 description: "Substitute nested map[i]i within []i.", 155 inputInterface: map[string]interface{}{ 156 "key1a": "val1a", 157 "key2a": []interface{}{5, "foo", map[string]interface{}{ 158 "key1b": "val1b", 159 "key2b": map[interface{}]interface{}{ 160 "key1c": "val1c"}}}}, 161 expectedInterface: map[string]interface{}{ 162 "key1a": "val1a", 163 "key2a": []interface{}{5, "foo", map[string]interface{}{ 164 "key1b": "val1b", 165 "key2b": map[string]interface{}{ 166 "key1c": "val1c"}}}}, 167 }, { 168 description: "An inner map[interface{}]interface{} with an int key.", 169 inputInterface: map[string]interface{}{ 170 "key1": "value1", 171 "key2": "value2", 172 "key3": map[interface{}]interface{}{ 173 "foo1": "val1", 174 5: "val2"}}, 175 expectedError: "map keyed with non-string value", 176 }, { 177 description: "An inner []interface{} containing a map[i]i with an int key.", 178 inputInterface: map[string]interface{}{ 179 "key1a": "val1b", 180 "key2a": "val2b", 181 "key3a": []interface{}{"foo1", 5, map[interface{}]interface{}{ 182 "key1b": "val1b", 183 "key2b": map[interface{}]interface{}{ 184 "key1c": "val1c", 185 5: "val2c"}}}}, 186 expectedError: "map keyed with non-string value", 187 }} 188 189 for i, test := range goodInterfaceTests { 190 c.Logf("test %d: %s", i, test.description) 191 input := test.inputInterface 192 cleansedInterfaceMap, err := common.ConformYAML(input) 193 if test.expectedError == "" { 194 if !c.Check(err, jc.ErrorIsNil) { 195 continue 196 } 197 c.Check(cleansedInterfaceMap, gc.DeepEquals, test.expectedInterface) 198 } else { 199 c.Check(err, gc.ErrorMatches, test.expectedError) 200 } 201 } 202 } 203 204 type userFriendlyDurationSuite struct { 205 testing.IsolationSuite 206 } 207 208 var _ = gc.Suite(&userFriendlyDurationSuite{}) 209 210 func (*userFriendlyDurationSuite) TestFormat(c *gc.C) { 211 // lp:1558657 212 now := time.Now() 213 for _, test := range []struct { 214 other time.Time 215 expected string 216 }{ 217 { 218 other: now, 219 expected: "just now", 220 }, { 221 other: now.Add(-1 * time.Second), 222 expected: "just now", 223 }, { 224 other: now.Add(-2 * time.Second), 225 expected: "2 seconds ago", 226 }, { 227 other: now.Add(-59 * time.Second), 228 expected: "59 seconds ago", 229 }, { 230 other: now.Add(-60 * time.Second), 231 expected: "1 minute ago", 232 }, { 233 other: now.Add(-61 * time.Second), 234 expected: "1 minute ago", 235 }, { 236 other: now.Add(-2 * time.Minute), 237 expected: "2 minutes ago", 238 }, { 239 other: now.Add(-59 * time.Minute), 240 expected: "59 minutes ago", 241 }, { 242 other: now.Add(-60 * time.Minute), 243 expected: "1 hour ago", 244 }, { 245 other: now.Add(-61 * time.Minute), 246 expected: "1 hour ago", 247 }, { 248 other: now.Add(-2 * time.Hour), 249 expected: "2 hours ago", 250 }, { 251 other: now.Add(-23 * time.Hour), 252 expected: "23 hours ago", 253 }, { 254 other: now.Add(-24 * time.Hour), 255 expected: now.Add(-24 * time.Hour).Format("2006-01-02"), 256 }, { 257 other: now.Add(-96 * time.Hour), 258 expected: now.Add(-96 * time.Hour).Format("2006-01-02"), 259 }, 260 } { 261 obtained := common.UserFriendlyDuration(test.other, now) 262 c.Check(obtained, gc.Equals, test.expected) 263 } 264 }