wijet-thor 0.14.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. data/CHANGELOG.rdoc +103 -0
  2. data/LICENSE +20 -0
  3. data/README.md +307 -0
  4. data/Thorfile +24 -0
  5. data/bin/rake2thor +86 -0
  6. data/bin/thor +6 -0
  7. data/lib/thor.rb +334 -0
  8. data/lib/thor/actions.rb +314 -0
  9. data/lib/thor/actions/create_file.rb +105 -0
  10. data/lib/thor/actions/create_link.rb +57 -0
  11. data/lib/thor/actions/directory.rb +93 -0
  12. data/lib/thor/actions/empty_directory.rb +134 -0
  13. data/lib/thor/actions/file_manipulation.rb +270 -0
  14. data/lib/thor/actions/inject_into_file.rb +109 -0
  15. data/lib/thor/base.rb +579 -0
  16. data/lib/thor/core_ext/file_binary_read.rb +9 -0
  17. data/lib/thor/core_ext/hash_with_indifferent_access.rb +75 -0
  18. data/lib/thor/core_ext/ordered_hash.rb +100 -0
  19. data/lib/thor/error.rb +30 -0
  20. data/lib/thor/group.rb +273 -0
  21. data/lib/thor/invocation.rb +168 -0
  22. data/lib/thor/parser.rb +4 -0
  23. data/lib/thor/parser/argument.rb +67 -0
  24. data/lib/thor/parser/arguments.rb +161 -0
  25. data/lib/thor/parser/option.rb +120 -0
  26. data/lib/thor/parser/options.rb +173 -0
  27. data/lib/thor/rake_compat.rb +66 -0
  28. data/lib/thor/runner.rb +309 -0
  29. data/lib/thor/shell.rb +88 -0
  30. data/lib/thor/shell/basic.rb +290 -0
  31. data/lib/thor/shell/color.rb +108 -0
  32. data/lib/thor/shell/html.rb +121 -0
  33. data/lib/thor/task.rb +114 -0
  34. data/lib/thor/util.rb +229 -0
  35. data/lib/thor/version.rb +3 -0
  36. data/spec/actions/create_file_spec.rb +170 -0
  37. data/spec/actions/directory_spec.rb +136 -0
  38. data/spec/actions/empty_directory_spec.rb +98 -0
  39. data/spec/actions/file_manipulation_spec.rb +310 -0
  40. data/spec/actions/inject_into_file_spec.rb +135 -0
  41. data/spec/actions_spec.rb +322 -0
  42. data/spec/base_spec.rb +269 -0
  43. data/spec/core_ext/hash_with_indifferent_access_spec.rb +43 -0
  44. data/spec/core_ext/ordered_hash_spec.rb +115 -0
  45. data/spec/fixtures/application.rb +2 -0
  46. data/spec/fixtures/bundle/execute.rb +6 -0
  47. data/spec/fixtures/bundle/main.thor +1 -0
  48. data/spec/fixtures/doc/%file_name%.rb.tt +1 -0
  49. data/spec/fixtures/doc/README +3 -0
  50. data/spec/fixtures/doc/block_helper.rb +3 -0
  51. data/spec/fixtures/doc/components/.empty_directory +0 -0
  52. data/spec/fixtures/doc/config.rb +1 -0
  53. data/spec/fixtures/group.thor +114 -0
  54. data/spec/fixtures/invoke.thor +112 -0
  55. data/spec/fixtures/path with spaces b/data/spec/fixtures/path with → spaces +0 -0
  56. data/spec/fixtures/script.thor +184 -0
  57. data/spec/fixtures/task.thor +10 -0
  58. data/spec/group_spec.rb +178 -0
  59. data/spec/invocation_spec.rb +100 -0
  60. data/spec/parser/argument_spec.rb +47 -0
  61. data/spec/parser/arguments_spec.rb +64 -0
  62. data/spec/parser/option_spec.rb +202 -0
  63. data/spec/parser/options_spec.rb +319 -0
  64. data/spec/rake_compat_spec.rb +68 -0
  65. data/spec/register_spec.rb +104 -0
  66. data/spec/runner_spec.rb +210 -0
  67. data/spec/shell/basic_spec.rb +223 -0
  68. data/spec/shell/color_spec.rb +41 -0
  69. data/spec/shell/html_spec.rb +27 -0
  70. data/spec/shell_spec.rb +47 -0
  71. data/spec/spec_helper.rb +54 -0
  72. data/spec/task_spec.rb +74 -0
  73. data/spec/thor_spec.rb +334 -0
  74. data/spec/util_spec.rb +163 -0
  75. metadata +193 -0
@@ -0,0 +1,41 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Thor::Shell::Color do
4
+ def shell
5
+ @shell ||= Thor::Shell::Color.new
6
+ end
7
+
8
+ describe "#say" do
9
+ it "set the color if specified" do
10
+ $stdout.should_receive(:puts).with("\e[32mWow! Now we have colors!\e[0m")
11
+ shell.say "Wow! Now we have colors!", :green
12
+ end
13
+
14
+ it "does not use a new line even with colors" do
15
+ $stdout.should_receive(:print).with("\e[32mWow! Now we have colors! \e[0m")
16
+ shell.say "Wow! Now we have colors! ", :green
17
+ end
18
+ end
19
+
20
+ describe "#say_status" do
21
+ it "uses color to say status" do
22
+ $stdout.should_receive(:puts).with("\e[1m\e[31m conflict\e[0m README")
23
+ shell.say_status :conflict, "README", :red
24
+ end
25
+ end
26
+
27
+ describe "#file_collision" do
28
+ describe "when a block is given" do
29
+ it "invokes the diff command" do
30
+ $stdout.stub!(:print)
31
+ $stdin.should_receive(:gets).and_return('d')
32
+ $stdin.should_receive(:gets).and_return('n')
33
+
34
+ output = capture(:stdout){ shell.file_collision('spec/fixtures/doc/README'){ "README\nEND\n" } }
35
+ output.should =~ /\e\[31m\- __start__\e\[0m/
36
+ output.should =~ /^ README/
37
+ output.should =~ /\e\[32m\+ END\e\[0m/
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,27 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_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 "set the color if specified" do
10
+ $stdout.should_receive(:puts).with('<span style="color: green;">Wow! Now we have colors!</span>')
11
+ shell.say "Wow! Now we have colors!", :green
12
+ end
13
+
14
+ it "does not use a new line even with colors" do
15
+ $stdout.should_receive(:print).with('<span style="color: green;">Wow! Now we have colors! </span>')
16
+ shell.say "Wow! Now we have colors! ", :green
17
+ end
18
+ end
19
+
20
+ describe "#say_status" do
21
+ it "uses color to say status" do
22
+ $stdout.should_receive(:puts).with('<strong><span style="color: red;"> conflict</span></strong> README')
23
+ shell.say_status :conflict, "README", :red
24
+ end
25
+ end
26
+
27
+ end
@@ -0,0 +1,47 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_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
+ base.shell.should == 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
+ shell.base.should == base
17
+ end
18
+ end
19
+
20
+ describe "#shell" do
21
+ it "returns the shell in use" do
22
+ MyCounter.new([1,2]).shell.should 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
+ Thor::Base.shell.should == shell.class
29
+ ENV['THOR_SHELL'] = 'TestShell'
30
+ Thor::Base.shell = nil
31
+ Thor::Base.shell.should == Thor::Shell::TestShell
32
+ ENV['THOR_SHELL'] = ''
33
+ Thor::Base.shell = shell.class
34
+ Thor::Base.shell.should == 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
+ capture(:stdout){ base.say_status :padding, "cool" }.strip.should == "padding cool"
43
+ end
44
+ end
45
+ end
46
+
47
+ end
@@ -0,0 +1,54 @@
1
+ $TESTING=true
2
+
3
+ require 'simplecov'
4
+ SimpleCov.start do
5
+ add_group 'Libraries', 'lib'
6
+ add_group 'Specs', 'spec'
7
+ end
8
+
9
+ $:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
10
+ require 'thor'
11
+ require 'thor/group'
12
+ require 'stringio'
13
+
14
+ require 'rdoc'
15
+ require 'rspec'
16
+ require 'diff/lcs' # You need diff/lcs installed to run specs (but not to run Thor).
17
+ require 'fakeweb' # You need fakeweb installed to run specs (but not to run Thor).
18
+
19
+ # Set shell to basic
20
+ $0 = "thor"
21
+ $thor_runner = true
22
+ ARGV.clear
23
+ Thor::Base.shell = Thor::Shell::Basic
24
+
25
+ # Load fixtures
26
+ load File.join(File.dirname(__FILE__), "fixtures", "task.thor")
27
+ load File.join(File.dirname(__FILE__), "fixtures", "group.thor")
28
+ load File.join(File.dirname(__FILE__), "fixtures", "script.thor")
29
+ load File.join(File.dirname(__FILE__), "fixtures", "invoke.thor")
30
+
31
+ RSpec.configure do |config|
32
+ def capture(stream)
33
+ begin
34
+ stream = stream.to_s
35
+ eval "$#{stream} = StringIO.new"
36
+ yield
37
+ result = eval("$#{stream}").string
38
+ ensure
39
+ eval("$#{stream} = #{stream.upcase}")
40
+ end
41
+
42
+ result
43
+ end
44
+
45
+ def source_root
46
+ File.join(File.dirname(__FILE__), 'fixtures')
47
+ end
48
+
49
+ def destination_root
50
+ File.join(File.dirname(__FILE__), 'sandbox')
51
+ end
52
+
53
+ alias :silence :capture
54
+ end
@@ -0,0 +1,74 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Thor::Task do
4
+ def task(options={})
5
+ options.each do |key, value|
6
+ options[key] = Thor::Option.parse(key, value)
7
+ end
8
+
9
+ @task ||= Thor::Task.new(:can_has, "I can has cheezburger", "I can has cheezburger\nLots and lots of it", "can_has", options)
10
+ end
11
+
12
+ describe "#formatted_usage" do
13
+ it "includes namespace within usage" do
14
+ Object.stub!(:namespace).and_return("foo")
15
+ Object.stub!(:arguments).and_return([])
16
+ task(:bar => :required).formatted_usage(Object).should == "foo:can_has --bar=BAR"
17
+ end
18
+
19
+ it "includes subcommand name within subcommand usage" do
20
+ object = Struct.new(:namespace, :arguments).new("main:foo", [])
21
+ task(:bar => :required).formatted_usage(object, false, true).should == "foo can_has --bar=BAR"
22
+ end
23
+
24
+ it "removes default from namespace" do
25
+ Object.stub!(:namespace).and_return("default:foo")
26
+ Object.stub!(:arguments).and_return([])
27
+ task(:bar => :required).formatted_usage(Object).should == ":foo:can_has --bar=BAR"
28
+ end
29
+
30
+ it "injects arguments into usage" do
31
+ Object.stub!(:namespace).and_return("foo")
32
+ Object.stub!(:arguments).and_return([ Thor::Argument.new(:bar, nil, true, :string) ])
33
+ task(:foo => :required).formatted_usage(Object).should == "foo:can_has BAR --foo=FOO"
34
+ end
35
+ end
36
+
37
+ describe "#dynamic" do
38
+ it "creates a dynamic task with the given name" do
39
+ Thor::DynamicTask.new('task').name.should == 'task'
40
+ Thor::DynamicTask.new('task').description.should == 'A dynamically-generated task'
41
+ Thor::DynamicTask.new('task').usage.should == 'task'
42
+ Thor::DynamicTask.new('task').options.should == {}
43
+ end
44
+
45
+ it "does not invoke an existing method" do
46
+ mock = mock()
47
+ mock.class.should_receive(:handle_no_task_error).with("to_s")
48
+ Thor::DynamicTask.new('to_s').run(mock)
49
+ end
50
+ end
51
+
52
+ describe "#dup" do
53
+ it "dup options hash" do
54
+ task = Thor::Task.new("can_has", nil, nil, nil, :foo => true, :bar => :required)
55
+ task.dup.options.delete(:foo)
56
+ task.options[:foo].should_not be_nil
57
+ end
58
+ end
59
+
60
+ describe "#run" do
61
+ it "runs a task by calling a method in the given instance" do
62
+ mock = mock()
63
+ mock.should_receive(:send).with("can_has", 1, 2, 3)
64
+ task.run(mock, [1, 2, 3])
65
+ end
66
+
67
+ it "raises an error if the method to be invoked is private" do
68
+ mock = mock()
69
+ mock.should_receive(:private_methods).and_return(['can_has'])
70
+ mock.class.should_receive(:handle_no_task_error).with("can_has")
71
+ task.run(mock)
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,334 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_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 = ["foo", "bar", "--force"]
7
+ arg, options = MyScript.start(args)
8
+ options.should == { "force" => true }
9
+ end
10
+
11
+ describe ":lazy_default" do
12
+ it "is absent when option is not specified" do
13
+ arg, options = MyScript.start(["with_optional"])
14
+ options.should == {}
15
+ end
16
+
17
+ it "sets a default that can be overridden for strings" do
18
+ arg, options = MyScript.start(["with_optional", "--lazy"])
19
+ options.should == { "lazy" => "yes" }
20
+
21
+ arg, options = MyScript.start(["with_optional", "--lazy", "yesyes!"])
22
+ options.should == { "lazy" => "yesyes!" }
23
+ end
24
+
25
+ it "sets a default that can be overridden for numerics" do
26
+ arg, options = MyScript.start(["with_optional", "--lazy-numeric"])
27
+ options.should == { "lazy_numeric" => 42 }
28
+
29
+ arg, options = MyScript.start(["with_optional", "--lazy-numeric", 20000])
30
+ options.should == { "lazy_numeric" => 20000 }
31
+ end
32
+
33
+ it "sets a default that can be overridden for arrays" do
34
+ arg, options = MyScript.start(["with_optional", "--lazy-array"])
35
+ options.should == { "lazy_array" => %w[eat at joes] }
36
+
37
+ arg, options = MyScript.start(["with_optional", "--lazy-array", "hello", "there"])
38
+ options.should == { "lazy_array" => %w[hello there] }
39
+ end
40
+
41
+ it "sets a default that can be overridden for hashes" do
42
+ arg, options = MyScript.start(["with_optional", "--lazy-hash"])
43
+ options.should == { "lazy_hash" => {'swedish' => 'meatballs'} }
44
+
45
+ arg, options = MyScript.start(["with_optional", "--lazy-hash", "polish:sausage"])
46
+ options.should == { "lazy_hash" => {'polish' => 'sausage'} }
47
+ end
48
+ end
49
+
50
+ describe "when :for is supplied" do
51
+ it "updates an already defined task" do
52
+ args, options = MyChildScript.start(["animal", "horse", "--other=fish"])
53
+ options[:other].should == "fish"
54
+ end
55
+
56
+ describe "and the target is on the parent class" do
57
+ it "updates an already defined task" do
58
+ args = ["example_default_task", "my_param", "--new-option=verified"]
59
+ options = Scripts::MyScript.start(args)
60
+ options[:new_option].should == "verified"
61
+ end
62
+
63
+ it "adds a task to the tasks list if the updated task is on the parent class" do
64
+ Scripts::MyScript.tasks["example_default_task"].should_not be_nil
65
+ end
66
+
67
+ it "clones the parent task" do
68
+ Scripts::MyScript.tasks["example_default_task"].should_not == MyChildScript.tasks["example_default_task"]
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ describe "#default_task" do
75
+ it "sets a default task" do
76
+ MyScript.default_task.should == "example_default_task"
77
+ end
78
+
79
+ it "invokes the default task if no command is specified" do
80
+ MyScript.start([]).should == "default task"
81
+ end
82
+
83
+ it "invokes the default task if no command is specified even if switches are given" do
84
+ MyScript.start(["--with", "option"]).should == {"with"=>"option"}
85
+ end
86
+
87
+ it "inherits the default task from parent" do
88
+ MyChildScript.default_task.should == "example_default_task"
89
+ end
90
+ end
91
+
92
+ describe "#map" do
93
+ it "calls the alias of a method if one is provided" do
94
+ MyScript.start(["-T", "fish"]).should == ["fish"]
95
+ end
96
+
97
+ it "calls the alias of a method if several are provided via .map" do
98
+ MyScript.start(["-f", "fish"]).should == ["fish", {}]
99
+ MyScript.start(["--foo", "fish"]).should == ["fish", {}]
100
+ end
101
+
102
+ it "inherits all mappings from parent" do
103
+ MyChildScript.default_task.should == "example_default_task"
104
+ end
105
+ end
106
+
107
+ describe "#desc" do
108
+ it "provides description for a task" do
109
+ content = capture(:stdout) { MyScript.start(["help"]) }
110
+ content.should =~ /thor my_script:zoo\s+# zoo around/m
111
+ end
112
+
113
+ it "provides no namespace if $thor_runner is false" do
114
+ begin
115
+ $thor_runner = false
116
+ content = capture(:stdout) { MyScript.start(["help"]) }
117
+ content.should =~ /thor zoo\s+# zoo around/m
118
+ ensure
119
+ $thor_runner = true
120
+ end
121
+ end
122
+
123
+ describe "when :for is supplied" do
124
+ it "overwrites a previous defined task" do
125
+ capture(:stdout) { MyChildScript.start(["help"]) }.should =~ /animal KIND \s+# fish around/m
126
+ end
127
+ end
128
+
129
+ describe "when :hide is supplied" do
130
+ it "does not show the task in help" do
131
+ capture(:stdout) { MyScript.start(["help"]) }.should_not =~ /this is hidden/m
132
+ end
133
+
134
+ it "but the task is still invokcable not show the task in help" do
135
+ MyScript.start(["hidden", "yesyes"]).should == ["yesyes"]
136
+ end
137
+ end
138
+ end
139
+
140
+ describe "#method_options" do
141
+ it "sets default options if called before an initializer" do
142
+ options = MyChildScript.class_options
143
+ options[:force].type.should == :boolean
144
+ options[:param].type.should == :numeric
145
+ end
146
+
147
+ it "overwrites default options if called on the method scope" do
148
+ args = ["zoo", "--force", "--param", "feathers"]
149
+ options = MyChildScript.start(args)
150
+ options.should == { "force" => true, "param" => "feathers" }
151
+ end
152
+
153
+ it "allows default options to be merged with method options" do
154
+ args = ["animal", "bird", "--force", "--param", "1.0", "--other", "tweets"]
155
+ arg, options = MyChildScript.start(args)
156
+ arg.should == 'bird'
157
+ options.should == { "force"=>true, "param"=>1.0, "other"=>"tweets" }
158
+ end
159
+ end
160
+
161
+ describe "#start" do
162
+ it "calls a no-param method when no params are passed" do
163
+ MyScript.start(["zoo"]).should == true
164
+ end
165
+
166
+ it "calls a single-param method when a single param is passed" do
167
+ MyScript.start(["animal", "fish"]).should == ["fish"]
168
+ end
169
+
170
+ it "does not set options in attributes" do
171
+ MyScript.start(["with_optional", "--all"]).should == [nil, { "all" => true }]
172
+ end
173
+
174
+ it "raises an error if a required param is not provided" do
175
+ capture(:stderr) { MyScript.start(["animal"]) }.strip.should == '"animal" was called incorrectly. Call as "thor my_script:animal TYPE".'
176
+ end
177
+
178
+ it "raises an error if the invoked task does not exist" do
179
+ capture(:stderr) { Amazing.start(["animal"]) }.strip.should == 'Could not find task "animal" in "amazing" namespace.'
180
+ end
181
+
182
+ it "calls method_missing if an unknown method is passed in" do
183
+ MyScript.start(["unk", "hello"]).should == [:unk, ["hello"]]
184
+ end
185
+
186
+ it "does not call a private method no matter what" do
187
+ capture(:stderr) { MyScript.start(["what"]) }.strip.should == 'Could not find task "what" in "my_script" namespace.'
188
+ end
189
+
190
+ it "uses task default options" do
191
+ options = MyChildScript.start(["animal", "fish"]).last
192
+ options.should == { "other" => "method default" }
193
+ end
194
+
195
+ it "raises when an exception happens within the task call" do
196
+ lambda { MyScript.start(["call_myself_with_wrong_arity"]) }.should raise_error(ArgumentError)
197
+ end
198
+ end
199
+
200
+ describe "#subcommand" do
201
+ it "maps a given subcommand to another Thor subclass" do
202
+ barn_help = capture(:stdout){ Scripts::MyDefaults.start(["barn"]) }
203
+ barn_help.should include("barn help [COMMAND] # Describe subcommands or one specific subcommand")
204
+ end
205
+
206
+ it "passes commands to subcommand classes" do
207
+ capture(:stdout){ Scripts::MyDefaults.start(["barn", "open"]) }.strip.should == "Open sesame!"
208
+ end
209
+
210
+ it "passes arguments to subcommand classes" do
211
+ capture(:stdout){ Scripts::MyDefaults.start(["barn", "open", "shotgun"]) }.strip.should == "That's going to leave a mark."
212
+ end
213
+
214
+ it "ignores unknown options (the subcommand class will handle them)" do
215
+ capture(:stdout){ Scripts::MyDefaults.start(["barn", "paint", "blue", "--coats", "4"])}.strip.should == "4 coats of blue paint"
216
+ end
217
+ end
218
+
219
+ describe "#help" do
220
+ def shell
221
+ @shell ||= Thor::Base.shell.new
222
+ end
223
+
224
+ describe "on general" do
225
+ before(:each) do
226
+ @content = capture(:stdout){ MyScript.help(shell) }
227
+ end
228
+
229
+ it "provides useful help info for the help method itself" do
230
+ @content.should =~ /help \[TASK\]\s+# Describe available tasks/
231
+ end
232
+
233
+ it "provides useful help info for a method with params" do
234
+ @content.should =~ /animal TYPE\s+# horse around/
235
+ end
236
+
237
+ it "uses the maximum terminal size to show tasks" do
238
+ @shell.should_receive(:terminal_width).and_return(80)
239
+ content = capture(:stdout){ MyScript.help(shell) }
240
+ content.should =~ /aaa\.\.\.$/
241
+ end
242
+
243
+ it "provides description for tasks from classes in the same namespace" do
244
+ @content.should =~ /baz\s+# do some bazing/
245
+ end
246
+
247
+ it "shows superclass tasks" do
248
+ content = capture(:stdout){ MyChildScript.help(shell) }
249
+ content.should =~ /foo BAR \s+# do some fooing/
250
+ end
251
+
252
+ it "shows class options information" do
253
+ content = capture(:stdout){ MyChildScript.help(shell) }
254
+ content.should =~ /Options\:/
255
+ content.should =~ /\[\-\-param=N\]/
256
+ end
257
+
258
+ it "injects class arguments into default usage" do
259
+ content = capture(:stdout){ Scripts::MyScript.help(shell) }
260
+ content.should =~ /zoo ACCESSOR \-\-param\=PARAM/
261
+ end
262
+ end
263
+
264
+ describe "for a specific task" do
265
+ it "provides full help info when talking about a specific task" do
266
+ capture(:stdout) { MyScript.task_help(shell, "foo") }.should == <<-END
267
+ Usage:
268
+ thor my_script:foo BAR
269
+
270
+ Options:
271
+ [--force] # Force to do some fooing
272
+
273
+ do some fooing
274
+ This is more info!
275
+ Everyone likes more info!
276
+ END
277
+ end
278
+
279
+ it "raises an error if the task can't be found" do
280
+ lambda {
281
+ MyScript.task_help(shell, "unknown")
282
+ }.should raise_error(Thor::UndefinedTaskError, 'Could not find task "unknown" in "my_script" namespace.')
283
+ end
284
+
285
+ it "normalizes names before claiming they don't exist" do
286
+ capture(:stdout) { MyScript.task_help(shell, "name-with-dashes") }.should =~ /thor my_script:name-with-dashes/
287
+ end
288
+
289
+ it "uses the long description if it exists" do
290
+ capture(:stdout) { MyScript.task_help(shell, "long_description") }.should == <<-HELP
291
+ Usage:
292
+ thor my_script:long_description
293
+
294
+ Description:
295
+ This is a really really really long description. Here you go. So very long.
296
+
297
+ It even has two paragraphs.
298
+ HELP
299
+ end
300
+
301
+ it "doesn't assign the long description to the next task without one" do
302
+ capture(:stdout) do
303
+ MyScript.task_help(shell, "name_with_dashes")
304
+ end.should_not =~ /so very long/i
305
+ end
306
+ end
307
+
308
+ describe "instance method" do
309
+ it "calls the class method" do
310
+ capture(:stdout){ MyScript.start(["help"]) }.should =~ /Tasks:/
311
+ end
312
+
313
+ it "calls the class method" do
314
+ capture(:stdout){ MyScript.start(["help", "foo"]) }.should =~ /Usage:/
315
+ end
316
+ end
317
+ end
318
+
319
+ describe "when creating tasks" do
320
+ it "prints a warning if a public method is created without description or usage" do
321
+ capture(:stdout) {
322
+ klass = Class.new(Thor)
323
+ klass.class_eval "def hello_from_thor; end"
324
+ }.should =~ /\[WARNING\] Attempted to create task "hello_from_thor" without usage or description/
325
+ end
326
+
327
+ it "does not print if overwriting a previous task" do
328
+ capture(:stdout) {
329
+ klass = Class.new(Thor)
330
+ klass.class_eval "def help; end"
331
+ }.should be_empty
332
+ end
333
+ end
334
+ end