github.com/nimakaviani/cli@v6.37.1-0.20180619223813-e734901a73fa+incompatible/command/common/help_command_test.go (about)

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