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  })