github.com/willmadison/cli@v6.40.1-0.20181018160101-29d5937903ff+incompatible/util/ui/ui_test.go (about) 1 package ui_test 2 3 import ( 4 "errors" 5 "time" 6 7 "code.cloudfoundry.org/cli/command/translatableerror/translatableerrorfakes" 8 "code.cloudfoundry.org/cli/util/configv3" 9 . "code.cloudfoundry.org/cli/util/ui" 10 "code.cloudfoundry.org/cli/util/ui/uifakes" 11 . "github.com/onsi/ginkgo" 12 . "github.com/onsi/gomega" 13 . "github.com/onsi/gomega/gbytes" 14 ) 15 16 var _ = Describe("UI", func() { 17 var ( 18 ui *UI 19 fakeConfig *uifakes.FakeConfig 20 out *Buffer 21 errBuff *Buffer 22 ) 23 24 BeforeEach(func() { 25 fakeConfig = new(uifakes.FakeConfig) 26 fakeConfig.ColorEnabledReturns(configv3.ColorEnabled) 27 28 var err error 29 ui, err = NewUI(fakeConfig) 30 Expect(err).NotTo(HaveOccurred()) 31 32 out = NewBuffer() 33 ui.Out = out 34 ui.OutForInteration = out 35 errBuff = NewBuffer() 36 ui.Err = errBuff 37 }) 38 39 Describe("DisplayError", func() { 40 When("passed a TranslatableError", func() { 41 var fakeTranslateErr *translatableerrorfakes.FakeTranslatableError 42 43 BeforeEach(func() { 44 fakeTranslateErr = new(translatableerrorfakes.FakeTranslatableError) 45 fakeTranslateErr.TranslateReturns("I am an error") 46 47 ui.DisplayError(fakeTranslateErr) 48 }) 49 50 It("displays the error to ui.Err and displays FAILED in bold red to ui.Out", func() { 51 Expect(ui.Err).To(Say("I am an error\n")) 52 Expect(out).To(Say("\x1b\\[31;1mFAILED\x1b\\[0m\n")) 53 }) 54 55 When("the locale is not set to english", func() { 56 It("translates the error text", func() { 57 Expect(fakeTranslateErr.TranslateCallCount()).To(Equal(1)) 58 Expect(fakeTranslateErr.TranslateArgsForCall(0)).NotTo(BeNil()) 59 }) 60 }) 61 }) 62 63 When("passed a generic error", func() { 64 It("displays the error text to ui.Err and displays FAILED in bold red to ui.Out", func() { 65 ui.DisplayError(errors.New("I am a BANANA!")) 66 Expect(ui.Err).To(Say("I am a BANANA!\n")) 67 Expect(out).To(Say("\x1b\\[31;1mFAILED\x1b\\[0m\n")) 68 }) 69 }) 70 }) 71 72 Describe("DisplayHeader", func() { 73 It("displays the header colorized and bolded to ui.Out", func() { 74 ui.DisplayHeader("some-header") 75 Expect(out).To(Say("\x1b\\[1msome-header\x1b\\[0m")) 76 }) 77 78 When("the locale is not set to English", func() { 79 BeforeEach(func() { 80 fakeConfig.LocaleReturns("fr-FR") 81 82 var err error 83 ui, err = NewUI(fakeConfig) 84 Expect(err).NotTo(HaveOccurred()) 85 86 ui.Out = out 87 }) 88 89 It("displays the translated header colorized and bolded to ui.Out", func() { 90 ui.DisplayHeader("FEATURE FLAGS") 91 Expect(out).To(Say("\x1b\\[1mINDICATEURS DE FONCTION\x1b\\[0m")) 92 }) 93 }) 94 }) 95 96 Describe("DisplayNewline", func() { 97 It("displays a new line", func() { 98 ui.DisplayNewline() 99 Expect(out).To(Say("\n")) 100 }) 101 }) 102 103 Describe("DisplayOK", func() { 104 It("displays 'OK' in green and bold", func() { 105 ui.DisplayOK() 106 Expect(out).To(Say("\x1b\\[32;1mOK\x1b\\[0m")) 107 }) 108 }) 109 110 // Covers the happy paths, additional cases are tested in TranslateText 111 Describe("DisplayText", func() { 112 It("displays the template with map values substituted in to ui.Out with a newline", func() { 113 ui.DisplayText( 114 "template with {{.SomeMapValue}}", 115 map[string]interface{}{ 116 "SomeMapValue": "map-value", 117 }) 118 Expect(out).To(Say("template with map-value\n")) 119 }) 120 121 When("the locale is not set to english", func() { 122 BeforeEach(func() { 123 fakeConfig.LocaleReturns("fr-FR") 124 125 var err error 126 ui, err = NewUI(fakeConfig) 127 Expect(err).NotTo(HaveOccurred()) 128 129 ui.Out = out 130 }) 131 132 It("displays the translated template with map values substituted in to ui.Out", func() { 133 ui.DisplayText( 134 "\nTIP: Use '{{.Command}}' to target new org", 135 map[string]interface{}{ 136 "Command": "foo", 137 }) 138 Expect(out).To(Say("\nASTUCE : utilisez 'foo' pour cibler une nouvelle organisation")) 139 }) 140 }) 141 }) 142 143 Describe("DisplayTextWithBold", func() { 144 It("displays the template to ui.Out", func() { 145 ui.DisplayTextWithBold("some-template") 146 Expect(out).To(Say("some-template")) 147 }) 148 149 When("an optional map is passed in", func() { 150 It("displays the template with map values bolded and substituted in to ui.Out", func() { 151 ui.DisplayTextWithBold( 152 "template with {{.SomeMapValue}}", 153 map[string]interface{}{ 154 "SomeMapValue": "map-value", 155 }) 156 Expect(out).To(Say("template with \x1b\\[1mmap-value\x1b\\[0m")) 157 }) 158 }) 159 160 When("multiple optional maps are passed in", func() { 161 It("displays the template with only the first map values bolded and substituted in to ui.Out", func() { 162 ui.DisplayTextWithBold( 163 "template with {{.SomeMapValue}} and {{.SomeOtherMapValue}}", 164 map[string]interface{}{ 165 "SomeMapValue": "map-value", 166 }, 167 map[string]interface{}{ 168 "SomeOtherMapValue": "other-map-value", 169 }) 170 Expect(out).To(Say("template with \x1b\\[1mmap-value\x1b\\[0m and <no value>")) 171 }) 172 }) 173 174 When("the locale is not set to english", func() { 175 BeforeEach(func() { 176 fakeConfig.LocaleReturns("fr-FR") 177 178 var err error 179 ui, err = NewUI(fakeConfig) 180 Expect(err).NotTo(HaveOccurred()) 181 182 ui.Out = out 183 }) 184 185 It("displays the translated template with map values bolded and substituted in to ui.Out", func() { 186 ui.DisplayTextWithBold( 187 "App {{.AppName}} does not exist.", 188 map[string]interface{}{ 189 "AppName": "some-app-name", 190 }) 191 Expect(out).To(Say("L'application \x1b\\[1msome-app-name\x1b\\[0m n'existe pas.\n")) 192 }) 193 }) 194 }) 195 196 Describe("DisplayTextWithFlavor", func() { 197 It("displays the template to ui.Out", func() { 198 ui.DisplayTextWithFlavor("some-template") 199 Expect(out).To(Say("some-template")) 200 }) 201 202 When("an optional map is passed in", func() { 203 It("displays the template with map values colorized, bolded, and substituted in to ui.Out", func() { 204 ui.DisplayTextWithFlavor( 205 "template with {{.SomeMapValue}}", 206 map[string]interface{}{ 207 "SomeMapValue": "map-value", 208 }) 209 Expect(out).To(Say("template with \x1b\\[36;1mmap-value\x1b\\[0m")) 210 }) 211 }) 212 213 When("multiple optional maps are passed in", func() { 214 It("displays the template with only the first map values colorized, bolded, and substituted in to ui.Out", func() { 215 ui.DisplayTextWithFlavor( 216 "template with {{.SomeMapValue}} and {{.SomeOtherMapValue}}", 217 map[string]interface{}{ 218 "SomeMapValue": "map-value", 219 }, 220 map[string]interface{}{ 221 "SomeOtherMapValue": "other-map-value", 222 }) 223 Expect(out).To(Say("template with \x1b\\[36;1mmap-value\x1b\\[0m and <no value>")) 224 }) 225 }) 226 227 When("the locale is not set to english", func() { 228 BeforeEach(func() { 229 fakeConfig.LocaleReturns("fr-FR") 230 231 var err error 232 ui, err = NewUI(fakeConfig) 233 Expect(err).NotTo(HaveOccurred()) 234 235 ui.Out = out 236 }) 237 238 It("displays the translated template with map values colorized, bolded and substituted in to ui.Out", func() { 239 ui.DisplayTextWithFlavor( 240 "App {{.AppName}} does not exist.", 241 map[string]interface{}{ 242 "AppName": "some-app-name", 243 }) 244 Expect(out).To(Say("L'application \x1b\\[36;1msome-app-name\x1b\\[0m n'existe pas.\n")) 245 }) 246 }) 247 }) 248 249 // Covers the happy paths, additional cases are tested in TranslateText 250 Describe("DisplayWarning", func() { 251 It("displays the warning to ui.Err", func() { 252 ui.DisplayWarning( 253 "template with {{.SomeMapValue}}", 254 map[string]interface{}{ 255 "SomeMapValue": "map-value", 256 }) 257 Expect(ui.Err).To(Say("template with map-value\n\n")) 258 }) 259 260 When("the locale is not set to english", func() { 261 BeforeEach(func() { 262 fakeConfig.LocaleReturns("fr-FR") 263 264 var err error 265 ui, err = NewUI(fakeConfig) 266 Expect(err).NotTo(HaveOccurred()) 267 268 ui.Err = NewBuffer() 269 }) 270 271 It("displays the translated warning to ui.Err", func() { 272 ui.DisplayWarning( 273 "'{{.VersionShort}}' and '{{.VersionLong}}' are also accepted.", 274 map[string]interface{}{ 275 "VersionShort": "some-value", 276 "VersionLong": "some-other-value", 277 }) 278 Expect(ui.Err).To(Say("'some-value' et 'some-other-value' sont également acceptés.\n")) 279 }) 280 }) 281 }) 282 283 // Covers the happy paths, additional cases are tested in TranslateText 284 Describe("DisplayWarnings", func() { 285 It("displays the warnings to ui.Err", func() { 286 ui.DisplayWarnings([]string{"warning-1", "warning-2"}) 287 Expect(ui.Err).To(Say("warning-1\n")) 288 Expect(ui.Err).To(Say("warning-2\n")) 289 Expect(ui.Err).To(Say("\n")) 290 }) 291 292 When("the locale is not set to english", func() { 293 BeforeEach(func() { 294 fakeConfig.LocaleReturns("fr-FR") 295 296 var err error 297 ui, err = NewUI(fakeConfig) 298 Expect(err).NotTo(HaveOccurred()) 299 300 ui.Err = NewBuffer() 301 }) 302 303 It("displays the translated warnings to ui.Err", func() { 304 ui.DisplayWarnings([]string{"Also delete any mapped routes", "FEATURE FLAGS"}) 305 Expect(ui.Err).To(Say("Supprimer aussi les routes mappées\n")) 306 Expect(ui.Err).To(Say("INDICATEURS DE FONCTION\n")) 307 Expect(ui.Err).To(Say("\n")) 308 }) 309 }) 310 311 Context("does not display newline when warnings are empty", func() { 312 It("does not print out a new line", func() { 313 ui.DisplayWarnings(nil) 314 Expect(errBuff.Contents()).To(BeEmpty()) 315 }) 316 }) 317 }) 318 319 Describe("TranslateText", func() { 320 It("returns the template", func() { 321 Expect(ui.TranslateText("some-template")).To(Equal("some-template")) 322 }) 323 324 When("an optional map is passed in", func() { 325 It("returns the template with map values substituted in", func() { 326 expected := ui.TranslateText( 327 "template {{.SomeMapValue}}", 328 map[string]interface{}{ 329 "SomeMapValue": "map-value", 330 }) 331 Expect(expected).To(Equal("template map-value")) 332 }) 333 }) 334 335 When("multiple optional maps are passed in", func() { 336 It("returns the template with only the first map values substituted in", func() { 337 expected := ui.TranslateText( 338 "template with {{.SomeMapValue}} and {{.SomeOtherMapValue}}", 339 map[string]interface{}{ 340 "SomeMapValue": "map-value", 341 }, 342 map[string]interface{}{ 343 "SomeOtherMapValue": "other-map-value", 344 }) 345 Expect(expected).To(Equal("template with map-value and <no value>")) 346 }) 347 }) 348 349 When("the locale is not set to english", func() { 350 BeforeEach(func() { 351 fakeConfig.LocaleReturns("fr-FR") 352 353 var err error 354 ui, err = NewUI(fakeConfig) 355 Expect(err).NotTo(HaveOccurred()) 356 }) 357 358 It("returns the translated template", func() { 359 expected := ui.TranslateText(" View allowable quotas with 'CF_NAME quotas'") 360 Expect(expected).To(Equal(" Affichez les quotas pouvant être alloués avec 'CF_NAME quotas'")) 361 }) 362 }) 363 }) 364 365 Describe("UserFriendlyDate", func() { 366 It("formats a time into an ISO8601 string", func() { 367 Expect(ui.UserFriendlyDate(time.Unix(0, 0))).To(MatchRegexp("\\w{3} [0-3]\\d \\w{3} [0-2]\\d:[0-5]\\d:[0-5]\\d \\w+ \\d{4}")) 368 }) 369 }) 370 })