github.com/cloudfoundry/cli@v7.1.0+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("DisplayDeprecationWarning", func() { 40 It("displays the deprecation warning to ui.Err", func() { 41 ui.DisplayDeprecationWarning() 42 Expect(ui.Err).To(Say("Deprecation warning: This command has been deprecated. This feature will be removed in the future.\n")) 43 }) 44 45 When("the locale is not set to English", func() { 46 BeforeEach(func() { 47 fakeConfig.LocaleReturns("fr-FR") 48 49 var err error 50 ui, err = NewUI(fakeConfig) 51 Expect(err).NotTo(HaveOccurred()) 52 53 ui.Err = NewBuffer() 54 }) 55 56 PIt("displays the translated deprecation warning to ui.Err", func() { 57 // TODO: Test implementation awaits translated version of deprecation warning string literal #164098152. 58 }) 59 }) 60 }) 61 62 Describe("DisplayFileDeprecationWarning", func() { 63 It("displays the `cf files` deprecation warning to ui.Err", func() { 64 ui.DisplayFileDeprecationWarning() 65 Expect(ui.Err).To(Say("Deprecation warning: This command has been deprecated and will be removed in the future. For similar functionality, please use the `cf ssh` command instead.\n")) 66 }) 67 68 When("the locale is not set to English", func() { 69 BeforeEach(func() { 70 fakeConfig.LocaleReturns("fr-FR") 71 72 var err error 73 ui, err = NewUI(fakeConfig) 74 Expect(err).NotTo(HaveOccurred()) 75 76 ui.Err = NewBuffer() 77 }) 78 79 PIt("displays the translated deprecation warning to ui.Err", func() { 80 // TODO: Test implementation awaits translated version of deprecation warning string literal #164098103. 81 }) 82 }) 83 }) 84 85 Describe("DisplayError", func() { 86 When("passed a TranslatableError", func() { 87 var fakeTranslateErr *translatableerrorfakes.FakeTranslatableError 88 89 BeforeEach(func() { 90 fakeTranslateErr = new(translatableerrorfakes.FakeTranslatableError) 91 fakeTranslateErr.TranslateReturns("I am an error") 92 93 ui.DisplayError(fakeTranslateErr) 94 }) 95 96 It("displays the error to ui.Err and displays FAILED in bold red to ui.Out", func() { 97 Expect(ui.Err).To(Say("I am an error\n")) 98 Expect(out).To(Say("\x1b\\[31;1mFAILED\x1b\\[0m\n")) 99 }) 100 101 When("the locale is not set to english", func() { 102 It("translates the error text", func() { 103 Expect(fakeTranslateErr.TranslateCallCount()).To(Equal(1)) 104 Expect(fakeTranslateErr.TranslateArgsForCall(0)).NotTo(BeNil()) 105 }) 106 }) 107 }) 108 109 When("passed a generic error", func() { 110 It("displays the error text to ui.Err and displays FAILED in bold red to ui.Out", func() { 111 ui.DisplayError(errors.New("I am a BANANA!")) 112 Expect(ui.Err).To(Say("I am a BANANA!\n")) 113 Expect(out).To(Say("\x1b\\[31;1mFAILED\x1b\\[0m\n")) 114 }) 115 }) 116 }) 117 118 Describe("DisplayHeader", func() { 119 It("displays the header colorized and bolded to ui.Out", func() { 120 ui.DisplayHeader("some-header") 121 Expect(out).To(Say("\x1b\\[1msome-header\x1b\\[0m")) 122 }) 123 124 When("the locale is not set to English", func() { 125 BeforeEach(func() { 126 fakeConfig.LocaleReturns("fr-FR") 127 128 var err error 129 ui, err = NewUI(fakeConfig) 130 Expect(err).NotTo(HaveOccurred()) 131 132 ui.Out = out 133 }) 134 135 It("displays the translated header colorized and bolded to ui.Out", func() { 136 ui.DisplayHeader("FEATURE FLAGS") 137 Expect(out).To(Say("\x1b\\[1mINDICATEURS DE FONCTION\x1b\\[0m")) 138 }) 139 }) 140 }) 141 142 Describe("DisplayNewline", func() { 143 It("displays a new line", func() { 144 ui.DisplayNewline() 145 Expect(out).To(Say("\n")) 146 }) 147 }) 148 149 Describe("DisplayOK", func() { 150 It("displays 'OK' in green and bold", func() { 151 ui.DisplayOK() 152 Expect(out).To(Say("\x1b\\[32;1mOK\x1b\\[0m")) 153 }) 154 }) 155 156 // Covers the happy paths, additional cases are tested in TranslateText 157 Describe("DisplayText", func() { 158 It("displays the template with map values substituted in to ui.Out with a newline", func() { 159 ui.DisplayText( 160 "template with {{.SomeMapValue}}", 161 map[string]interface{}{ 162 "SomeMapValue": "map-value", 163 }) 164 Expect(out).To(Say("template with map-value\n")) 165 }) 166 167 When("the locale is not set to english", func() { 168 BeforeEach(func() { 169 fakeConfig.LocaleReturns("fr-FR") 170 171 var err error 172 ui, err = NewUI(fakeConfig) 173 Expect(err).NotTo(HaveOccurred()) 174 175 ui.Out = out 176 }) 177 178 It("displays the translated template with map values substituted in to ui.Out", func() { 179 ui.DisplayText( 180 "\nTIP: Use '{{.Command}}' to target new org", 181 map[string]interface{}{ 182 "Command": "foo", 183 }) 184 Expect(out).To(Say("\nASTUCE : utilisez 'foo' pour cibler une nouvelle organisation")) 185 }) 186 }) 187 }) 188 189 Describe("DeferText", func() { 190 It("defers the template with map values substituted in to ui.Out with a newline", func() { 191 ui.DeferText( 192 "template with {{.SomeMapValue}}", 193 map[string]interface{}{ 194 "SomeMapValue": "map-value", 195 }) 196 Expect(out).NotTo(Say("template with map-value\n")) 197 ui.FlushDeferred() 198 Expect(out).To(Say("template with map-value\n")) 199 }) 200 201 When("the locale is not set to english", func() { 202 BeforeEach(func() { 203 fakeConfig.LocaleReturns("fr-FR") 204 205 var err error 206 ui, err = NewUI(fakeConfig) 207 Expect(err).NotTo(HaveOccurred()) 208 209 ui.Out = out 210 }) 211 212 It("defers the translated template with map values substituted in to ui.Out", func() { 213 ui.DeferText( 214 "\nTIP: Use '{{.Command}}' to target new org", 215 map[string]interface{}{ 216 "Command": "foo", 217 }) 218 Expect(out).NotTo(Say("\nASTUCE : utilisez 'foo' pour cibler une nouvelle organisation")) 219 ui.FlushDeferred() 220 Expect(out).To(Say("\nASTUCE : utilisez 'foo' pour cibler une nouvelle organisation")) 221 ui.FlushDeferred() 222 Expect(out).NotTo(Say("\nASTUCE : utilisez 'foo' pour cibler une nouvelle organisation")) 223 }) 224 }) 225 }) 226 227 Describe("DisplayTextWithBold", func() { 228 It("displays the template to ui.Out", func() { 229 ui.DisplayTextWithBold("some-template") 230 Expect(out).To(Say("some-template")) 231 }) 232 233 When("an optional map is passed in", func() { 234 It("displays the template with map values bolded and substituted in to ui.Out", func() { 235 ui.DisplayTextWithBold( 236 "template with {{.SomeMapValue}}", 237 map[string]interface{}{ 238 "SomeMapValue": "map-value", 239 }) 240 Expect(out).To(Say("template with \x1b\\[1mmap-value\x1b\\[0m")) 241 }) 242 }) 243 244 When("multiple optional maps are passed in", func() { 245 It("displays the template with only the first map values bolded and substituted in to ui.Out", func() { 246 ui.DisplayTextWithBold( 247 "template with {{.SomeMapValue}} and {{.SomeOtherMapValue}}", 248 map[string]interface{}{ 249 "SomeMapValue": "map-value", 250 }, 251 map[string]interface{}{ 252 "SomeOtherMapValue": "other-map-value", 253 }) 254 Expect(out).To(Say("template with \x1b\\[1mmap-value\x1b\\[0m and <no value>")) 255 }) 256 }) 257 258 When("the locale is not set to english", func() { 259 BeforeEach(func() { 260 fakeConfig.LocaleReturns("fr-FR") 261 262 var err error 263 ui, err = NewUI(fakeConfig) 264 Expect(err).NotTo(HaveOccurred()) 265 266 ui.Out = out 267 }) 268 269 It("displays the translated template with map values bolded and substituted in to ui.Out", func() { 270 ui.DisplayTextWithBold( 271 "App {{.AppName}} does not exist.", 272 map[string]interface{}{ 273 "AppName": "some-app-name", 274 }) 275 Expect(out).To(Say("L'application \x1b\\[1msome-app-name\x1b\\[0m n'existe pas.\n")) 276 }) 277 }) 278 }) 279 280 Describe("DisplayTextWithFlavor", func() { 281 It("displays the template to ui.Out", func() { 282 ui.DisplayTextWithFlavor("some-template") 283 Expect(out).To(Say("some-template")) 284 }) 285 286 When("an optional map is passed in", func() { 287 It("displays the template with map values colorized, bolded, and substituted in to ui.Out", func() { 288 ui.DisplayTextWithFlavor( 289 "template with {{.SomeMapValue}}", 290 map[string]interface{}{ 291 "SomeMapValue": "map-value", 292 }) 293 Expect(out).To(Say("template with \x1b\\[36;1mmap-value\x1b\\[0m")) 294 }) 295 }) 296 297 When("multiple optional maps are passed in", func() { 298 It("displays the template with only the first map values colorized, bolded, and substituted in to ui.Out", func() { 299 ui.DisplayTextWithFlavor( 300 "template with {{.SomeMapValue}} and {{.SomeOtherMapValue}}", 301 map[string]interface{}{ 302 "SomeMapValue": "map-value", 303 }, 304 map[string]interface{}{ 305 "SomeOtherMapValue": "other-map-value", 306 }) 307 Expect(out).To(Say("template with \x1b\\[36;1mmap-value\x1b\\[0m and <no value>")) 308 }) 309 }) 310 311 When("the locale is not set to english", func() { 312 BeforeEach(func() { 313 fakeConfig.LocaleReturns("fr-FR") 314 315 var err error 316 ui, err = NewUI(fakeConfig) 317 Expect(err).NotTo(HaveOccurred()) 318 319 ui.Out = out 320 }) 321 322 It("displays the translated template with map values colorized, bolded and substituted in to ui.Out", func() { 323 ui.DisplayTextWithFlavor( 324 "App {{.AppName}} does not exist.", 325 map[string]interface{}{ 326 "AppName": "some-app-name", 327 }) 328 Expect(out).To(Say("L'application \x1b\\[36;1msome-app-name\x1b\\[0m n'existe pas.\n")) 329 }) 330 }) 331 }) 332 333 Describe("TranslateText", func() { 334 It("returns the template", func() { 335 Expect(ui.TranslateText("some-template")).To(Equal("some-template")) 336 }) 337 338 When("an optional map is passed in", func() { 339 It("returns the template with map values substituted in", func() { 340 expected := ui.TranslateText( 341 "template {{.SomeMapValue}}", 342 map[string]interface{}{ 343 "SomeMapValue": "map-value", 344 }) 345 Expect(expected).To(Equal("template map-value")) 346 }) 347 }) 348 349 When("multiple optional maps are passed in", func() { 350 It("returns the template with only the first map values substituted in", func() { 351 expected := ui.TranslateText( 352 "template with {{.SomeMapValue}} and {{.SomeOtherMapValue}}", 353 map[string]interface{}{ 354 "SomeMapValue": "map-value", 355 }, 356 map[string]interface{}{ 357 "SomeOtherMapValue": "other-map-value", 358 }) 359 Expect(expected).To(Equal("template with map-value and <no value>")) 360 }) 361 }) 362 363 When("the locale is not set to english", func() { 364 BeforeEach(func() { 365 fakeConfig.LocaleReturns("fr-FR") 366 367 var err error 368 ui, err = NewUI(fakeConfig) 369 Expect(err).NotTo(HaveOccurred()) 370 }) 371 372 It("returns the translated template", func() { 373 expected := ui.TranslateText(" View allowable quotas with 'CF_NAME quotas'") 374 Expect(expected).To(Equal(" Affichez les quotas pouvant être alloués avec 'CF_NAME quotas'")) 375 }) 376 }) 377 }) 378 379 Describe("UserFriendlyDate", func() { 380 It("formats a time into an ISO8601 string", func() { 381 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}`)) 382 }) 383 }) 384 })