github.com/asifdxtreme/cli@v6.1.3-0.20150123051144-9ead8700b4ae+incompatible/main/main_test.go (about)

     1  package main_test
     2  
     3  import (
     4  	"bufio"
     5  	"os"
     6  	"os/exec"
     7  	"path/filepath"
     8  	"time"
     9  
    10  	. "github.com/onsi/ginkgo"
    11  	. "github.com/onsi/gomega"
    12  	. "github.com/onsi/gomega/gbytes"
    13  	. "github.com/onsi/gomega/gexec"
    14  )
    15  
    16  var _ = Describe("main", func() {
    17  	var (
    18  		old_PLUGINS_HOME string
    19  	)
    20  
    21  	BeforeEach(func() {
    22  		old_PLUGINS_HOME = os.Getenv("CF_PLUGIN_HOME")
    23  
    24  		dir, err := os.Getwd()
    25  		Expect(err).NotTo(HaveOccurred())
    26  
    27  		fullDir := filepath.Join(dir, "..", "fixtures", "config", "main-plugin-test-config")
    28  		err = os.Setenv("CF_PLUGIN_HOME", fullDir)
    29  		Expect(err).NotTo(HaveOccurred())
    30  	})
    31  
    32  	AfterEach(func() {
    33  		err := os.Setenv("CF_PLUGIN_HOME", old_PLUGINS_HOME)
    34  		Expect(err).NotTo(HaveOccurred())
    35  	})
    36  
    37  	Describe("exit codes", func() {
    38  		It("exits non-zero when an unknown command is invoked", func() {
    39  			result := Cf("some-command-that-should-never-actually-be-a-real-thing-i-can-use")
    40  
    41  			Eventually(result, 3*time.Second).Should(Say("not a registered command"))
    42  			Eventually(result).Should(Exit(1))
    43  		})
    44  
    45  		It("exits non-zero when known command is invoked with invalid option", func() {
    46  			result := Cf("push", "--crazy")
    47  			Eventually(result).Should(Exit(1))
    48  		})
    49  	})
    50  
    51  	It("can print help for all core commands by executing only the command `cf`", func() {
    52  		output := Cf().Wait(3 * time.Second)
    53  		Eventually(output.Out.Contents).Should(ContainSubstring("A command line tool to interact with Cloud Foundry"))
    54  	})
    55  
    56  	Describe("Flag verification", func() {
    57  		It("informs user for any incorrect provided flags", func() {
    58  			result := Cf("push", "--no-hostname", "--bad-flag")
    59  			Eventually(result.Out).Should(Say("\"--bad-flag\""))
    60  			Consistently(result.Out).ShouldNot(Say("\"--no-hostname\""))
    61  		})
    62  
    63  		It("checks flags with prefix '--'", func() {
    64  			result := Cf("push", "not-a-flag", "--invalid-flag")
    65  			Eventually(result.Out).Should(Say("Unknown flag \"--invalid-flag\""))
    66  			Consistently(result.Out).ShouldNot(Say("Unknown flag \"not-a-flag\""))
    67  		})
    68  
    69  		It("checks flags with prefix '-'", func() {
    70  			result := Cf("push", "not-a-flag", "-invalid-flag")
    71  			Eventually(result.Out).Should(Say("\"-invalid-flag\""))
    72  			Consistently(result.Out).ShouldNot(Say("\"not-a-flag\""))
    73  		})
    74  
    75  		It("checks flags but ignores the value after '=' ", func() {
    76  			result := Cf("push", "-p=./", "-invalid-flag=blarg")
    77  			Eventually(result.Out).Should(Say("\"-invalid-flag\""))
    78  			Consistently(result.Out).ShouldNot(Say("Unknown flag \"-p\""))
    79  		})
    80  
    81  		It("outputs all unknown flags in single sentence", func() {
    82  			result := Cf("push", "--bad-flag1", "--bad-flag2", "--bad-flag3")
    83  			Eventually(result.Out).Should(Say("\"--bad-flag1\", \"--bad-flag2\", \"--bad-flag3\""))
    84  		})
    85  
    86  		It("only checks input flags against flags from the provided command", func() {
    87  			result := Cf("push", "--no-hostname", "--skip-ssl-validation")
    88  			Eventually(result.Out).Should(Say("\"--skip-ssl-validation\""))
    89  		})
    90  
    91  		It("accepts -h and --h flags for all commands", func() {
    92  			result := Cf("push", "-h")
    93  			Consistently(result.Out).ShouldNot(Say("Unknown flag \"-h\""))
    94  
    95  			result = Cf("target", "--h")
    96  			Consistently(result.Out).ShouldNot(Say("Unknown flag \"--h\""))
    97  		})
    98  
    99  		Context("When TotalArgs is set in the metadata for a command", func() {
   100  			It("will only validate flags in the argument position after position <TotalArgs>", func() {
   101  				result := Cf("create-buildpack", "buildpack_name", "location/to/nowhere", "-100", "-bad_flag")
   102  				Eventually(result.Out).ShouldNot(Say("\"-100\""))
   103  				Eventually(result.Out).Should(Say("\"-bad_flag\""))
   104  			})
   105  
   106  			It("will not validate arguments before the position <TotalArgs>", func() {
   107  				result := Cf("create-buildpack", "-bad-flag", "--bad-flag2")
   108  				Eventually(result.Out).ShouldNot(Say("\"-bad-flag\""))
   109  				Eventually(result.Out).ShouldNot(Say("\"--bad_flag2\""))
   110  			})
   111  		})
   112  
   113  		Context("When a negative integer is preceeded by a valid flag", func() {
   114  			It("skips validation for negative integer flag values", func() {
   115  				result := Cf("update-space-quota", "-i", "-10")
   116  				Eventually(result.Out).ShouldNot(Say("\"-10\""))
   117  			})
   118  		})
   119  
   120  		Context("When a negative integer is preceeded by a invalid flag", func() {
   121  			It("validates the negative integer as a flag", func() {
   122  				result := Cf("update-space-quota", "-badflag", "-10")
   123  				Eventually(result.Out).Should(Say("\"-badflag\""))
   124  				Eventually(result.Out).Should(Say("\"-10\""))
   125  			})
   126  		})
   127  	})
   128  
   129  	Describe("Plugins", func() {
   130  		It("Can call a plugin command from the Plugins configuration if it does not exist as a cf command", func() {
   131  			output := Cf("test_1_cmd1").Wait(3 * time.Second)
   132  			Eventually(output.Out).Should(Say("You called cmd1 in test_1"))
   133  		})
   134  
   135  		It("Can call a plugin command via alias if it does not exist as a cf command", func() {
   136  			output := Cf("test_1_cmd1_alias").Wait(3 * time.Second)
   137  			Eventually(output.Out).Should(Say("You called cmd1 in test_1"))
   138  		})
   139  
   140  		It("Can call another plugin command when more than one plugin is installed", func() {
   141  			output := Cf("test_2_cmd1").Wait(3 * time.Second)
   142  			Eventually(output.Out).Should(Say("You called cmd1 in test_2"))
   143  		})
   144  
   145  		It("informs user for any invalid commands", func() {
   146  			output := Cf("foo-bar")
   147  			Eventually(output.Out, 3*time.Second).Should(Say("'foo-bar' is not a registered command"))
   148  		})
   149  
   150  		It("Calls help if the plugin shares the same name", func() {
   151  			output := Cf("help")
   152  			Consistently(output.Out, 1).ShouldNot(Say("You called help in test_with_help"))
   153  		})
   154  
   155  		It("Can call help for a plugin command", func() {
   156  			output := Cf("help", "test_1_cmd1").Wait(3 * time.Second)
   157  			Eventually(output.Out).ShouldNot(Say("You called cmd1 in test_1"))
   158  			Eventually(output.Out.Contents).Should(ContainSubstring("USAGE:"))
   159  			Eventually(output.Out.Contents).Should(ContainSubstring("cf test_1_cmd1 [-a] [-b] [--no-ouput]"))
   160  			Eventually(output.Out.Contents).Should(ContainSubstring("OPTIONS:"))
   161  			Eventually(output.Out.Contents).Should(ContainSubstring("----no-output	example option with no use"))
   162  		})
   163  
   164  		It("shows help with a '-h' or '--help' flag in plugin command", func() {
   165  			output := Cf("test_1_cmd1", "-h").Wait(3 * time.Second)
   166  			Eventually(output.Out).ShouldNot(Say("You called cmd1 in test_1"))
   167  			Eventually(output.Out.Contents).Should(ContainSubstring("USAGE:"))
   168  			Eventually(output.Out.Contents).Should(ContainSubstring("OPTIONS:"))
   169  		})
   170  
   171  		It("Calls the core push command if the plugin shares the same name", func() {
   172  			output := Cf("push")
   173  			Consistently(output.Out, 1).ShouldNot(Say("You called push in test_with_push"))
   174  		})
   175  
   176  		It("Calls the core short name if a plugin shares the same name", func() {
   177  			output := Cf("p")
   178  			Consistently(output.Out, 1).ShouldNot(Say("You called p within the plugin"))
   179  		})
   180  
   181  		It("Passes all arguments to a plugin", func() {
   182  			output := Cf("my-say", "foo").Wait(3 * time.Second)
   183  			Eventually(output.Out).Should(Say("foo"))
   184  		})
   185  
   186  		It("Passes all arguments and flags to a plugin", func() {
   187  			output := Cf("my-say", "foo", "--loud").Wait(3 * time.Second)
   188  			Eventually(output.Out).Should(Say("FOO"))
   189  		})
   190  
   191  		It("Calls a plugin that calls core commands", func() {
   192  			output := Cf("awesomeness").Wait(3 * time.Second)
   193  			Eventually(output.Out).Should(Say("my-say")) //look for another plugin
   194  		})
   195  
   196  		It("Sends stdoutput to the plugin to echo", func() {
   197  			output := Cf("core-command", "plugins").Wait(3 * time.Second)
   198  			Eventually(output.Out.Contents).Should(MatchRegexp("Command output from the plugin(.*\\W)*awesomeness(.*\\W)*FIN"))
   199  		})
   200  
   201  		It("Can call a core commmand from a plugin without terminal output", func() {
   202  			output := Cf("core-command-quiet", "plugins").Wait(3 * time.Second)
   203  			Eventually(output.Out.Contents).Should(MatchRegexp("^\n---------- Command output from the plugin"))
   204  		})
   205  
   206  		It("Can call a plugin that requires stdin (interactive)", func() {
   207  			session := CfWithIo("input", "silly\n").Wait(5 * time.Second)
   208  			Eventually(session.Out).Should(Say("silly"))
   209  		})
   210  
   211  		It("exits 1 when a plugin panics", func() {
   212  			session := Cf("panic").Wait(5 * time.Second)
   213  			Eventually(session).Should(Exit(1))
   214  		})
   215  
   216  		It("exits 1 when a plugin exits 1", func() {
   217  			session := Cf("exit1").Wait(5 * time.Second)
   218  			Eventually(session).Should(Exit(1))
   219  		})
   220  	})
   221  })
   222  
   223  func Cf(args ...string) *Session {
   224  	path, err := Build("github.com/cloudfoundry/cli/main")
   225  	Expect(err).NotTo(HaveOccurred())
   226  
   227  	session, err := Start(exec.Command(path, args...), GinkgoWriter, GinkgoWriter)
   228  	Expect(err).NotTo(HaveOccurred())
   229  
   230  	return session
   231  }
   232  func CfWithIo(command string, args string) *Session {
   233  	path, err := Build("github.com/cloudfoundry/cli/main")
   234  	Expect(err).NotTo(HaveOccurred())
   235  
   236  	cmd := exec.Command(path, command)
   237  
   238  	stdin, err := cmd.StdinPipe()
   239  	Expect(err).ToNot(HaveOccurred())
   240  
   241  	buffer := bufio.NewWriter(stdin)
   242  	buffer.WriteString(args)
   243  	buffer.Flush()
   244  
   245  	session, err := Start(cmd, GinkgoWriter, GinkgoWriter)
   246  	Expect(err).NotTo(HaveOccurred())
   247  
   248  	return session
   249  }
   250  
   251  // gexec.Build leaves a compiled binary behind in /tmp.
   252  var _ = AfterSuite(func() {
   253  	CleanupBuildArtifacts()
   254  })