thor 0.17.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. data/{CHANGELOG.rdoc → CHANGELOG.md} +30 -36
  2. data/README.md +10 -3
  3. data/lib/thor.rb +205 -180
  4. data/lib/thor/actions.rb +5 -5
  5. data/lib/thor/actions/create_link.rb +3 -0
  6. data/lib/thor/actions/directory.rb +2 -0
  7. data/lib/thor/actions/file_manipulation.rb +1 -1
  8. data/lib/thor/base.rb +84 -95
  9. data/lib/thor/{task.rb → command.rb} +17 -13
  10. data/lib/thor/core_ext/io_binary_read.rb +12 -0
  11. data/lib/thor/error.rb +4 -7
  12. data/lib/thor/group.rb +30 -33
  13. data/lib/thor/invocation.rb +28 -26
  14. data/lib/thor/parser/options.rb +3 -1
  15. data/lib/thor/runner.rb +21 -20
  16. data/lib/thor/shell/basic.rb +5 -1
  17. data/lib/thor/shell/color.rb +4 -0
  18. data/lib/thor/shell/html.rb +4 -0
  19. data/lib/thor/util.rb +214 -210
  20. data/lib/thor/version.rb +1 -1
  21. data/spec/actions/create_file_spec.rb +1 -1
  22. data/spec/actions/create_link_spec.rb +15 -1
  23. data/spec/actions/directory_spec.rb +18 -5
  24. data/spec/actions/empty_directory_spec.rb +1 -1
  25. data/spec/actions/file_manipulation_spec.rb +13 -13
  26. data/spec/actions/inject_into_file_spec.rb +1 -1
  27. data/spec/actions_spec.rb +1 -1
  28. data/spec/base_spec.rb +40 -24
  29. data/spec/command_spec.rb +80 -0
  30. data/spec/core_ext/hash_with_indifferent_access_spec.rb +1 -1
  31. data/spec/core_ext/ordered_hash_spec.rb +1 -1
  32. data/spec/exit_condition_spec.rb +3 -3
  33. data/spec/fixtures/{task.thor → command.thor} +0 -0
  34. data/spec/fixtures/doc/%file_name%.rb.tt +1 -0
  35. data/spec/fixtures/doc/COMMENTER +11 -0
  36. data/spec/fixtures/doc/README +3 -0
  37. data/spec/fixtures/doc/block_helper.rb +3 -0
  38. data/spec/fixtures/doc/config.rb +1 -0
  39. data/spec/fixtures/doc/config.yaml.tt +1 -0
  40. data/spec/fixtures/doc/excluding/%file_name%.rb.tt +1 -0
  41. data/spec/fixtures/group.thor +24 -10
  42. data/spec/fixtures/invoke.thor +3 -3
  43. data/spec/fixtures/script.thor +40 -15
  44. data/spec/fixtures/subcommand.thor +17 -0
  45. data/spec/group_spec.rb +13 -13
  46. data/spec/{spec_helper.rb → helper.rb} +11 -7
  47. data/spec/invocation_spec.rb +16 -16
  48. data/spec/parser/argument_spec.rb +4 -4
  49. data/spec/parser/arguments_spec.rb +1 -1
  50. data/spec/parser/option_spec.rb +1 -1
  51. data/spec/parser/options_spec.rb +6 -1
  52. data/spec/rake_compat_spec.rb +1 -1
  53. data/spec/register_spec.rb +12 -12
  54. data/spec/runner_spec.rb +36 -36
  55. data/spec/shell/basic_spec.rb +9 -10
  56. data/spec/shell/color_spec.rb +16 -2
  57. data/spec/shell/html_spec.rb +1 -1
  58. data/spec/shell_spec.rb +1 -1
  59. data/spec/subcommand_spec.rb +30 -0
  60. data/spec/thor_spec.rb +81 -78
  61. data/spec/util_spec.rb +10 -10
  62. data/thor.gemspec +22 -18
  63. metadata +49 -38
  64. data/.gitignore +0 -44
  65. data/.rspec +0 -3
  66. data/.travis.yml +0 -8
  67. data/Gemfile +0 -19
  68. data/bin/rake2thor +0 -86
  69. data/lib/thor/core_ext/file_binary_read.rb +0 -9
  70. data/spec/task_spec.rb +0 -80
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require 'helper'
2
2
  require 'thor/parser'
3
3
 
4
4
  describe Thor::Arguments do
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require 'helper'
2
2
  require 'thor/parser'
3
3
 
4
4
  describe Thor::Option do
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require 'helper'
2
2
  require 'thor/parser'
3
3
 
4
4
  describe Thor::Options do
@@ -223,6 +223,11 @@ describe Thor::Options do
223
223
  expect(remaining).to eq(["--bar", "--verbose"])
224
224
  end
225
225
 
226
+ it "retains -- after it has stopped parsing" do
227
+ expect(parse(%w[--bar -- whatever])).to eq({})
228
+ expect(remaining).to eq(["--bar", "--", "whatever"])
229
+ end
230
+
226
231
  it "still accepts options that are given before non-options" do
227
232
  expect(parse(%w[--verbose foo])).to eq({"verbose" => true})
228
233
  expect(remaining).to eq(["foo"])
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
1
+ require 'helper'
2
2
  require 'thor/rake_compat'
3
3
  require 'rake/tasklib'
4
4
 
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
1
+ require 'helper'
2
2
 
3
3
  class BoringVendorProvidedCLI < Thor
4
4
  desc "boring", "do boring stuff"
@@ -20,7 +20,7 @@ class ExcitingPluginCLI < Thor
20
20
  end
21
21
 
22
22
  class SuperSecretPlugin < Thor
23
- default_task :squirrel
23
+ default_command :squirrel
24
24
 
25
25
  desc "squirrel", "All of secret squirrel's secrets"
26
26
  def squirrel
@@ -60,7 +60,7 @@ class PluginWithDefault < Thor
60
60
  puts msg
61
61
  end
62
62
 
63
- default_task :say
63
+ default_command :say
64
64
  end
65
65
 
66
66
  class PluginWithDefaultMultipleArguments < Thor
@@ -69,17 +69,17 @@ class PluginWithDefaultMultipleArguments < Thor
69
69
  puts args
70
70
  end
71
71
 
72
- default_task :say
72
+ default_command :say
73
73
  end
74
74
 
75
- class PluginWithDefaultTaskAndDeclaredArgument < Thor
75
+ class PluginWithDefaultcommandAndDeclaredArgument < Thor
76
76
  desc "say MSG [MSG]", "print multiple messages"
77
77
  argument :msg
78
78
  def say
79
79
  puts msg
80
80
  end
81
81
 
82
- default_task :say
82
+ default_command :say
83
83
  end
84
84
 
85
85
  BoringVendorProvidedCLI.register(
@@ -120,7 +120,7 @@ BoringVendorProvidedCLI.register(
120
120
  'subcommands ftw')
121
121
 
122
122
  BoringVendorProvidedCLI.register(
123
- PluginWithDefaultTaskAndDeclaredArgument,
123
+ PluginWithDefaultcommandAndDeclaredArgument,
124
124
  'say_argument',
125
125
  'say message',
126
126
  'subcommands ftw')
@@ -136,18 +136,18 @@ describe ".register-ing a Thor subclass" do
136
136
  expect(help_output).to include('do exciting things')
137
137
  end
138
138
 
139
- it "invokes the default task correctly" do
139
+ it "invokes the default command correctly" do
140
140
  output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[say hello]) }
141
141
  expect(output).to include("hello")
142
142
  end
143
143
 
144
- it "invokes the default task correctly with multiple args" do
144
+ it "invokes the default command correctly with multiple args" do
145
145
  output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[say_multiple hello adam]) }
146
146
  expect(output).to include("hello")
147
147
  expect(output).to include("adam")
148
148
  end
149
149
 
150
- it "invokes the default task correctly with a declared argument" do
150
+ it "invokes the default command correctly with a declared argument" do
151
151
  output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[say_argument hello]) }
152
152
  expect(output).to include("hello")
153
153
  end
@@ -185,12 +185,12 @@ describe ".register-ing a Thor::Group subclass" do
185
185
  end
186
186
 
187
187
  describe "1.8 and 1.9 syntax compatibility" do
188
- it "is compatible with both 1.8 and 1.9 syntax w/o task options" do
188
+ it "is compatible with both 1.8 and 1.9 syntax w/o command options" do
189
189
  group_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[zoo]) }
190
190
  expect(group_output).to match(/zebra/)
191
191
  end
192
192
 
193
- it "is compatible with both 1.8 and 1.9 syntax w/task options" do
193
+ it "is compatible with both 1.8 and 1.9 syntax w/command options" do
194
194
  group_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[zoo -w lion]) }
195
195
  expect(group_output).to match(/lion/)
196
196
  end
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
1
+ require 'helper'
2
2
  require 'thor/runner'
3
3
 
4
4
  describe Thor::Runner do
@@ -14,13 +14,13 @@ describe Thor::Runner do
14
14
 
15
15
  describe "#help" do
16
16
  it "shows information about Thor::Runner itself" do
17
- expect(capture(:stdout) { Thor::Runner.start(["help"]) }).to match(/List the available thor tasks/)
17
+ expect(capture(:stdout) { Thor::Runner.start(["help"]) }).to match(/List the available thor commands/)
18
18
  end
19
19
 
20
- it "shows information about an specific Thor::Runner task" do
20
+ it "shows information about a specific Thor::Runner command" do
21
21
  content = capture(:stdout) { Thor::Runner.start(["help", "list"]) }
22
- expect(content).to match(/List the available thor tasks/)
23
- expect(content).not_to match(/help \[TASK\]/)
22
+ expect(content).to match(/List the available thor commands/)
23
+ expect(content).not_to match(/help \[COMMAND\]/)
24
24
  end
25
25
 
26
26
  it "shows information about a specific Thor class" do
@@ -28,10 +28,10 @@ describe Thor::Runner do
28
28
  expect(content).to match(/zoo\s+# zoo around/m)
29
29
  end
30
30
 
31
- it "shows information about an specific task from an specific Thor class" do
31
+ it "shows information about an specific command from an specific Thor class" do
32
32
  content = capture(:stdout) { Thor::Runner.start(["help", "my_script:zoo"]) }
33
33
  expect(content).to match(/zoo around/)
34
- expect(content).not_to match(/help \[TASK\]/)
34
+ expect(content).not_to match(/help \[COMMAND\]/)
35
35
  end
36
36
 
37
37
  it "shows information about a specific Thor group class" do
@@ -39,63 +39,63 @@ describe Thor::Runner do
39
39
  expect(content).to match(/my_counter N/)
40
40
  end
41
41
 
42
- it "raises error if a class/task cannot be found" do
42
+ it "raises error if a class/command cannot be found" do
43
43
  content = capture(:stderr){ Thor::Runner.start(["help", "unknown"]) }
44
- expect(content.strip).to eq('Could not find task "unknown" in "default" namespace.')
44
+ expect(content.strip).to eq('Could not find command "unknown" in "default" namespace.')
45
45
  end
46
46
 
47
- it "raises error if a class/task cannot be found for a setup without thorfiles" do
47
+ it "raises error if a class/command cannot be found for a setup without thorfiles" do
48
48
  when_no_thorfiles_exist do
49
49
  Thor::Runner.should_receive :exit
50
50
  content = capture(:stderr){ Thor::Runner.start(["help", "unknown"]) }
51
- expect(content.strip).to eq('Could not find task "unknown".')
51
+ expect(content.strip).to eq('Could not find command "unknown".')
52
52
  end
53
53
  end
54
54
  end
55
55
 
56
56
  describe "#start" do
57
- it "invokes a task from Thor::Runner" do
57
+ it "invokes a command from Thor::Runner" do
58
58
  ARGV.replace ["list"]
59
59
  expect(capture(:stdout) { Thor::Runner.start }).to match(/my_counter N/)
60
60
  end
61
61
 
62
- it "invokes a task from a specific Thor class" do
62
+ it "invokes a command from a specific Thor class" do
63
63
  ARGV.replace ["my_script:zoo"]
64
64
  expect(Thor::Runner.start).to be_true
65
65
  end
66
66
 
67
- it "invokes the default task from a specific Thor class if none is specified" do
67
+ it "invokes the default command from a specific Thor class if none is specified" do
68
68
  ARGV.replace ["my_script"]
69
- expect(Thor::Runner.start).to eq("default task")
69
+ expect(Thor::Runner.start).to eq("default command")
70
70
  end
71
71
 
72
- it "forwads arguments to the invoked task" do
72
+ it "forwads arguments to the invoked command" do
73
73
  ARGV.replace ["my_script:animal", "horse"]
74
74
  expect(Thor::Runner.start).to eq(["horse"])
75
75
  end
76
76
 
77
- it "invokes tasks through shortcuts" do
77
+ it "invokes commands through shortcuts" do
78
78
  ARGV.replace ["my_script", "-T", "horse"]
79
79
  expect(Thor::Runner.start).to eq(["horse"])
80
80
  end
81
81
 
82
82
  it "invokes a Thor::Group" do
83
83
  ARGV.replace ["my_counter", "1", "2", "--third", "3"]
84
- expect(Thor::Runner.start).to eq([1, 2, 3])
84
+ expect(Thor::Runner.start).to eq([1, 2, 3, nil, nil, nil])
85
85
  end
86
86
 
87
- it "raises an error if class/task can't be found" do
87
+ it "raises an error if class/command can't be found" do
88
88
  ARGV.replace ["unknown"]
89
89
  content = capture(:stderr){ Thor::Runner.start }
90
- expect(content.strip).to eq('Could not find task "unknown" in "default" namespace.')
90
+ expect(content.strip).to eq('Could not find command "unknown" in "default" namespace.')
91
91
  end
92
92
 
93
- it "raises an error if class/task can't be found in a setup without thorfiles" do
93
+ it "raises an error if class/command can't be found in a setup without thorfiles" do
94
94
  when_no_thorfiles_exist do
95
95
  ARGV.replace ["unknown"]
96
96
  Thor::Runner.should_receive :exit
97
97
  content = capture(:stderr){ Thor::Runner.start }
98
- expect(content.strip).to eq('Could not find task "unknown".')
98
+ expect(content.strip).to eq('Could not find command "unknown".')
99
99
  end
100
100
  end
101
101
 
@@ -112,13 +112,13 @@ describe Thor::Runner do
112
112
  it "does not swallow Thor InvocationError" do
113
113
  ARGV.replace ["my_script:animal"]
114
114
  content = capture(:stderr) { Thor::Runner.start }
115
- expect(content.strip).to eq('thor animal requires at least 1 argument: "thor my_script:animal TYPE".')
115
+ expect(content.strip).to eq(%Q'ERROR: thor animal was called with no arguments\nUsage: "thor my_script:animal TYPE".')
116
116
  end
117
117
  end
118
118
 
119
- describe "tasks" do
119
+ describe "commands" do
120
120
  before do
121
- @location = "#{File.dirname(__FILE__)}/fixtures/task.thor"
121
+ @location = "#{File.dirname(__FILE__)}/fixtures/command.thor"
122
122
  @original_yaml = {
123
123
  "random" => {
124
124
  :location => @location,
@@ -136,7 +136,7 @@ describe Thor::Runner do
136
136
  end
137
137
 
138
138
  describe "list" do
139
- it "gives a list of the available tasks" do
139
+ it "gives a list of the available commands" do
140
140
  ARGV.replace ["list"]
141
141
  content = capture(:stdout) { Thor::Runner.start }
142
142
  expect(content).to match(/amazing:describe NAME\s+# say that someone is amazing/m)
@@ -147,7 +147,7 @@ describe Thor::Runner do
147
147
  expect(capture(:stdout) { Thor::Runner.start }).to match(/my_counter N/)
148
148
  end
149
149
 
150
- it "can filter a list of the available tasks by --group" do
150
+ it "can filter a list of the available commands by --group" do
151
151
  ARGV.replace ["list", "--group", "standard"]
152
152
  expect(capture(:stdout) { Thor::Runner.start }).to match(/amazing:describe NAME/)
153
153
  ARGV.replace []
@@ -156,34 +156,34 @@ describe Thor::Runner do
156
156
  expect(capture(:stdout) { Thor::Runner.start }).to match(/my_script:animal TYPE/)
157
157
  end
158
158
 
159
- it "can skip all filters to show all tasks using --all" do
159
+ it "can skip all filters to show all commands using --all" do
160
160
  ARGV.replace ["list", "--all"]
161
161
  content = capture(:stdout) { Thor::Runner.start }
162
162
  expect(content).to match(/amazing:describe NAME/)
163
163
  expect(content).to match(/my_script:animal TYPE/)
164
164
  end
165
165
 
166
- it "doesn't list superclass tasks in the subclass" do
166
+ it "doesn't list superclass commands in the subclass" do
167
167
  ARGV.replace ["list"]
168
168
  expect(capture(:stdout) { Thor::Runner.start }).not_to match(/amazing:help/)
169
169
  end
170
170
 
171
- it "presents tasks in the default namespace with an empty namespace" do
171
+ it "presents commands in the default namespace with an empty namespace" do
172
172
  ARGV.replace ["list"]
173
173
  expect(capture(:stdout) { Thor::Runner.start }).to match(/^thor :cow\s+# prints 'moo'/m)
174
174
  end
175
175
 
176
- it "runs tasks with an empty namespace from the default namespace" do
177
- ARGV.replace [":task_conflict"]
178
- expect(capture(:stdout) { Thor::Runner.start }).to eq("task\n")
176
+ it "runs commands with an empty namespace from the default namespace" do
177
+ ARGV.replace [":command_conflict"]
178
+ expect(capture(:stdout) { Thor::Runner.start }).to eq("command\n")
179
179
  end
180
180
 
181
- it "runs groups even when there is a task with the same name" do
182
- ARGV.replace ["task_conflict"]
181
+ it "runs groups even when there is a command with the same name" do
182
+ ARGV.replace ["command_conflict"]
183
183
  expect(capture(:stdout) { Thor::Runner.start }).to eq("group\n")
184
184
  end
185
185
 
186
- it "runs tasks with no colon in the default namespace" do
186
+ it "runs commands with no colon in the default namespace" do
187
187
  ARGV.replace ["cow"]
188
188
  expect(capture(:stdout) { Thor::Runner.start }).to eq("moo\n")
189
189
  end
@@ -1,6 +1,5 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ # coding: UTF-8
2
+ require 'helper'
4
3
 
5
4
  describe Thor::Shell::Basic do
6
5
  def shell
@@ -93,8 +92,8 @@ describe Thor::Shell::Basic do
93
92
 
94
93
  describe "#say_status" do
95
94
  it "prints a message to the user with status" do
96
- $stdout.should_receive(:puts).with(" create ~/.thor/task.thor")
97
- shell.say_status(:create, "~/.thor/task.thor")
95
+ $stdout.should_receive(:puts).with(" create ~/.thor/command.thor")
96
+ shell.say_status(:create, "~/.thor/command.thor")
98
97
  end
99
98
 
100
99
  it "always use new line" do
@@ -107,7 +106,7 @@ describe Thor::Shell::Basic do
107
106
  $stdout.should_not_receive(:puts)
108
107
 
109
108
  shell.mute do
110
- shell.say_status(:created, "~/.thor/task.thor")
109
+ shell.say_status(:created, "~/.thor/command.thor")
111
110
  end
112
111
  end
113
112
 
@@ -117,18 +116,18 @@ describe Thor::Shell::Basic do
117
116
 
118
117
  $stdout.should_not_receive(:puts)
119
118
  shell.base = base
120
- shell.say_status(:created, "~/.thor/task.thor")
119
+ shell.say_status(:created, "~/.thor/command.thor")
121
120
  end
122
121
 
123
122
  it "does not print a message if log status is set to false" do
124
123
  $stdout.should_not_receive(:puts)
125
- shell.say_status(:created, "~/.thor/task.thor", false)
124
+ shell.say_status(:created, "~/.thor/command.thor", false)
126
125
  end
127
126
 
128
127
  it "uses padding to set messages left margin" do
129
128
  shell.padding = 2
130
- $stdout.should_receive(:puts).with(" create ~/.thor/task.thor")
131
- shell.say_status(:create, "~/.thor/task.thor")
129
+ $stdout.should_receive(:puts).with(" create ~/.thor/command.thor")
130
+ shell.say_status(:create, "~/.thor/command.thor")
132
131
  end
133
132
  end
134
133
 
@@ -1,12 +1,16 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require 'helper'
2
2
 
3
3
  describe Thor::Shell::Color do
4
4
  def shell
5
5
  @shell ||= Thor::Shell::Color.new
6
6
  end
7
7
 
8
+ before do
9
+ StringIO.any_instance.stub(:tty?).and_return(true)
10
+ end
11
+
8
12
  describe "#say" do
9
- it "set the color if specified" do
13
+ it "set the color if specified and tty?" do
10
14
  out = capture(:stdout) do
11
15
  shell.say "Wow! Now we have colors!", :green
12
16
  end
@@ -14,6 +18,15 @@ describe Thor::Shell::Color do
14
18
  expect(out.chomp).to eq("\e[32mWow! Now we have colors!\e[0m")
15
19
  end
16
20
 
21
+ it "does not set the color if output is not a tty" do
22
+ out = capture(:stdout) do
23
+ $stdout.should_receive(:tty?).and_return(false)
24
+ shell.say "Wow! Now we have colors!", :green
25
+ end
26
+
27
+ expect(out.chomp).to eq("Wow! Now we have colors!")
28
+ end
29
+
17
30
  it "does not use a new line even with colors" do
18
31
  out = capture(:stdout) do
19
32
  shell.say "Wow! Now we have colors! ", :green
@@ -68,6 +81,7 @@ describe Thor::Shell::Color do
68
81
  describe "when a block is given" do
69
82
  it "invokes the diff command" do
70
83
  $stdout.stub!(:print)
84
+ $stdout.stub!(:tty?).and_return(true)
71
85
  $stdin.should_receive(:gets).and_return('d')
72
86
  $stdin.should_receive(:gets).and_return('n')
73
87
 
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require 'helper'
2
2
 
3
3
  describe Thor::Shell::HTML do
4
4
  def shell
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
1
+ require 'helper'
2
2
 
3
3
  describe Thor::Shell do
4
4
  def shell
@@ -0,0 +1,30 @@
1
+ require 'helper'
2
+
3
+ describe Thor do
4
+
5
+ describe "#subcommand" do
6
+
7
+ it "maps a given subcommand to another Thor subclass" do
8
+ barn_help = capture(:stdout) { Scripts::MyDefaults.start(%w[barn]) }
9
+ expect(barn_help).to include("barn help [COMMAND] # Describe subcommands or one specific subcommand")
10
+ end
11
+
12
+ it "passes commands to subcommand classes" do
13
+ expect(capture(:stdout) { Scripts::MyDefaults.start(%w[barn open]) }.strip).to eq("Open sesame!")
14
+ end
15
+
16
+ it "passes arguments to subcommand classes" do
17
+ expect(capture(:stdout) { Scripts::MyDefaults.start(%w[barn open shotgun]) }.strip).to eq("That's going to leave a mark.")
18
+ end
19
+
20
+ it "ignores unknown options (the subcommand class will handle them)" do
21
+ expect(capture(:stdout) { Scripts::MyDefaults.start(%w[barn paint blue --coats 4])}.strip).to eq("4 coats of blue paint")
22
+ end
23
+
24
+ it "passes parsed options to subcommands" do
25
+ output = capture(:stdout) { TestSubcommands::Parent.start(%w[sub print_opt --opt output]) }
26
+ expect(output).to eq("output")
27
+ end
28
+ end
29
+
30
+ end