22
23
return jc, tc, testing.InitCommand(jc, args)
25
type SuperCommandSuite struct{}
26
type SuperCommandSuite struct {
27
var _ = Suite(&SuperCommandSuite{})
30
var _ = gc.Suite(&SuperCommandSuite{})
29
32
const helpText = "\n help\\s+- show help on a command or other topic"
30
33
const helpCommandsText = "commands:" + helpText
32
func (s *SuperCommandSuite) TestDispatch(c *C) {
35
func (s *SuperCommandSuite) TestDispatch(c *gc.C) {
33
36
jc := cmd.NewSuperCommand(cmd.SuperCommandParams{Name: "jujutest"})
35
c.Assert(info.Name, Equals, "jujutest")
36
c.Assert(info.Args, Equals, "<command> ...")
37
c.Assert(info.Doc, Matches, helpCommandsText)
38
c.Assert(info.Name, gc.Equals, "jujutest")
39
c.Assert(info.Args, gc.Equals, "<command> ...")
40
c.Assert(info.Doc, gc.Matches, helpCommandsText)
39
42
jc, _, err := initDefenestrate([]string{"discombobulate"})
40
c.Assert(err, ErrorMatches, "unrecognized command: jujutest discombobulate")
43
c.Assert(err, gc.ErrorMatches, "unrecognized command: jujutest discombobulate")
42
c.Assert(info.Name, Equals, "jujutest")
43
c.Assert(info.Args, Equals, "<command> ...")
44
c.Assert(info.Doc, Matches, "commands:\n defenestrate - defenestrate the juju"+helpText)
45
c.Assert(info.Name, gc.Equals, "jujutest")
46
c.Assert(info.Args, gc.Equals, "<command> ...")
47
c.Assert(info.Doc, gc.Matches, "commands:\n defenestrate - defenestrate the juju"+helpText)
46
49
jc, tc, err := initDefenestrate([]string{"defenestrate"})
48
c.Assert(tc.Option, Equals, "")
50
c.Assert(err, gc.IsNil)
51
c.Assert(tc.Option, gc.Equals, "")
50
c.Assert(info.Name, Equals, "jujutest defenestrate")
51
c.Assert(info.Args, Equals, "<something>")
52
c.Assert(info.Doc, Equals, "defenestrate-doc")
53
c.Assert(info.Name, gc.Equals, "jujutest defenestrate")
54
c.Assert(info.Args, gc.Equals, "<something>")
55
c.Assert(info.Doc, gc.Equals, "defenestrate-doc")
54
57
_, tc, err = initDefenestrate([]string{"defenestrate", "--option", "firmly"})
56
c.Assert(tc.Option, Equals, "firmly")
58
c.Assert(err, gc.IsNil)
59
c.Assert(tc.Option, gc.Equals, "firmly")
58
61
_, tc, err = initDefenestrate([]string{"defenestrate", "gibberish"})
59
c.Assert(err, ErrorMatches, `unrecognized args: \["gibberish"\]`)
62
c.Assert(err, gc.ErrorMatches, `unrecognized args: \["gibberish"\]`)
61
64
// --description must be used on it's own.
62
65
_, _, err = initDefenestrate([]string{"--description", "defenestrate"})
63
c.Assert(err, ErrorMatches, `unrecognized args: \["defenestrate"\]`)
66
c.Assert(err, gc.ErrorMatches, `unrecognized args: \["defenestrate"\]`)
66
func (s *SuperCommandSuite) TestRegister(c *C) {
69
func (s *SuperCommandSuite) TestRegister(c *gc.C) {
67
70
jc := cmd.NewSuperCommand(cmd.SuperCommandParams{Name: "jujutest"})
68
71
jc.Register(&TestCommand{Name: "flip"})
69
72
jc.Register(&TestCommand{Name: "flap"})
70
73
badCall := func() { jc.Register(&TestCommand{Name: "flap"}) }
71
c.Assert(badCall, PanicMatches, "command already registered: flap")
74
c.Assert(badCall, gc.PanicMatches, "command already registered: flap")
74
func (s *SuperCommandSuite) TestRegisterAlias(c *C) {
77
func (s *SuperCommandSuite) TestRegisterAlias(c *gc.C) {
75
78
jc := cmd.NewSuperCommand(cmd.SuperCommandParams{Name: "jujutest"})
76
79
jc.Register(&TestCommand{Name: "flip", Aliases: []string{"flap", "flop"}})
79
c.Assert(info.Doc, Equals, `commands:
82
c.Assert(info.Doc, gc.Equals, `commands:
80
83
flap - alias for flip
81
84
flip - flip the juju
82
85
flop - alias for flip
87
90
flapbabble - flapbabble the juju
88
91
flip - flip the juju`
90
func (s *SuperCommandSuite) TestInfo(c *C) {
93
func (s *SuperCommandSuite) TestInfo(c *gc.C) {
91
94
jc := cmd.NewSuperCommand(cmd.SuperCommandParams{
93
96
Purpose: "to be purposeful",
94
97
Doc: "doc\nblah\ndoc",
97
c.Assert(info.Name, Equals, "jujutest")
98
c.Assert(info.Purpose, Equals, "to be purposeful")
100
c.Assert(info.Name, gc.Equals, "jujutest")
101
c.Assert(info.Purpose, gc.Equals, "to be purposeful")
99
102
// info doc starts with the jc.Doc and ends with the help command
100
c.Assert(info.Doc, Matches, jc.Doc+"(.|\n)*")
101
c.Assert(info.Doc, Matches, "(.|\n)*"+helpCommandsText)
103
c.Assert(info.Doc, gc.Matches, jc.Doc+"(.|\n)*")
104
c.Assert(info.Doc, gc.Matches, "(.|\n)*"+helpCommandsText)
103
106
jc.Register(&TestCommand{Name: "flip"})
104
107
jc.Register(&TestCommand{Name: "flapbabble"})
106
c.Assert(info.Doc, Matches, jc.Doc+"\n\n"+commandsDoc+helpText)
109
c.Assert(info.Doc, gc.Matches, jc.Doc+"\n\n"+commandsDoc+helpText)
110
c.Assert(info.Doc, Matches, commandsDoc+helpText)
113
c.Assert(info.Doc, gc.Matches, commandsDoc+helpText)
113
116
type testVersionFlagCommand struct {
163
166
// and there should be no output. The --version flag on the 'test'
164
167
// subcommand has a different type to the "juju --version" flag.
165
168
code = cmd.Main(jc, ctx, []string{"test", "--version=abc.123"})
166
c.Check(code, Equals, 0)
167
c.Assert(stderr.String(), Equals, "")
168
c.Assert(stdout.String(), Equals, "")
169
c.Assert(testVersionFlagCommand.version, Equals, "abc.123")
169
c.Check(code, gc.Equals, 0)
170
c.Assert(stderr.String(), gc.Equals, "")
171
c.Assert(stdout.String(), gc.Equals, "")
172
c.Assert(testVersionFlagCommand.version, gc.Equals, "abc.123")
172
func (s *SuperCommandSuite) TestLogging(c *C) {
175
func (s *SuperCommandSuite) TestLogging(c *gc.C) {
173
176
jc := cmd.NewSuperCommand(cmd.SuperCommandParams{Name: "jujutest", Log: &cmd.Log{}})
174
177
jc.Register(&TestCommand{Name: "blah"})
175
178
ctx := testing.Context(c)
176
179
code := cmd.Main(jc, ctx, []string{"blah", "--option", "error", "--debug"})
177
c.Assert(code, Equals, 1)
178
c.Assert(bufferString(ctx.Stderr), Matches, `^.* ERROR .* command failed: BAM!
180
c.Assert(code, gc.Equals, 1)
181
c.Assert(bufferString(ctx.Stderr), gc.Matches, `^.* ERROR .* BAM!
183
func (s *SuperCommandSuite) TestDescription(c *C) {
185
func (s *SuperCommandSuite) TestDescription(c *gc.C) {
184
186
jc := cmd.NewSuperCommand(cmd.SuperCommandParams{Name: "jujutest", Purpose: "blow up the death star"})
185
187
jc.Register(&TestCommand{Name: "blah"})
186
188
ctx := testing.Context(c)
187
189
code := cmd.Main(jc, ctx, []string{"blah", "--description"})
188
c.Assert(code, Equals, 0)
189
c.Assert(bufferString(ctx.Stdout), Equals, "blow up the death star\n")
190
c.Assert(code, gc.Equals, 0)
191
c.Assert(bufferString(ctx.Stdout), gc.Equals, "blow up the death star\n")
192
func (s *SuperCommandSuite) TestHelp(c *C) {
194
func (s *SuperCommandSuite) TestHelp(c *gc.C) {
193
195
jc := cmd.NewSuperCommand(cmd.SuperCommandParams{Name: "jujutest"})
194
196
jc.Register(&TestCommand{Name: "blah"})
195
197
ctx := testing.Context(c)
196
198
code := cmd.Main(jc, ctx, []string{"blah", "--help"})
197
c.Assert(code, Equals, 0)
199
c.Assert(code, gc.Equals, 0)
198
200
stripped := strings.Replace(bufferString(ctx.Stdout), "\n", "", -1)
199
c.Assert(stripped, Matches, ".*usage: jujutest blah.*blah-doc.*")
201
c.Assert(stripped, gc.Matches, ".*usage: jujutest blah.*blah-doc.*")
202
func (s *SuperCommandSuite) TestHelpWithPrefix(c *C) {
204
func (s *SuperCommandSuite) TestHelpWithPrefix(c *gc.C) {
203
205
jc := cmd.NewSuperCommand(cmd.SuperCommandParams{Name: "jujutest", UsagePrefix: "juju"})
204
206
jc.Register(&TestCommand{Name: "blah"})
205
207
ctx := testing.Context(c)
206
208
code := cmd.Main(jc, ctx, []string{"blah", "--help"})
207
c.Assert(code, Equals, 0)
209
c.Assert(code, gc.Equals, 0)
208
210
stripped := strings.Replace(bufferString(ctx.Stdout), "\n", "", -1)
209
c.Assert(stripped, Matches, ".*usage: juju jujutest blah.*blah-doc.*")
211
c.Assert(stripped, gc.Matches, ".*usage: juju jujutest blah.*blah-doc.*")
212
214
func NewSuperWithCallback(callback func(*cmd.Context, string, []string) error) cmd.Command {
231
233
NewSuperWithCallback(callback),
232
234
testing.Context(c),
233
235
[]string{"foo", "bar", "baz", "--debug"})
234
c.Assert(code, Equals, 0)
235
c.Assert(calledName, Equals, "foo")
236
c.Assert(calledArgs, DeepEquals, []string{"bar", "baz", "--debug"})
236
c.Assert(code, gc.Equals, 0)
237
c.Assert(calledName, gc.Equals, "foo")
238
c.Assert(calledArgs, gc.DeepEquals, []string{"bar", "baz", "--debug"})
239
func (s *SuperCommandSuite) TestMissingCallbackErrors(c *C) {
241
func (s *SuperCommandSuite) TestMissingCallbackErrors(c *gc.C) {
240
242
callback := func(ctx *cmd.Context, subcommand string, args []string) error {
241
243
return fmt.Errorf("command not found %q", subcommand)
244
246
ctx := testing.Context(c)
245
247
code := cmd.Main(NewSuperWithCallback(callback), ctx, []string{"foo"})
246
c.Assert(code, Equals, 1)
247
c.Assert(testing.Stdout(ctx), Equals, "")
248
c.Assert(testing.Stderr(ctx), Equals, "error: command not found \"foo\"\n")
248
c.Assert(code, gc.Equals, 1)
249
c.Assert(testing.Stdout(ctx), gc.Equals, "")
250
c.Assert(testing.Stderr(ctx), gc.Equals, "ERROR command not found \"foo\"\n")
251
func (s *SuperCommandSuite) TestMissingCallbackContextWiredIn(c *C) {
253
func (s *SuperCommandSuite) TestMissingCallbackContextWiredIn(c *gc.C) {
252
254
callback := func(ctx *cmd.Context, subcommand string, args []string) error {
253
255
fmt.Fprintf(ctx.Stdout, "this is std out")
254
256
fmt.Fprintf(ctx.Stderr, "this is std err")