github.com/cloudfoundry-attic/cli-with-i18n@v6.32.1-0.20171002233121-7401370d3b85+incompatible/command/common/help_command_test.go (about)

     1  package common_test
     2  
     3  import (
     4  	"code.cloudfoundry.org/cli/actor/sharedaction"
     5  	"code.cloudfoundry.org/cli/command/commandfakes"
     6  	. "code.cloudfoundry.org/cli/command/common"
     7  	"code.cloudfoundry.org/cli/command/common/commonfakes"
     8  	"code.cloudfoundry.org/cli/command/flag"
     9  	"code.cloudfoundry.org/cli/util/configv3"
    10  	"code.cloudfoundry.org/cli/util/ui"
    11  
    12  	. "github.com/onsi/ginkgo"
    13  	. "github.com/onsi/gomega"
    14  	. "github.com/onsi/gomega/gbytes"
    15  )
    16  
    17  var _ = Describe("help Command", func() {
    18  	var (
    19  		testUI     *ui.UI
    20  		fakeActor  *commonfakes.FakeHelpActor
    21  		cmd        HelpCommand
    22  		fakeConfig *commandfakes.FakeConfig
    23  	)
    24  
    25  	BeforeEach(func() {
    26  		testUI = ui.NewTestUI(NewBuffer(), NewBuffer(), NewBuffer())
    27  		fakeActor = new(commonfakes.FakeHelpActor)
    28  		fakeConfig = new(commandfakes.FakeConfig)
    29  		fakeConfig.BinaryNameReturns("faceman")
    30  		fakeConfig.BinaryVersionReturns("face2.0-yesterday")
    31  
    32  		cmd = HelpCommand{
    33  			UI:     testUI,
    34  			Actor:  fakeActor,
    35  			Config: fakeConfig,
    36  		}
    37  	})
    38  
    39  	Context("providing help for a specific command", func() {
    40  		Describe("built-in command", func() {
    41  			BeforeEach(func() {
    42  				cmd.OptionalArgs = flag.CommandName{
    43  					CommandName: "help",
    44  				}
    45  
    46  				commandInfo := sharedaction.CommandInfo{
    47  					Name:        "help",
    48  					Description: "Show help",
    49  					Usage:       "CF_NAME help [COMMAND]",
    50  					Alias:       "h",
    51  				}
    52  				fakeActor.CommandInfoByNameReturns(commandInfo, nil)
    53  			})
    54  
    55  			It("displays the name for help", func() {
    56  				err := cmd.Execute(nil)
    57  				Expect(err).ToNot(HaveOccurred())
    58  
    59  				Expect(testUI.Out).To(Say("NAME:"))
    60  				Expect(testUI.Out).To(Say("   help - Show help"))
    61  
    62  				Expect(fakeActor.CommandInfoByNameCallCount()).To(Equal(1))
    63  				_, commandName := fakeActor.CommandInfoByNameArgsForCall(0)
    64  				Expect(commandName).To(Equal("help"))
    65  			})
    66  
    67  			It("displays the usage for help", func() {
    68  				err := cmd.Execute(nil)
    69  				Expect(err).ToNot(HaveOccurred())
    70  
    71  				Expect(testUI.Out).To(Say("NAME:"))
    72  				Expect(testUI.Out).To(Say("USAGE:"))
    73  				Expect(testUI.Out).To(Say("   faceman help \\[COMMAND\\]"))
    74  			})
    75  
    76  			Describe("related commands", func() {
    77  				Context("when the command has related commands", func() {
    78  					BeforeEach(func() {
    79  						commandInfo := sharedaction.CommandInfo{
    80  							Name:            "app",
    81  							RelatedCommands: []string{"broccoli", "tomato"},
    82  						}
    83  						fakeActor.CommandInfoByNameReturns(commandInfo, nil)
    84  					})
    85  
    86  					It("displays the related commands for help", func() {
    87  						err := cmd.Execute(nil)
    88  						Expect(err).ToNot(HaveOccurred())
    89  
    90  						Expect(testUI.Out).To(Say("NAME:"))
    91  						Expect(testUI.Out).To(Say("SEE ALSO:"))
    92  						Expect(testUI.Out).To(Say("   broccoli, tomato"))
    93  					})
    94  				})
    95  
    96  				Context("when the command does not have related commands", func() {
    97  					It("displays the related commands for help", func() {
    98  						err := cmd.Execute(nil)
    99  						Expect(err).ToNot(HaveOccurred())
   100  
   101  						Expect(testUI.Out).To(Say("NAME:"))
   102  						Expect(testUI.Out).NotTo(Say("SEE ALSO:"))
   103  					})
   104  				})
   105  			})
   106  
   107  			Describe("aliases", func() {
   108  				Context("when the command has an alias", func() {
   109  					It("displays the alias for help", func() {
   110  						err := cmd.Execute(nil)
   111  						Expect(err).ToNot(HaveOccurred())
   112  
   113  						Expect(testUI.Out).To(Say("USAGE:"))
   114  						Expect(testUI.Out).To(Say("ALIAS:"))
   115  						Expect(testUI.Out).To(Say("   h"))
   116  					})
   117  				})
   118  
   119  				Context("when the command does not have an alias", func() {
   120  					BeforeEach(func() {
   121  						cmd.OptionalArgs = flag.CommandName{
   122  							CommandName: "app",
   123  						}
   124  
   125  						commandInfo := sharedaction.CommandInfo{
   126  							Name: "app",
   127  						}
   128  						fakeActor.CommandInfoByNameReturns(commandInfo, nil)
   129  					})
   130  
   131  					It("no alias is displayed", func() {
   132  						err := cmd.Execute(nil)
   133  						Expect(err).ToNot(HaveOccurred())
   134  
   135  						Expect(testUI.Out).ToNot(Say("ALIAS:"))
   136  					})
   137  				})
   138  			})
   139  
   140  			Describe("options", func() {
   141  				Context("when the command has options", func() {
   142  					BeforeEach(func() {
   143  						cmd.OptionalArgs = flag.CommandName{
   144  							CommandName: "push",
   145  						}
   146  						commandInfo := sharedaction.CommandInfo{
   147  							Name: "push",
   148  							Flags: []sharedaction.CommandFlag{
   149  								{
   150  									Long:        "no-hostname",
   151  									Description: "Map the root domain to this app",
   152  								},
   153  								{
   154  									Short:       "b",
   155  									Description: "Custom buildpack by name (e.g. my-buildpack) or Git URL (e.g. 'https://github.com/cloudfoundry/java-buildpack.git') or Git URL with a branch or tag (e.g. 'https://github.com/cloudfoundry/java-buildpack.git#v3.3.0' for 'v3.3.0' tag). To use built-in buildpacks only, specify 'default' or 'null'",
   156  								},
   157  								{
   158  									Long:        "hostname",
   159  									Short:       "n",
   160  									Description: "Hostname (e.g. my-subdomain)",
   161  								},
   162  								{
   163  									Long:        "force",
   164  									Short:       "f",
   165  									Description: "do it",
   166  									Default:     "yes",
   167  								},
   168  							},
   169  						}
   170  						fakeActor.CommandInfoByNameReturns(commandInfo, nil)
   171  					})
   172  
   173  					Context("only has a long option", func() {
   174  						It("displays the options for app", func() {
   175  							err := cmd.Execute(nil)
   176  							Expect(err).ToNot(HaveOccurred())
   177  
   178  							Expect(testUI.Out).To(Say("USAGE:"))
   179  							Expect(testUI.Out).To(Say("OPTIONS:"))
   180  							Expect(testUI.Out).To(Say("--no-hostname\\s+Map the root domain to this app"))
   181  						})
   182  					})
   183  
   184  					Context("only has a short option", func() {
   185  						It("displays the options for app", func() {
   186  							err := cmd.Execute(nil)
   187  							Expect(err).ToNot(HaveOccurred())
   188  
   189  							Expect(testUI.Out).To(Say("USAGE:"))
   190  							Expect(testUI.Out).To(Say("OPTIONS:"))
   191  							Expect(testUI.Out).To(Say("-b\\s+Custom buildpack by name \\(e.g. my-buildpack\\) or Git URL \\(e.g. 'https://github.com/cloudfoundry/java-buildpack.git'\\) or Git URL with a branch or tag \\(e.g. 'https://github.com/cloudfoundry/java-buildpack.git#v3.3.0' for 'v3.3.0' tag\\). To use built-in buildpacks only, specify 'default' or 'null'"))
   192  						})
   193  					})
   194  
   195  					Context("has long and short options", func() {
   196  						It("displays the options for app", func() {
   197  							err := cmd.Execute(nil)
   198  							Expect(err).ToNot(HaveOccurred())
   199  
   200  							Expect(testUI.Out).To(Say("USAGE:"))
   201  							Expect(testUI.Out).To(Say("OPTIONS:"))
   202  							Expect(testUI.Out).To(Say("--hostname, -n\\s+Hostname \\(e.g. my-subdomain\\)"))
   203  						})
   204  					})
   205  
   206  					Context("has hidden options", func() {
   207  						It("does not display the hidden option", func() {
   208  							err := cmd.Execute(nil)
   209  							Expect(err).ToNot(HaveOccurred())
   210  
   211  							Expect(testUI.Out).ToNot(Say("--app-ports"))
   212  						})
   213  					})
   214  
   215  					Context("has a default for an option", func() {
   216  						It("displays the default", func() {
   217  							err := cmd.Execute(nil)
   218  							Expect(err).ToNot(HaveOccurred())
   219  
   220  							Expect(testUI.Out).To(Say("do it \\(Default: yes\\)"))
   221  						})
   222  					})
   223  				})
   224  			})
   225  		})
   226  
   227  		Describe("Environment", func() {
   228  			Context("has environment variables", func() {
   229  				var envVars []sharedaction.EnvironmentVariable
   230  
   231  				BeforeEach(func() {
   232  					cmd.OptionalArgs = flag.CommandName{
   233  						CommandName: "push",
   234  					}
   235  					envVars = []sharedaction.EnvironmentVariable{
   236  						sharedaction.EnvironmentVariable{
   237  							Name:         "CF_STAGING_TIMEOUT",
   238  							Description:  "Max wait time for buildpack staging, in minutes",
   239  							DefaultValue: "15",
   240  						},
   241  						sharedaction.EnvironmentVariable{
   242  							Name:         "CF_STARTUP_TIMEOUT",
   243  							Description:  "Max wait time for app instance startup, in minutes",
   244  							DefaultValue: "5",
   245  						},
   246  					}
   247  					commandInfo := sharedaction.CommandInfo{
   248  						Name:        "push",
   249  						Environment: envVars,
   250  					}
   251  
   252  					fakeActor.CommandInfoByNameReturns(commandInfo, nil)
   253  				})
   254  
   255  				It("displays the timeouts under environment", func() {
   256  					err := cmd.Execute(nil)
   257  					Expect(err).ToNot(HaveOccurred())
   258  
   259  					Expect(testUI.Out).To(Say("ENVIRONMENT:"))
   260  					Expect(testUI.Out).To(Say(`
   261     CF_STAGING_TIMEOUT=15        Max wait time for buildpack staging, in minutes
   262     CF_STARTUP_TIMEOUT=5         Max wait time for app instance startup, in minutes
   263  `))
   264  				})
   265  			})
   266  
   267  			Context("does not have any associated environment variables", func() {
   268  				BeforeEach(func() {
   269  					cmd.OptionalArgs = flag.CommandName{
   270  						CommandName: "app",
   271  					}
   272  					commandInfo := sharedaction.CommandInfo{
   273  						Name: "app",
   274  					}
   275  
   276  					fakeActor.CommandInfoByNameReturns(commandInfo, nil)
   277  				})
   278  
   279  				It("does not show the environment section", func() {
   280  					err := cmd.Execute(nil)
   281  					Expect(err).ToNot(HaveOccurred())
   282  					Expect(testUI.Out).ToNot(Say("ENVIRONMENT:"))
   283  				})
   284  			})
   285  		})
   286  
   287  		Describe("plug-in command", func() {
   288  			BeforeEach(func() {
   289  				cmd.OptionalArgs = flag.CommandName{
   290  					CommandName: "enable-diego",
   291  				}
   292  
   293  				fakeConfig.PluginsReturns([]configv3.Plugin{
   294  					{Name: "Diego-Enabler",
   295  						Commands: []configv3.PluginCommand{
   296  							{
   297  								Name:     "enable-diego",
   298  								Alias:    "ed",
   299  								HelpText: "enable Diego support for an app",
   300  								UsageDetails: configv3.PluginUsageDetails{
   301  									Usage: "faceman diego-enabler this and that and a little stuff",
   302  									Options: map[string]string{
   303  										"--first":        "foobar",
   304  										"--second-third": "baz",
   305  									},
   306  								},
   307  							},
   308  						},
   309  					},
   310  				})
   311  
   312  				fakeActor.CommandInfoByNameReturns(sharedaction.CommandInfo{},
   313  					sharedaction.ErrorInvalidCommand{CommandName: "enable-diego"})
   314  			})
   315  
   316  			It("displays the plugin's help", func() {
   317  				err := cmd.Execute(nil)
   318  				Expect(err).ToNot(HaveOccurred())
   319  
   320  				Expect(testUI.Out).To(Say("enable-diego - enable Diego support for an app"))
   321  				Expect(testUI.Out).To(Say("faceman diego-enabler this and that and a little stuff"))
   322  				Expect(testUI.Out).To(Say("ALIAS:"))
   323  				Expect(testUI.Out).To(Say("ed"))
   324  				Expect(testUI.Out).To(Say("--first\\s+foobar"))
   325  				Expect(testUI.Out).To(Say("--second-third\\s+baz"))
   326  			})
   327  		})
   328  
   329  		Describe("plug-in alias", func() {
   330  			BeforeEach(func() {
   331  				cmd.OptionalArgs = flag.CommandName{
   332  					CommandName: "ed",
   333  				}
   334  
   335  				fakeConfig.PluginsReturns([]configv3.Plugin{
   336  					{
   337  						Name: "Diego-Enabler",
   338  						Commands: []configv3.PluginCommand{
   339  							{
   340  								Name:     "enable-diego",
   341  								Alias:    "ed",
   342  								HelpText: "enable Diego support for an app",
   343  								UsageDetails: configv3.PluginUsageDetails{
   344  									Usage: "faceman diego-enabler this and that and a little stuff",
   345  									Options: map[string]string{
   346  										"--first":        "foobar",
   347  										"--second-third": "baz",
   348  									},
   349  								},
   350  							},
   351  						},
   352  					},
   353  				})
   354  
   355  				fakeActor.CommandInfoByNameReturns(sharedaction.CommandInfo{},
   356  					sharedaction.ErrorInvalidCommand{CommandName: "enable-diego"})
   357  			})
   358  
   359  			It("displays the plugin's help", func() {
   360  				err := cmd.Execute(nil)
   361  				Expect(err).ToNot(HaveOccurred())
   362  
   363  				Expect(testUI.Out).To(Say("enable-diego - enable Diego support for an app"))
   364  				Expect(testUI.Out).To(Say("faceman diego-enabler this and that and a little stuff"))
   365  				Expect(testUI.Out).To(Say("ALIAS:"))
   366  				Expect(testUI.Out).To(Say("ed"))
   367  				Expect(testUI.Out).To(Say("--first\\s+foobar"))
   368  				Expect(testUI.Out).To(Say("--second-third\\s+baz"))
   369  			})
   370  		})
   371  	})
   372  
   373  	Describe("help for common commands", func() {
   374  		BeforeEach(func() {
   375  			cmd.OptionalArgs = flag.CommandName{
   376  				CommandName: "",
   377  			}
   378  			cmd.AllCommands = false
   379  			cmd.Actor = sharedaction.NewActor(nil)
   380  		})
   381  
   382  		It("returns a list of only the common commands", func() {
   383  			err := cmd.Execute(nil)
   384  			Expect(err).ToNot(HaveOccurred())
   385  
   386  			Expect(testUI.Out).To(Say("faceman version face2.0-yesterday, Cloud Foundry command line tool"))
   387  			Expect(testUI.Out).To(Say("Usage: faceman \\[global options\\] command \\[arguments...\\] \\[command options\\]"))
   388  
   389  			Expect(testUI.Out).To(Say("Before getting started:"))
   390  			Expect(testUI.Out).To(Say("  help,h    logout,lo"))
   391  
   392  			Expect(testUI.Out).To(Say("Application lifecycle:"))
   393  			Expect(testUI.Out).To(Say("  apps,a\\s+run-task,rt\\s+events"))
   394  			Expect(testUI.Out).To(Say("  restage,rg\\s+scale"))
   395  
   396  			Expect(testUI.Out).To(Say("Services integration:"))
   397  			Expect(testUI.Out).To(Say("  marketplace,m\\s+create-user-provided-service,cups"))
   398  			Expect(testUI.Out).To(Say("  services,s\\s+update-user-provided-service,uups"))
   399  
   400  			Expect(testUI.Out).To(Say("Route and domain management:"))
   401  			Expect(testUI.Out).To(Say("  routes,r\\s+delete-route\\s+create-domain"))
   402  			Expect(testUI.Out).To(Say("  domains\\s+map-route"))
   403  
   404  			Expect(testUI.Out).To(Say("Space management:"))
   405  			Expect(testUI.Out).To(Say("  spaces\\s+create-space\\s+set-space-role"))
   406  
   407  			Expect(testUI.Out).To(Say("Org management:"))
   408  			Expect(testUI.Out).To(Say("  orgs,o\\s+set-org-role"))
   409  
   410  			Expect(testUI.Out).To(Say("CLI plugin management:"))
   411  			Expect(testUI.Out).To(Say("  install-plugin    list-plugin-repos"))
   412  
   413  			Expect(testUI.Out).To(Say("Global options:"))
   414  			Expect(testUI.Out).To(Say("  --help, -h                         Show help"))
   415  			Expect(testUI.Out).To(Say("  -v                                 Print API request diagnostics to stdout"))
   416  
   417  			Expect(testUI.Out).To(Say("Use 'cf help -a' to see all commands\\."))
   418  		})
   419  
   420  		Context("when there are multiple installed plugins", func() {
   421  			BeforeEach(func() {
   422  				fakeConfig.PluginsReturns([]configv3.Plugin{
   423  					{
   424  						Name: "Some-other-plugin",
   425  						Commands: []configv3.PluginCommand{
   426  							{
   427  								Name:     "some-other-plugin-command",
   428  								HelpText: "does some other thing",
   429  							},
   430  						},
   431  					},
   432  					{
   433  						Name: "some-plugin",
   434  						Commands: []configv3.PluginCommand{
   435  							{
   436  								Name:     "enable",
   437  								HelpText: "enable command",
   438  							},
   439  							{
   440  								Name:     "disable",
   441  								HelpText: "disable command",
   442  							},
   443  							{
   444  								Name:     "some-other-command",
   445  								HelpText: "does something",
   446  							},
   447  						},
   448  					},
   449  					{
   450  						Name: "the-last-plugin",
   451  						Commands: []configv3.PluginCommand{
   452  							{
   453  								Name:     "last-plugin-command",
   454  								HelpText: "does the last thing",
   455  							},
   456  						},
   457  					},
   458  				})
   459  			})
   460  
   461  			It("returns the plugin commands organized by plugin and sorted in alphabetical order", func() {
   462  				err := cmd.Execute(nil)
   463  				Expect(err).ToNot(HaveOccurred())
   464  
   465  				Expect(testUI.Out).To(Say("Commands offered by installed plugins:"))
   466  				Expect(testUI.Out).To(Say("some-other-plugin-command\\s+enable\\s+last-plugin-command"))
   467  				Expect(testUI.Out).To(Say("disable\\s+some-other-command"))
   468  
   469  			})
   470  		})
   471  	})
   472  
   473  	Describe("providing help for all commands", func() {
   474  		Context("when a command is not provided", func() {
   475  			BeforeEach(func() {
   476  				cmd.OptionalArgs = flag.CommandName{
   477  					CommandName: "",
   478  				}
   479  				cmd.AllCommands = true
   480  
   481  				cmd.Actor = sharedaction.NewActor(nil)
   482  				fakeConfig.PluginsReturns([]configv3.Plugin{
   483  					{
   484  						Name: "Diego-Enabler",
   485  						Commands: []configv3.PluginCommand{
   486  							{
   487  								Name:     "enable-diego",
   488  								HelpText: "enable Diego support for an app",
   489  							},
   490  						},
   491  					},
   492  				})
   493  			})
   494  
   495  			It("returns a list of all commands", func() {
   496  				err := cmd.Execute(nil)
   497  				Expect(err).ToNot(HaveOccurred())
   498  
   499  				Expect(testUI.Out).To(Say("NAME:"))
   500  				Expect(testUI.Out).To(Say("   faceman - A command line tool to interact with Cloud Foundry"))
   501  				Expect(testUI.Out).To(Say("USAGE:"))
   502  				Expect(testUI.Out).To(Say("   faceman \\[global options\\] command \\[arguments...\\] \\[command options\\]"))
   503  				Expect(testUI.Out).To(Say("VERSION:"))
   504  				Expect(testUI.Out).To(Say("   face2.0-yesterday"))
   505  
   506  				Expect(testUI.Out).To(Say("GETTING STARTED:"))
   507  				Expect(testUI.Out).To(Say("   help\\s+Show help"))
   508  				Expect(testUI.Out).To(Say("   api\\s+Set or view target api url"))
   509  
   510  				Expect(testUI.Out).To(Say("APPS:"))
   511  				Expect(testUI.Out).To(Say("   apps\\s+List all apps in the target space"))
   512  				Expect(testUI.Out).To(Say("   ssh-enabled\\s+Reports whether SSH is enabled on an application container instance"))
   513  
   514  				Expect(testUI.Out).To(Say("SERVICES:"))
   515  				Expect(testUI.Out).To(Say("   marketplace\\s+List available offerings in the marketplace"))
   516  				Expect(testUI.Out).To(Say("   create-service\\s+Create a service instance"))
   517  
   518  				Expect(testUI.Out).To(Say("ORGS:"))
   519  				Expect(testUI.Out).To(Say("   orgs\\s+List all orgs"))
   520  				Expect(testUI.Out).To(Say("   delete-org\\s+Delete an org"))
   521  
   522  				Expect(testUI.Out).To(Say("SPACES:"))
   523  				Expect(testUI.Out).To(Say("   spaces\\s+List all spaces in an org"))
   524  				Expect(testUI.Out).To(Say("   allow-space-ssh\\s+Allow SSH access for the space"))
   525  
   526  				Expect(testUI.Out).To(Say("DOMAINS:"))
   527  				Expect(testUI.Out).To(Say("   domains\\s+List domains in the target org"))
   528  				Expect(testUI.Out).To(Say("   router-groups\\s+List router groups"))
   529  
   530  				Expect(testUI.Out).To(Say("ROUTES:"))
   531  				Expect(testUI.Out).To(Say("   routes\\s+List all routes in the current space or the current organization"))
   532  				Expect(testUI.Out).To(Say("   unmap-route\\s+Remove a url route from an app"))
   533  
   534  				Expect(testUI.Out).To(Say("NETWORK POLICIES:"))
   535  				Expect(testUI.Out).To(Say("   network-policies\\s+List direct network traffic policies"))
   536  				Expect(testUI.Out).To(Say("   add-network-policy\\s+Create policy to allow direct network traffic from one app to another"))
   537  				Expect(testUI.Out).To(Say("   remove-network-policy\\s+Remove network traffic policy of an app"))
   538  
   539  				Expect(testUI.Out).To(Say("BUILDPACKS:"))
   540  				Expect(testUI.Out).To(Say("   buildpacks\\s+List all buildpacks"))
   541  				Expect(testUI.Out).To(Say("   delete-buildpack\\s+Delete a buildpack"))
   542  
   543  				Expect(testUI.Out).To(Say("USER ADMIN:"))
   544  				Expect(testUI.Out).To(Say("   create-user\\s+Create a new user"))
   545  				Expect(testUI.Out).To(Say("   space-users\\s+Show space users by role"))
   546  
   547  				Expect(testUI.Out).To(Say("ORG ADMIN:"))
   548  				Expect(testUI.Out).To(Say("   quotas\\s+List available usage quotas"))
   549  				Expect(testUI.Out).To(Say("   delete-quota\\s+Delete a quota"))
   550  
   551  				Expect(testUI.Out).To(Say("SPACE ADMIN:"))
   552  				Expect(testUI.Out).To(Say("   space-quotas\\s+List available space resource quotas"))
   553  				Expect(testUI.Out).To(Say("   set-space-quota\\s+Assign a space quota definition to a space"))
   554  
   555  				Expect(testUI.Out).To(Say("SERVICE ADMIN:"))
   556  				Expect(testUI.Out).To(Say("   service-auth-tokens\\s+List service auth tokens"))
   557  				Expect(testUI.Out).To(Say("   service-access\\s+List service access settings"))
   558  
   559  				Expect(testUI.Out).To(Say("SECURITY GROUP:"))
   560  				Expect(testUI.Out).To(Say("   security-group\\s+Show a single security group"))
   561  				Expect(testUI.Out).To(Say("   staging-security-groups\\s+List security groups in the staging set for applications"))
   562  
   563  				Expect(testUI.Out).To(Say("ENVIRONMENT VARIABLE GROUPS:"))
   564  				Expect(testUI.Out).To(Say("   running-environment-variable-group\\s+Retrieve the contents of the running environment variable group"))
   565  				Expect(testUI.Out).To(Say("   set-running-environment-variable-group Pass parameters as JSON to create a running environment variable group"))
   566  
   567  				Expect(testUI.Out).To(Say("ISOLATION SEGMENTS:"))
   568  				Expect(testUI.Out).To(Say("   isolation-segments\\s+List all isolation segments"))
   569  				Expect(testUI.Out).To(Say("   create-isolation-segment\\s+Create an isolation segment"))
   570  				Expect(testUI.Out).To(Say("   delete-isolation-segment\\s+Delete an isolation segment"))
   571  				Expect(testUI.Out).To(Say("   enable-org-isolation\\s+Entitle an organization to an isolation segment"))
   572  				Expect(testUI.Out).To(Say("   disable-org-isolation\\s+Revoke an organization's entitlement to an isolation segment"))
   573  				Expect(testUI.Out).To(Say("   set-org-default-isolation-segment\\s+Set the default isolation segment used for apps in spaces in an org"))
   574  				Expect(testUI.Out).To(Say("   reset-org-default-isolation-segment\\s+Reset the default isolation segment used for apps in spaces of an org"))
   575  				Expect(testUI.Out).To(Say("   set-space-isolation-segment"))
   576  				Expect(testUI.Out).To(Say("   reset-space-isolation-segment"))
   577  
   578  				Expect(testUI.Out).To(Say("FEATURE FLAGS:"))
   579  				Expect(testUI.Out).To(Say("   feature-flags\\s+Retrieve list of feature flags with status of each flag-able feature"))
   580  				Expect(testUI.Out).To(Say("   disable-feature-flag"))
   581  
   582  				Expect(testUI.Out).To(Say("ADVANCED:"))
   583  				Expect(testUI.Out).To(Say("   curl\\s+Executes a request to the targeted API endpoint"))
   584  				Expect(testUI.Out).To(Say("   ssh-code\\s+Get a one time password for ssh clients"))
   585  
   586  				Expect(testUI.Out).To(Say("ADD/REMOVE PLUGIN REPOSITORY:"))
   587  				Expect(testUI.Out).To(Say("   add-plugin-repo\\s+Add a new plugin repository"))
   588  				Expect(testUI.Out).To(Say("   repo-plugins\\s+List all available plugins in specified repository or in all added repositories"))
   589  
   590  				Expect(testUI.Out).To(Say("ADD/REMOVE PLUGIN:"))
   591  				Expect(testUI.Out).To(Say("   plugins\\s+List commands of installed plugins"))
   592  				Expect(testUI.Out).To(Say("   uninstall-plugin\\s+Uninstall CLI plugin"))
   593  
   594  				Expect(testUI.Out).To(Say("INSTALLED PLUGIN COMMANDS:"))
   595  				Expect(testUI.Out).To(Say("   enable-diego\\s+enable Diego support for an app"))
   596  
   597  				Expect(testUI.Out).To(Say("ENVIRONMENT VARIABLES:"))
   598  				Expect(testUI.Out).To(Say("   CF_COLOR=false                     Do not colorize output"))
   599  				Expect(testUI.Out).To(Say("   CF_DIAL_TIMEOUT=5                  Max wait time to establish a connection, including name resolution, in seconds"))
   600  				Expect(testUI.Out).To(Say("   CF_HOME=path/to/dir/               Override path to default config directory"))
   601  				Expect(testUI.Out).To(Say("   CF_PLUGIN_HOME=path/to/dir/        Override path to default plugin config directory"))
   602  				Expect(testUI.Out).To(Say("   CF_TRACE=true                      Print API request diagnostics to stdout"))
   603  				Expect(testUI.Out).To(Say("   CF_TRACE=path/to/trace.log         Append API request diagnostics to a log file"))
   604  				Expect(testUI.Out).To(Say("   https_proxy=proxy.example.com:8080 Enable HTTP proxying for API requests"))
   605  
   606  				Expect(testUI.Out).To(Say("GLOBAL OPTIONS:"))
   607  				Expect(testUI.Out).To(Say("   --help, -h                         Show help"))
   608  				Expect(testUI.Out).To(Say("   -v                                 Print API request diagnostics to stdout"))
   609  
   610  				Expect(testUI.Out).To(Say("V3 APPS \\(experimental\\):"))
   611  				Expect(testUI.Out).To(Say("   v3-apps\\s+List all apps in the target space"))
   612  				Expect(testUI.Out).To(Say("   v3-app\\s+Display health and status for an app"))
   613  				Expect(testUI.Out).To(Say("   v3-create-app\\s+Create a V3 App"))
   614  				Expect(testUI.Out).To(Say("   v3-push\\s+Push a new app or sync changes to an existing app"))
   615  				Expect(testUI.Out).To(Say("   v3-scale\\s+Change or view the instance count, disk space limit, and memory limit for an app"))
   616  				Expect(testUI.Out).To(Say("   v3-delete\\s+Delete a V3 App"))
   617  				Expect(testUI.Out).To(Say("   v3-start\\s+Start an app"))
   618  				Expect(testUI.Out).To(Say("   v3-stop\\s+Stop an app"))
   619  				Expect(testUI.Out).To(Say("   v3-restart\\s+Stop all instances of the app, then start them again. This causes downtime."))
   620  				Expect(testUI.Out).To(Say("   v3-stage\\s+Create a new droplet for an app"))
   621  				Expect(testUI.Out).To(Say("   v3-restart-app-instance\\s+Terminate, then instantiate an app instance"))
   622  				Expect(testUI.Out).To(Say("   v3-droplets\\s+List droplets of an app"))
   623  				Expect(testUI.Out).To(Say("   v3-set-droplet\\s+Set the droplet used to run an app"))
   624  				Expect(testUI.Out).To(Say("   v3-set-env\\s+Set an env variable for an app"))
   625  				Expect(testUI.Out).To(Say("   v3-unset-env\\s+Remove an env variable from an app"))
   626  				Expect(testUI.Out).To(Say("   v3-get-health-check\\s+Show the type of health check performed on an app"))
   627  				Expect(testUI.Out).To(Say("   v3-set-health-check\\s+Change type of health check performed on an app's process"))
   628  				Expect(testUI.Out).To(Say("   v3-packages\\s+List packages of an app"))
   629  				Expect(testUI.Out).To(Say("   v3-create-package\\s+Uploads a V3 Package"))
   630  			})
   631  
   632  			Context("when there are multiple installed plugins", func() {
   633  				BeforeEach(func() {
   634  					fakeConfig.PluginsReturns([]configv3.Plugin{
   635  						{
   636  							Name: "Some-other-plugin",
   637  							Commands: []configv3.PluginCommand{
   638  								{
   639  									Name:     "some-other-plugin-command",
   640  									HelpText: "does some other thing",
   641  								},
   642  							},
   643  						},
   644  						{
   645  							Name: "some-plugin",
   646  							Commands: []configv3.PluginCommand{
   647  								{
   648  									Name:     "enable",
   649  									HelpText: "enable command",
   650  								},
   651  								{
   652  									Name:     "disable",
   653  									HelpText: "disable command",
   654  								},
   655  								{
   656  									Name:     "some-other-command",
   657  									HelpText: "does something",
   658  								},
   659  							},
   660  						},
   661  						{
   662  							Name: "the-last-plugin",
   663  							Commands: []configv3.PluginCommand{
   664  								{
   665  									Name:     "last-plugin-command",
   666  									HelpText: "does the last thing",
   667  								},
   668  							},
   669  						},
   670  					})
   671  				})
   672  
   673  				It("returns the plugin commands organized by plugin and sorted in alphabetical order", func() {
   674  					err := cmd.Execute(nil)
   675  					Expect(err).ToNot(HaveOccurred())
   676  
   677  					Expect(testUI.Out).To(Say(`INSTALLED PLUGIN COMMANDS:.*
   678  \s+some-other-plugin-command\s+does some other thing.*
   679  \s+disable\s+disable command.*
   680  \s+enable\s+enable command.*
   681  \s+some-other-command\s+does something.*
   682  \s+last-plugin-command\s+does the last thing`))
   683  				})
   684  			})
   685  		})
   686  	})
   687  })