thor 0.19.1 → 0.19.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -0
  3. data/CONTRIBUTING.md +15 -0
  4. data/README.md +7 -1
  5. data/lib/thor.rb +31 -23
  6. data/lib/thor/actions.rb +21 -22
  7. data/lib/thor/actions/create_file.rb +1 -1
  8. data/lib/thor/actions/create_link.rb +1 -1
  9. data/lib/thor/actions/directory.rb +2 -2
  10. data/lib/thor/actions/empty_directory.rb +8 -8
  11. data/lib/thor/actions/file_manipulation.rb +23 -12
  12. data/lib/thor/actions/inject_into_file.rb +10 -14
  13. data/lib/thor/base.rb +33 -33
  14. data/lib/thor/command.rb +9 -9
  15. data/lib/thor/core_ext/hash_with_indifferent_access.rb +9 -1
  16. data/lib/thor/core_ext/io_binary_read.rb +7 -5
  17. data/lib/thor/core_ext/ordered_hash.rb +94 -63
  18. data/lib/thor/error.rb +3 -3
  19. data/lib/thor/group.rb +12 -12
  20. data/lib/thor/invocation.rb +4 -5
  21. data/lib/thor/parser/argument.rb +4 -7
  22. data/lib/thor/parser/arguments.rb +16 -16
  23. data/lib/thor/parser/option.rb +39 -19
  24. data/lib/thor/parser/options.rb +7 -5
  25. data/lib/thor/runner.rb +25 -25
  26. data/lib/thor/shell.rb +1 -1
  27. data/lib/thor/shell/basic.rb +41 -26
  28. data/lib/thor/shell/color.rb +1 -1
  29. data/lib/thor/shell/html.rb +4 -4
  30. data/lib/thor/util.rb +8 -7
  31. data/lib/thor/version.rb +1 -1
  32. data/thor.gemspec +6 -9
  33. metadata +6 -148
  34. data/Thorfile +0 -29
  35. data/spec/actions/create_file_spec.rb +0 -168
  36. data/spec/actions/create_link_spec.rb +0 -96
  37. data/spec/actions/directory_spec.rb +0 -169
  38. data/spec/actions/empty_directory_spec.rb +0 -129
  39. data/spec/actions/file_manipulation_spec.rb +0 -392
  40. data/spec/actions/inject_into_file_spec.rb +0 -135
  41. data/spec/actions_spec.rb +0 -331
  42. data/spec/base_spec.rb +0 -298
  43. data/spec/command_spec.rb +0 -79
  44. data/spec/core_ext/hash_with_indifferent_access_spec.rb +0 -48
  45. data/spec/core_ext/ordered_hash_spec.rb +0 -115
  46. data/spec/exit_condition_spec.rb +0 -19
  47. data/spec/fixtures/application.rb +0 -2
  48. data/spec/fixtures/app{1}/README +0 -3
  49. data/spec/fixtures/bundle/execute.rb +0 -6
  50. data/spec/fixtures/bundle/main.thor +0 -1
  51. data/spec/fixtures/command.thor +0 -10
  52. data/spec/fixtures/doc/%file_name%.rb.tt +0 -1
  53. data/spec/fixtures/doc/COMMENTER +0 -11
  54. data/spec/fixtures/doc/README +0 -3
  55. data/spec/fixtures/doc/block_helper.rb +0 -3
  56. data/spec/fixtures/doc/config.rb +0 -1
  57. data/spec/fixtures/doc/config.yaml.tt +0 -1
  58. data/spec/fixtures/doc/excluding/%file_name%.rb.tt +0 -1
  59. data/spec/fixtures/enum.thor +0 -10
  60. data/spec/fixtures/group.thor +0 -128
  61. data/spec/fixtures/invoke.thor +0 -131
  62. data/spec/fixtures/path with spaces b/data/spec/fixtures/path with → spaces +0 -0
  63. data/spec/fixtures/preserve/script.sh +0 -3
  64. data/spec/fixtures/script.thor +0 -220
  65. data/spec/fixtures/subcommand.thor +0 -17
  66. data/spec/group_spec.rb +0 -222
  67. data/spec/helper.rb +0 -80
  68. data/spec/invocation_spec.rb +0 -120
  69. data/spec/line_editor/basic_spec.rb +0 -28
  70. data/spec/line_editor/readline_spec.rb +0 -69
  71. data/spec/line_editor_spec.rb +0 -43
  72. data/spec/parser/argument_spec.rb +0 -53
  73. data/spec/parser/arguments_spec.rb +0 -66
  74. data/spec/parser/option_spec.rb +0 -210
  75. data/spec/parser/options_spec.rb +0 -414
  76. data/spec/quality_spec.rb +0 -75
  77. data/spec/rake_compat_spec.rb +0 -72
  78. data/spec/register_spec.rb +0 -227
  79. data/spec/runner_spec.rb +0 -246
  80. data/spec/sandbox/application.rb +0 -2
  81. data/spec/sandbox/app{1}/README +0 -3
  82. data/spec/sandbox/bundle/execute.rb +0 -6
  83. data/spec/sandbox/bundle/main.thor +0 -1
  84. data/spec/sandbox/command.thor +0 -10
  85. data/spec/sandbox/doc/%file_name%.rb.tt +0 -1
  86. data/spec/sandbox/doc/COMMENTER +0 -11
  87. data/spec/sandbox/doc/README +0 -3
  88. data/spec/sandbox/doc/block_helper.rb +0 -3
  89. data/spec/sandbox/doc/config.rb +0 -1
  90. data/spec/sandbox/doc/config.yaml.tt +0 -1
  91. data/spec/sandbox/doc/excluding/%file_name%.rb.tt +0 -1
  92. data/spec/sandbox/enum.thor +0 -10
  93. data/spec/sandbox/group.thor +0 -128
  94. data/spec/sandbox/invoke.thor +0 -131
  95. data/spec/sandbox/path with spaces b/data/spec/sandbox/path with → spaces +0 -0
  96. data/spec/sandbox/preserve/script.sh +0 -3
  97. data/spec/sandbox/script.thor +0 -220
  98. data/spec/sandbox/subcommand.thor +0 -17
  99. data/spec/shell/basic_spec.rb +0 -337
  100. data/spec/shell/color_spec.rb +0 -119
  101. data/spec/shell/html_spec.rb +0 -31
  102. data/spec/shell_spec.rb +0 -47
  103. data/spec/subcommand_spec.rb +0 -48
  104. data/spec/thor_spec.rb +0 -505
  105. data/spec/util_spec.rb +0 -196
@@ -1,31 +0,0 @@
1
- require "helper"
2
-
3
- describe Thor::Shell::HTML do
4
- def shell
5
- @shell ||= Thor::Shell::HTML.new
6
- end
7
-
8
- describe "#say" do
9
- it "sets the color if specified" do
10
- out = capture(:stdout) { shell.say "Wow! Now we have colors!", :green }
11
- expect(out.chomp).to eq('<span style="color: green;">Wow! Now we have colors!</span>')
12
- end
13
-
14
- it "sets bold if specified" do
15
- out = capture(:stdout) { shell.say "Wow! Now we have colors *and* bold!", [:green, :bold] }
16
- expect(out.chomp).to eq('<span style="color: green; font-weight: bold;">Wow! Now we have colors *and* bold!</span>')
17
- end
18
-
19
- it "does not use a new line even with colors" do
20
- out = capture(:stdout) { shell.say "Wow! Now we have colors! ", :green }
21
- expect(out.chomp).to eq('<span style="color: green;">Wow! Now we have colors! </span>')
22
- end
23
- end
24
-
25
- describe "#say_status" do
26
- it "uses color to say status" do
27
- expect($stdout).to receive(:print).with("<span style=\"color: red; font-weight: bold;\"> conflict</span> README\n")
28
- shell.say_status :conflict, "README", :red
29
- end
30
- end
31
- end
@@ -1,47 +0,0 @@
1
- require "helper"
2
-
3
- describe Thor::Shell do
4
- def shell
5
- @shell ||= Thor::Base.shell.new
6
- end
7
-
8
- describe "#initialize" do
9
- it "sets shell value" do
10
- base = MyCounter.new [1, 2], {}, :shell => shell
11
- expect(base.shell).to eq(shell)
12
- end
13
-
14
- it "sets the base value on the shell if an accessor is available" do
15
- base = MyCounter.new [1, 2], {}, :shell => shell
16
- expect(shell.base).to eq(base)
17
- end
18
- end
19
-
20
- describe "#shell" do
21
- it "returns the shell in use" do
22
- expect(MyCounter.new([1, 2]).shell).to be_kind_of(Thor::Base.shell)
23
- end
24
-
25
- it "uses $THOR_SHELL" do
26
- class Thor::Shell::TestShell < Thor::Shell::Basic; end
27
-
28
- expect(Thor::Base.shell).to eq(shell.class)
29
- ENV["THOR_SHELL"] = "TestShell"
30
- Thor::Base.shell = nil
31
- expect(Thor::Base.shell).to eq(Thor::Shell::TestShell)
32
- ENV["THOR_SHELL"] = ""
33
- Thor::Base.shell = shell.class
34
- expect(Thor::Base.shell).to eq(shell.class)
35
- end
36
- end
37
-
38
- describe "with_padding" do
39
- it "uses padding for inside block outputs" do
40
- base = MyCounter.new([1, 2])
41
- base.with_padding do
42
- expect(capture(:stdout) { base.say_status :padding, "cool" }.strip).to eq("padding cool")
43
- end
44
- end
45
- end
46
-
47
- end
@@ -1,48 +0,0 @@
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
-
29
- it "accepts the help switch and calls the help command on the subcommand" do
30
- output = capture(:stdout) { TestSubcommands::Parent.start(%w[sub print_opt --help]) }
31
- sub_help = capture(:stdout) { TestSubcommands::Parent.start(%w[sub help print_opt]) }
32
- expect(output).to eq(sub_help)
33
- end
34
-
35
- it "accepts the help short switch and calls the help command on the subcommand" do
36
- output = capture(:stdout) { TestSubcommands::Parent.start(%w[sub print_opt -h]) }
37
- sub_help = capture(:stdout) { TestSubcommands::Parent.start(%w[sub help print_opt]) }
38
- expect(output).to eq(sub_help)
39
- end
40
-
41
- it "the help command on the subcommand and after it should result in the same output" do
42
- output = capture(:stdout) { TestSubcommands::Parent.start(%w[sub help])}
43
- sub_help = capture(:stdout) { TestSubcommands::Parent.start(%w[help sub])}
44
- expect(output).to eq(sub_help)
45
- end
46
- end
47
-
48
- end
@@ -1,505 +0,0 @@
1
- require "helper"
2
-
3
- describe Thor do
4
- describe "#method_option" do
5
- it "sets options to the next method to be invoked" do
6
- args = %w[foo bar --force]
7
- _, options = MyScript.start(args)
8
- expect(options).to eq("force" => true)
9
- end
10
-
11
- describe ":lazy_default" do
12
- it "is absent when option is not specified" do
13
- _, options = MyScript.start(%w[with_optional])
14
- expect(options).to eq({})
15
- end
16
-
17
- it "sets a default that can be overridden for strings" do
18
- _, options = MyScript.start(%w[with_optional --lazy])
19
- expect(options).to eq("lazy" => "yes")
20
-
21
- _, options = MyScript.start(%w[with_optional --lazy yesyes!])
22
- expect(options).to eq("lazy" => "yesyes!")
23
- end
24
-
25
- it "sets a default that can be overridden for numerics" do
26
- _, options = MyScript.start(%w[with_optional --lazy-numeric])
27
- expect(options).to eq("lazy_numeric" => 42)
28
-
29
- _, options = MyScript.start(%w[with_optional --lazy-numeric 20000])
30
- expect(options).to eq("lazy_numeric" => 20_000)
31
- end
32
-
33
- it "sets a default that can be overridden for arrays" do
34
- _, options = MyScript.start(%w[with_optional --lazy-array])
35
- expect(options).to eq("lazy_array" => %w[eat at joes])
36
-
37
- _, options = MyScript.start(%w[with_optional --lazy-array hello there])
38
- expect(options).to eq("lazy_array" => %w[hello there])
39
- end
40
-
41
- it "sets a default that can be overridden for hashes" do
42
- _, options = MyScript.start(%w[with_optional --lazy-hash])
43
- expect(options).to eq("lazy_hash" => {"swedish" => "meatballs"})
44
-
45
- _, options = MyScript.start(%w[with_optional --lazy-hash polish:sausage])
46
- expect(options).to eq("lazy_hash" => {"polish" => "sausage"})
47
- end
48
- end
49
-
50
- describe "when :for is supplied" do
51
- it "updates an already defined command" do
52
- _, options = MyChildScript.start(%w[animal horse --other=fish])
53
- expect(options[:other]).to eq("fish")
54
- end
55
-
56
- describe "and the target is on the parent class" do
57
- it "updates an already defined command" do
58
- args = %w[example_default_command my_param --new-option=verified]
59
- options = Scripts::MyScript.start(args)
60
- expect(options[:new_option]).to eq("verified")
61
- end
62
-
63
- it "adds a command to the command list if the updated command is on the parent class" do
64
- expect(Scripts::MyScript.commands["example_default_command"]).to be
65
- end
66
-
67
- it "clones the parent command" do
68
- expect(Scripts::MyScript.commands["example_default_command"]).not_to eq(MyChildScript.commands["example_default_command"])
69
- end
70
- end
71
- end
72
- end
73
-
74
- describe "#default_command" do
75
- it "sets a default command" do
76
- expect(MyScript.default_command).to eq("example_default_command")
77
- end
78
-
79
- it "invokes the default command if no command is specified" do
80
- expect(MyScript.start([])).to eq("default command")
81
- end
82
-
83
- it "invokes the default command if no command is specified even if switches are given" do
84
- expect(MyScript.start(%w[--with option])).to eq("with" => "option")
85
- end
86
-
87
- it "inherits the default command from parent" do
88
- expect(MyChildScript.default_command).to eq("example_default_command")
89
- end
90
- end
91
-
92
- describe "#stop_on_unknown_option!" do
93
- my_script = Class.new(Thor) do
94
- class_option "verbose", :type => :boolean
95
- class_option "mode", :type => :string
96
-
97
- stop_on_unknown_option! :exec
98
-
99
- desc "exec", "Run a command"
100
- def exec(*args)
101
- [options, args]
102
- end
103
-
104
- desc "boring", "An ordinary command"
105
- def boring(*args)
106
- [options, args]
107
- end
108
- end
109
-
110
- it "passes remaining args to command when it encounters a non-option" do
111
- expect(my_script.start(%w[exec command --verbose])).to eq [{}, %w[command --verbose]]
112
- end
113
-
114
- it "passes remaining args to command when it encounters an unknown option" do
115
- expect(my_script.start(%w[exec --foo command --bar])).to eq [{}, %w[--foo command --bar]]
116
- end
117
-
118
- it "still accepts options that are given before non-options" do
119
- expect(my_script.start(%w[exec --verbose command --foo])).to eq [{"verbose" => true}, %w[command --foo]]
120
- end
121
-
122
- it "still accepts options that require a value" do
123
- expect(my_script.start(%w[exec --mode rashly command])).to eq [{"mode" => "rashly"}, %w[command]]
124
- end
125
-
126
- it "still passes everything after -- to command" do
127
- expect(my_script.start(%w[exec -- --verbose])).to eq [{}, %w[--verbose]]
128
- end
129
-
130
- it "does not affect ordinary commands" do
131
- expect(my_script.start(%w[boring command --verbose])).to eq [{"verbose" => true}, %w[command]]
132
- end
133
-
134
- context "when provided with multiple command names" do
135
- klass = Class.new(Thor) do
136
- stop_on_unknown_option! :foo, :bar
137
- end
138
- it "affects all specified commands" do
139
- expect(klass.stop_on_unknown_option?(double(:name => "foo"))).to be true
140
- expect(klass.stop_on_unknown_option?(double(:name => "bar"))).to be true
141
- expect(klass.stop_on_unknown_option?(double(:name => "baz"))).to be false
142
- end
143
- end
144
-
145
- context "when invoked several times" do
146
- klass = Class.new(Thor) do
147
- stop_on_unknown_option! :foo
148
- stop_on_unknown_option! :bar
149
- end
150
- it "affects all specified commands" do
151
- expect(klass.stop_on_unknown_option?(double(:name => "foo"))).to be true
152
- expect(klass.stop_on_unknown_option?(double(:name => "bar"))).to be true
153
- expect(klass.stop_on_unknown_option?(double(:name => "baz"))).to be false
154
- end
155
- end
156
-
157
- it "doesn't break new" do
158
- expect(my_script.new).to be_a(Thor)
159
- end
160
- end
161
-
162
- describe "#map" do
163
- it "calls the alias of a method if one is provided" do
164
- expect(MyScript.start(%w[-T fish])).to eq(%w[fish])
165
- end
166
-
167
- it "calls the alias of a method if several are provided via #map" do
168
- expect(MyScript.start(%w[-f fish])).to eq(["fish", {}])
169
- expect(MyScript.start(%w[--foo fish])).to eq(["fish", {}])
170
- end
171
-
172
- it "inherits all mappings from parent" do
173
- expect(MyChildScript.default_command).to eq("example_default_command")
174
- end
175
- end
176
-
177
- describe "#package_name" do
178
- it "provides a proper description for a command when the package_name is assigned" do
179
- content = capture(:stdout) { PackageNameScript.start(%w[help]) }
180
- expect(content).to match(/Baboon commands:/m)
181
- end
182
-
183
- # TODO: remove this, might be redundant, just wanted to prove full coverage
184
- it "provides a proper description for a command when the package_name is NOT assigned" do
185
- content = capture(:stdout) { MyScript.start(%w[help]) }
186
- expect(content).to match(/Commands:/m)
187
- end
188
- end
189
-
190
- describe "#desc" do
191
- it "provides description for a command" do
192
- content = capture(:stdout) { MyScript.start(%w[help]) }
193
- expect(content).to match(/thor my_script:zoo\s+# zoo around/m)
194
- end
195
-
196
- it "provides no namespace if $thor_runner is false" do
197
- begin
198
- $thor_runner = false
199
- content = capture(:stdout) { MyScript.start(%w[help]) }
200
- expect(content).to match(/thor zoo\s+# zoo around/m)
201
- ensure
202
- $thor_runner = true
203
- end
204
- end
205
-
206
- describe "when :for is supplied" do
207
- it "overwrites a previous defined command" do
208
- expect(capture(:stdout) { MyChildScript.start(%w[help]) }).to match(/animal KIND \s+# fish around/m)
209
- end
210
- end
211
-
212
- describe "when :hide is supplied" do
213
- it "does not show the command in help" do
214
- expect(capture(:stdout) { MyScript.start(%w[help]) }).not_to match(/this is hidden/m)
215
- end
216
-
217
- it "but the command is still invokable, does not show the command in help" do
218
- expect(MyScript.start(%w[hidden yesyes])).to eq(%w[yesyes])
219
- end
220
- end
221
- end
222
-
223
- describe "#method_options" do
224
- it "sets default options if called before an initializer" do
225
- options = MyChildScript.class_options
226
- expect(options[:force].type).to eq(:boolean)
227
- expect(options[:param].type).to eq(:numeric)
228
- end
229
-
230
- it "overwrites default options if called on the method scope" do
231
- args = %w[zoo --force --param feathers]
232
- options = MyChildScript.start(args)
233
- expect(options).to eq("force" => true, "param" => "feathers")
234
- end
235
-
236
- it "allows default options to be merged with method options" do
237
- args = %w[animal bird --force --param 1.0 --other tweets]
238
- arg, options = MyChildScript.start(args)
239
- expect(arg).to eq("bird")
240
- expect(options).to eq("force" => true, "param" => 1.0, "other" => "tweets")
241
- end
242
- end
243
-
244
- describe "#start" do
245
- it "calls a no-param method when no params are passed" do
246
- expect(MyScript.start(%w[zoo])).to eq(true)
247
- end
248
-
249
- it "calls a single-param method when a single param is passed" do
250
- expect(MyScript.start(%w[animal fish])).to eq(%w[fish])
251
- end
252
-
253
- it "does not set options in attributes" do
254
- expect(MyScript.start(%w[with_optional --all])).to eq([nil, {"all" => true}, []])
255
- end
256
-
257
- it "raises an error if the wrong number of params are provided" do
258
- arity_asserter = lambda do |args, msg|
259
- stderr = capture(:stderr) { Scripts::Arities.start(args) }
260
- expect(stderr.strip).to eq(msg)
261
- end
262
- arity_asserter.call %w[zero_args one], %Q(ERROR: "thor zero_args" was called with arguments ["one"]
263
- Usage: "thor scripts:arities:zero_args")
264
- arity_asserter.call %w[one_arg], %Q(ERROR: "thor one_arg" was called with no arguments
265
- Usage: "thor scripts:arities:one_arg ARG")
266
- arity_asserter.call %w[one_arg one two], %Q(ERROR: "thor one_arg" was called with arguments ["one", "two"]
267
- Usage: "thor scripts:arities:one_arg ARG")
268
- arity_asserter.call %w[one_arg one two], %Q(ERROR: "thor one_arg" was called with arguments ["one", "two"]
269
- Usage: "thor scripts:arities:one_arg ARG")
270
- arity_asserter.call %w[two_args one], %Q(ERROR: "thor two_args" was called with arguments ["one"]
271
- Usage: "thor scripts:arities:two_args ARG1 ARG2")
272
- arity_asserter.call %w[optional_arg one two], %Q(ERROR: "thor optional_arg" was called with arguments ["one", "two"]
273
- Usage: "thor scripts:arities:optional_arg [ARG]")
274
- end
275
-
276
- it "raises an error if the invoked command does not exist" do
277
- expect(capture(:stderr) { Amazing.start(%w[animal]) }.strip).to eq('Could not find command "animal" in "amazing" namespace.')
278
- end
279
-
280
- it "calls method_missing if an unknown method is passed in" do
281
- expect(MyScript.start(%w[unk hello])).to eq([:unk, %w[hello]])
282
- end
283
-
284
- it "does not call a private method no matter what" do
285
- expect(capture(:stderr) { MyScript.start(%w[what]) }.strip).to eq('Could not find command "what" in "my_script" namespace.')
286
- end
287
-
288
- it "uses command default options" do
289
- options = MyChildScript.start(%w[animal fish]).last
290
- expect(options).to eq("other" => "method default")
291
- end
292
-
293
- it "raises when an exception happens within the command call" do
294
- expect { MyScript.start(%w[call_myself_with_wrong_arity]) }.to raise_error(ArgumentError)
295
- end
296
-
297
- context "when the user enters an unambiguous substring of a command" do
298
- it "invokes a command" do
299
- expect(MyScript.start(%w[z])).to eq(MyScript.start(%w[zoo]))
300
- end
301
-
302
- it "invokes a command, even when there's an alias it resolves to the same command" do
303
- expect(MyScript.start(%w[hi arg])).to eq(MyScript.start(%w[hidden arg]))
304
- end
305
-
306
- it "invokes an alias" do
307
- expect(MyScript.start(%w[animal_pri])).to eq(MyScript.start(%w[zoo]))
308
- end
309
- end
310
-
311
- context "when the user enters an ambiguous substring of a command" do
312
- it "raises an exception and displays a message that explains the ambiguity" do
313
- shell = Thor::Base.shell.new
314
- expect(shell).to receive(:error).with("Ambiguous command call matches [call_myself_with_wrong_arity, call_unexistent_method]")
315
- MyScript.start(%w[call], :shell => shell)
316
- end
317
-
318
- it "raises an exception when there is an alias" do
319
- shell = Thor::Base.shell.new
320
- expect(shell).to receive(:error).with("Ambiguous command f matches [foo, fu]")
321
- MyScript.start(%w[f], :shell => shell)
322
- end
323
- end
324
-
325
- end
326
-
327
- describe "#help" do
328
- def shell
329
- @shell ||= Thor::Base.shell.new
330
- end
331
-
332
- describe "on general" do
333
- before do
334
- @content = capture(:stdout) { MyScript.help(shell) }
335
- end
336
-
337
- it "provides useful help info for the help method itself" do
338
- expect(@content).to match(/help \[COMMAND\]\s+# Describe available commands/)
339
- end
340
-
341
- it "provides useful help info for a method with params" do
342
- expect(@content).to match(/animal TYPE\s+# horse around/)
343
- end
344
-
345
- it "uses the maximum terminal size to show commands" do
346
- expect(@shell).to receive(:terminal_width).and_return(80)
347
- content = capture(:stdout) { MyScript.help(shell) }
348
- expect(content).to match(/aaa\.\.\.$/)
349
- end
350
-
351
- it "provides description for commands from classes in the same namespace" do
352
- expect(@content).to match(/baz\s+# do some bazing/)
353
- end
354
-
355
- it "shows superclass commands" do
356
- content = capture(:stdout) { MyChildScript.help(shell) }
357
- expect(content).to match(/foo BAR \s+# do some fooing/)
358
- end
359
-
360
- it "shows class options information" do
361
- content = capture(:stdout) { MyChildScript.help(shell) }
362
- expect(content).to match(/Options\:/)
363
- expect(content).to match(/\[\-\-param=N\]/)
364
- end
365
-
366
- it "injects class arguments into default usage" do
367
- content = capture(:stdout) { Scripts::MyScript.help(shell) }
368
- expect(content).to match(/zoo ACCESSOR \-\-param\=PARAM/)
369
- end
370
- end
371
-
372
- describe "for a specific command" do
373
- it "provides full help info when talking about a specific command" do
374
- expect(capture(:stdout) { MyScript.command_help(shell, "foo") }).to eq(<<-END)
375
- Usage:
376
- thor my_script:foo BAR
377
-
378
- Options:
379
- [--force] # Force to do some fooing
380
-
381
- do some fooing
382
- This is more info!
383
- Everyone likes more info!
384
- END
385
- end
386
-
387
- it "raises an error if the command can't be found" do
388
- expect do
389
- MyScript.command_help(shell, "unknown")
390
- end.to raise_error(Thor::UndefinedCommandError, 'Could not find command "unknown" in "my_script" namespace.')
391
- end
392
-
393
- it "normalizes names before claiming they don't exist" do
394
- expect(capture(:stdout) { MyScript.command_help(shell, "name-with-dashes") }).to match(/thor my_script:name-with-dashes/)
395
- end
396
-
397
- it "uses the long description if it exists" do
398
- expect(capture(:stdout) { MyScript.command_help(shell, "long_description") }).to eq(<<-HELP)
399
- Usage:
400
- thor my_script:long_description
401
-
402
- Description:
403
- This is a really really really long description. Here you go. So very long.
404
-
405
- It even has two paragraphs.
406
- HELP
407
- end
408
-
409
- it "doesn't assign the long description to the next command without one" do
410
- expect(capture(:stdout) do
411
- MyScript.command_help(shell, "name_with_dashes")
412
- end).not_to match(/so very long/i)
413
- end
414
- end
415
-
416
- describe "instance method" do
417
- it "calls the class method" do
418
- expect(capture(:stdout) { MyScript.start(%w[help]) }).to match(/Commands:/)
419
- end
420
-
421
- it "calls the class method" do
422
- expect(capture(:stdout) { MyScript.start(%w[help foo]) }).to match(/Usage:/)
423
- end
424
- end
425
- end
426
-
427
- describe "when creating commands" do
428
- it "prints a warning if a public method is created without description or usage" do
429
- expect(capture(:stdout) do
430
- klass = Class.new(Thor)
431
- klass.class_eval "def hello_from_thor; end"
432
- end).to match(/\[WARNING\] Attempted to create command "hello_from_thor" without usage or description/)
433
- end
434
-
435
- it "does not print if overwriting a previous command" do
436
- expect(capture(:stdout) do
437
- klass = Class.new(Thor)
438
- klass.class_eval "def help; end"
439
- end).to be_empty
440
- end
441
- end
442
-
443
- describe "edge-cases" do
444
- it "can handle boolean options followed by arguments" do
445
- klass = Class.new(Thor) do
446
- method_option :loud, :type => :boolean
447
- desc "hi NAME", "say hi to name"
448
- def hi(name)
449
- name.upcase! if options[:loud]
450
- "Hi #{name}"
451
- end
452
- end
453
-
454
- expect(klass.start(%w[hi jose])).to eq("Hi jose")
455
- expect(klass.start(%w[hi jose --loud])).to eq("Hi JOSE")
456
- expect(klass.start(%w[hi --loud jose])).to eq("Hi JOSE")
457
- end
458
-
459
- it "passes through unknown options" do
460
- klass = Class.new(Thor) do
461
- desc "unknown", "passing unknown options"
462
- def unknown(*args)
463
- args
464
- end
465
- end
466
-
467
- expect(klass.start(%w[unknown foo --bar baz bat --bam])).to eq(%w[foo --bar baz bat --bam])
468
- expect(klass.start(%w[unknown --bar baz])).to eq(%w[--bar baz])
469
- end
470
-
471
- it "does not pass through unknown options with strict args" do
472
- klass = Class.new(Thor) do
473
- strict_args_position!
474
-
475
- desc "unknown", "passing unknown options"
476
- def unknown(*args)
477
- args
478
- end
479
- end
480
-
481
- expect(klass.start(%w[unknown --bar baz])).to eq([])
482
- expect(klass.start(%w[unknown foo --bar baz])).to eq(%w[foo])
483
- end
484
-
485
- it "strict args works in the inheritance chain" do
486
- parent = Class.new(Thor) do
487
- strict_args_position!
488
- end
489
-
490
- klass = Class.new(parent) do
491
- desc "unknown", "passing unknown options"
492
- def unknown(*args)
493
- args
494
- end
495
- end
496
-
497
- expect(klass.start(%w[unknown --bar baz])).to eq([])
498
- expect(klass.start(%w[unknown foo --bar baz])).to eq(%w[foo])
499
- end
500
-
501
- it "send as a command name" do
502
- expect(MyScript.start(%w[send])).to eq(true)
503
- end
504
- end
505
- end