wijet-thor 0.14.6
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.
- data/CHANGELOG.rdoc +103 -0
- data/LICENSE +20 -0
- data/README.md +307 -0
- data/Thorfile +24 -0
- data/bin/rake2thor +86 -0
- data/bin/thor +6 -0
- data/lib/thor.rb +334 -0
- data/lib/thor/actions.rb +314 -0
- data/lib/thor/actions/create_file.rb +105 -0
- data/lib/thor/actions/create_link.rb +57 -0
- data/lib/thor/actions/directory.rb +93 -0
- data/lib/thor/actions/empty_directory.rb +134 -0
- data/lib/thor/actions/file_manipulation.rb +270 -0
- data/lib/thor/actions/inject_into_file.rb +109 -0
- data/lib/thor/base.rb +579 -0
- data/lib/thor/core_ext/file_binary_read.rb +9 -0
- data/lib/thor/core_ext/hash_with_indifferent_access.rb +75 -0
- data/lib/thor/core_ext/ordered_hash.rb +100 -0
- data/lib/thor/error.rb +30 -0
- data/lib/thor/group.rb +273 -0
- data/lib/thor/invocation.rb +168 -0
- data/lib/thor/parser.rb +4 -0
- data/lib/thor/parser/argument.rb +67 -0
- data/lib/thor/parser/arguments.rb +161 -0
- data/lib/thor/parser/option.rb +120 -0
- data/lib/thor/parser/options.rb +173 -0
- data/lib/thor/rake_compat.rb +66 -0
- data/lib/thor/runner.rb +309 -0
- data/lib/thor/shell.rb +88 -0
- data/lib/thor/shell/basic.rb +290 -0
- data/lib/thor/shell/color.rb +108 -0
- data/lib/thor/shell/html.rb +121 -0
- data/lib/thor/task.rb +114 -0
- data/lib/thor/util.rb +229 -0
- data/lib/thor/version.rb +3 -0
- data/spec/actions/create_file_spec.rb +170 -0
- data/spec/actions/directory_spec.rb +136 -0
- data/spec/actions/empty_directory_spec.rb +98 -0
- data/spec/actions/file_manipulation_spec.rb +310 -0
- data/spec/actions/inject_into_file_spec.rb +135 -0
- data/spec/actions_spec.rb +322 -0
- data/spec/base_spec.rb +269 -0
- data/spec/core_ext/hash_with_indifferent_access_spec.rb +43 -0
- data/spec/core_ext/ordered_hash_spec.rb +115 -0
- data/spec/fixtures/application.rb +2 -0
- data/spec/fixtures/bundle/execute.rb +6 -0
- data/spec/fixtures/bundle/main.thor +1 -0
- data/spec/fixtures/doc/%file_name%.rb.tt +1 -0
- data/spec/fixtures/doc/README +3 -0
- data/spec/fixtures/doc/block_helper.rb +3 -0
- data/spec/fixtures/doc/components/.empty_directory +0 -0
- data/spec/fixtures/doc/config.rb +1 -0
- data/spec/fixtures/group.thor +114 -0
- data/spec/fixtures/invoke.thor +112 -0
- data/spec/fixtures/path with spaces b/data/spec/fixtures/path with → spaces +0 -0
- data/spec/fixtures/script.thor +184 -0
- data/spec/fixtures/task.thor +10 -0
- data/spec/group_spec.rb +178 -0
- data/spec/invocation_spec.rb +100 -0
- data/spec/parser/argument_spec.rb +47 -0
- data/spec/parser/arguments_spec.rb +64 -0
- data/spec/parser/option_spec.rb +202 -0
- data/spec/parser/options_spec.rb +319 -0
- data/spec/rake_compat_spec.rb +68 -0
- data/spec/register_spec.rb +104 -0
- data/spec/runner_spec.rb +210 -0
- data/spec/shell/basic_spec.rb +223 -0
- data/spec/shell/color_spec.rb +41 -0
- data/spec/shell/html_spec.rb +27 -0
- data/spec/shell_spec.rb +47 -0
- data/spec/spec_helper.rb +54 -0
- data/spec/task_spec.rb +74 -0
- data/spec/thor_spec.rb +334 -0
- data/spec/util_spec.rb +163 -0
- 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
|
data/spec/shell_spec.rb
ADDED
@@ -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
|
data/spec/spec_helper.rb
ADDED
@@ -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
|
data/spec/task_spec.rb
ADDED
@@ -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
|
data/spec/thor_spec.rb
ADDED
@@ -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
|