thor 0.16.0 → 1.2.1
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.
- checksums.yaml +7 -0
- data/CONTRIBUTING.md +15 -0
- data/README.md +23 -6
- data/bin/thor +1 -1
- data/lib/thor/actions/create_file.rb +34 -35
- data/lib/thor/actions/create_link.rb +9 -5
- data/lib/thor/actions/directory.rb +33 -23
- data/lib/thor/actions/empty_directory.rb +75 -85
- data/lib/thor/actions/file_manipulation.rb +103 -36
- data/lib/thor/actions/inject_into_file.rb +46 -36
- data/lib/thor/actions.rb +90 -68
- data/lib/thor/base.rb +302 -244
- data/lib/thor/command.rb +142 -0
- data/lib/thor/core_ext/hash_with_indifferent_access.rb +52 -24
- data/lib/thor/error.rb +90 -10
- data/lib/thor/group.rb +70 -74
- data/lib/thor/invocation.rb +63 -55
- data/lib/thor/line_editor/basic.rb +37 -0
- data/lib/thor/line_editor/readline.rb +88 -0
- data/lib/thor/line_editor.rb +17 -0
- data/lib/thor/nested_context.rb +29 -0
- data/lib/thor/parser/argument.rb +24 -28
- data/lib/thor/parser/arguments.rb +110 -102
- data/lib/thor/parser/option.rb +53 -15
- data/lib/thor/parser/options.rb +174 -97
- data/lib/thor/parser.rb +4 -4
- data/lib/thor/rake_compat.rb +12 -11
- data/lib/thor/runner.rb +159 -155
- data/lib/thor/shell/basic.rb +216 -93
- data/lib/thor/shell/color.rb +53 -40
- data/lib/thor/shell/html.rb +61 -58
- data/lib/thor/shell.rb +29 -36
- data/lib/thor/util.rb +231 -213
- data/lib/thor/version.rb +1 -1
- data/lib/thor.rb +303 -166
- data/thor.gemspec +27 -24
- metadata +36 -226
- data/.gitignore +0 -44
- data/.rspec +0 -2
- data/.travis.yml +0 -7
- data/CHANGELOG.rdoc +0 -134
- data/Gemfile +0 -15
- data/Thorfile +0 -30
- data/bin/rake2thor +0 -86
- data/lib/thor/core_ext/dir_escape.rb +0 -0
- data/lib/thor/core_ext/file_binary_read.rb +0 -9
- data/lib/thor/core_ext/ordered_hash.rb +0 -100
- data/lib/thor/task.rb +0 -132
- data/spec/actions/create_file_spec.rb +0 -170
- data/spec/actions/create_link_spec.rb +0 -81
- data/spec/actions/directory_spec.rb +0 -149
- data/spec/actions/empty_directory_spec.rb +0 -130
- data/spec/actions/file_manipulation_spec.rb +0 -370
- data/spec/actions/inject_into_file_spec.rb +0 -135
- data/spec/actions_spec.rb +0 -331
- data/spec/base_spec.rb +0 -279
- data/spec/core_ext/hash_with_indifferent_access_spec.rb +0 -43
- data/spec/core_ext/ordered_hash_spec.rb +0 -115
- data/spec/exit_condition_spec.rb +0 -19
- data/spec/fixtures/application.rb +0 -2
- data/spec/fixtures/app{1}/README +0 -3
- data/spec/fixtures/bundle/execute.rb +0 -6
- data/spec/fixtures/bundle/main.thor +0 -1
- data/spec/fixtures/doc/%file_name%.rb.tt +0 -1
- data/spec/fixtures/doc/COMMENTER +0 -10
- data/spec/fixtures/doc/README +0 -3
- data/spec/fixtures/doc/block_helper.rb +0 -3
- data/spec/fixtures/doc/components/.empty_directory +0 -0
- data/spec/fixtures/doc/config.rb +0 -1
- data/spec/fixtures/doc/config.yaml.tt +0 -1
- data/spec/fixtures/enum.thor +0 -10
- data/spec/fixtures/group.thor +0 -114
- data/spec/fixtures/invoke.thor +0 -112
- data/spec/fixtures/path with spaces +0 -0
- data/spec/fixtures/script.thor +0 -190
- data/spec/fixtures/task.thor +0 -10
- data/spec/group_spec.rb +0 -216
- data/spec/invocation_spec.rb +0 -100
- data/spec/parser/argument_spec.rb +0 -53
- data/spec/parser/arguments_spec.rb +0 -66
- data/spec/parser/option_spec.rb +0 -202
- data/spec/parser/options_spec.rb +0 -330
- data/spec/rake_compat_spec.rb +0 -72
- data/spec/register_spec.rb +0 -135
- data/spec/runner_spec.rb +0 -241
- data/spec/shell/basic_spec.rb +0 -300
- data/spec/shell/color_spec.rb +0 -81
- data/spec/shell/html_spec.rb +0 -32
- data/spec/shell_spec.rb +0 -47
- data/spec/spec_helper.rb +0 -59
- data/spec/task_spec.rb +0 -80
- data/spec/thor_spec.rb +0 -418
- data/spec/util_spec.rb +0 -196
data/spec/register_spec.rb
DELETED
@@ -1,135 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
|
3
|
-
class BoringVendorProvidedCLI < Thor
|
4
|
-
desc "boring", "do boring stuff"
|
5
|
-
def boring
|
6
|
-
puts "bored. <yawn>"
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
class ExcitingPluginCLI < Thor
|
11
|
-
desc "hooray", "say hooray!"
|
12
|
-
def hooray
|
13
|
-
puts "hooray!"
|
14
|
-
end
|
15
|
-
|
16
|
-
desc "fireworks", "exciting fireworks!"
|
17
|
-
def fireworks
|
18
|
-
puts "kaboom!"
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
class SuperSecretPlugin < Thor
|
23
|
-
default_task :squirrel
|
24
|
-
|
25
|
-
desc "squirrel", "All of secret squirrel's secrets"
|
26
|
-
def squirrel
|
27
|
-
puts "I love nuts"
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
class GroupPlugin < Thor::Group
|
32
|
-
desc "part one"
|
33
|
-
def part_one
|
34
|
-
puts "part one"
|
35
|
-
end
|
36
|
-
|
37
|
-
desc "part two"
|
38
|
-
def part_two
|
39
|
-
puts "part two"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
class ClassOptionGroupPlugin < Thor::Group
|
44
|
-
class_option :who,
|
45
|
-
:type => :string,
|
46
|
-
:aliases => "-w",
|
47
|
-
:default => "zebra"
|
48
|
-
end
|
49
|
-
|
50
|
-
class CompatibleWith19Plugin < ClassOptionGroupPlugin
|
51
|
-
desc "animal"
|
52
|
-
def animal
|
53
|
-
p options[:who]
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
BoringVendorProvidedCLI.register(
|
58
|
-
ExcitingPluginCLI,
|
59
|
-
"exciting",
|
60
|
-
"do exciting things",
|
61
|
-
"Various non-boring actions")
|
62
|
-
|
63
|
-
BoringVendorProvidedCLI.register(
|
64
|
-
SuperSecretPlugin,
|
65
|
-
"secret",
|
66
|
-
"secret stuff",
|
67
|
-
"Nothing to see here. Move along.",
|
68
|
-
:hide => true)
|
69
|
-
|
70
|
-
BoringVendorProvidedCLI.register(
|
71
|
-
GroupPlugin,
|
72
|
-
'groupwork',
|
73
|
-
"Do a bunch of things in a row",
|
74
|
-
"purple monkey dishwasher")
|
75
|
-
|
76
|
-
BoringVendorProvidedCLI.register(
|
77
|
-
CompatibleWith19Plugin,
|
78
|
-
'zoo',
|
79
|
-
"zoo [-w animal]",
|
80
|
-
"Shows a provided animal or just zebra")
|
81
|
-
|
82
|
-
describe ".register-ing a Thor subclass" do
|
83
|
-
it "registers the plugin as a subcommand" do
|
84
|
-
fireworks_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[exciting fireworks]) }
|
85
|
-
fireworks_output.should == "kaboom!\n"
|
86
|
-
end
|
87
|
-
|
88
|
-
it "includes the plugin's usage in the help" do
|
89
|
-
help_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[help]) }
|
90
|
-
help_output.should include('do exciting things')
|
91
|
-
end
|
92
|
-
|
93
|
-
context "when $thor_runner is false" do
|
94
|
-
it "includes the plugin's subcommand name in subcommand's help" do
|
95
|
-
begin
|
96
|
-
$thor_runner = false
|
97
|
-
help_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[exciting]) }
|
98
|
-
help_output.should include('thor exciting_plugin_c_l_i fireworks')
|
99
|
-
ensure
|
100
|
-
$thor_runner = true
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
context "when hidden" do
|
106
|
-
it "omits the hidden plugin's usage from the help" do
|
107
|
-
help_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[help]) }
|
108
|
-
help_output.should_not include('secret stuff')
|
109
|
-
end
|
110
|
-
|
111
|
-
it "registers the plugin as a subcommand" do
|
112
|
-
secret_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[secret squirrel]) }
|
113
|
-
secret_output.should == "I love nuts\n"
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
describe ".register-ing a Thor::Group subclass" do
|
119
|
-
it "registers the group as a single command" do
|
120
|
-
group_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[groupwork]) }
|
121
|
-
group_output.should == "part one\npart two\n"
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
describe "1.8 and 1.9 syntax compatibility" do
|
126
|
-
it "is compatible with both 1.8 and 1.9 syntax w/o task options" do
|
127
|
-
group_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[zoo]) }
|
128
|
-
group_output.should match /zebra/
|
129
|
-
end
|
130
|
-
|
131
|
-
it "is compatible with both 1.8 and 1.9 syntax w/task options" do
|
132
|
-
group_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[zoo -w lion]) }
|
133
|
-
group_output.should match /lion/
|
134
|
-
end
|
135
|
-
end
|
data/spec/runner_spec.rb
DELETED
@@ -1,241 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
|
2
|
-
require 'thor/runner'
|
3
|
-
|
4
|
-
describe Thor::Runner do
|
5
|
-
def when_no_thorfiles_exist
|
6
|
-
old_dir = Dir.pwd
|
7
|
-
Dir.chdir '..'
|
8
|
-
delete = Thor::Base.subclasses.select {|e| e.namespace == 'default' }
|
9
|
-
delete.each {|e| Thor::Base.subclasses.delete e }
|
10
|
-
yield
|
11
|
-
Thor::Base.subclasses.concat delete
|
12
|
-
Dir.chdir old_dir
|
13
|
-
end
|
14
|
-
|
15
|
-
describe "#help" do
|
16
|
-
it "shows information about Thor::Runner itself" do
|
17
|
-
capture(:stdout){ Thor::Runner.start(["help"]) }.should =~ /List the available thor tasks/
|
18
|
-
end
|
19
|
-
|
20
|
-
it "shows information about an specific Thor::Runner task" do
|
21
|
-
content = capture(:stdout){ Thor::Runner.start(["help", "list"]) }
|
22
|
-
content.should =~ /List the available thor tasks/
|
23
|
-
content.should_not =~ /help \[TASK\]/
|
24
|
-
end
|
25
|
-
|
26
|
-
it "shows information about a specific Thor class" do
|
27
|
-
content = capture(:stdout){ Thor::Runner.start(["help", "my_script"]) }
|
28
|
-
content.should =~ /zoo\s+# zoo around/m
|
29
|
-
end
|
30
|
-
|
31
|
-
it "shows information about an specific task from an specific Thor class" do
|
32
|
-
content = capture(:stdout){ Thor::Runner.start(["help", "my_script:zoo"]) }
|
33
|
-
content.should =~ /zoo around/
|
34
|
-
content.should_not =~ /help \[TASK\]/
|
35
|
-
end
|
36
|
-
|
37
|
-
it "shows information about a specific Thor group class" do
|
38
|
-
content = capture(:stdout){ Thor::Runner.start(["help", "my_counter"]) }
|
39
|
-
content.should =~ /my_counter N/
|
40
|
-
end
|
41
|
-
|
42
|
-
it "raises error if a class/task cannot be found" do
|
43
|
-
content = capture(:stderr){ Thor::Runner.start(["help", "unknown"]) }
|
44
|
-
content.strip.should == 'Could not find task "unknown" in "default" namespace.'
|
45
|
-
end
|
46
|
-
|
47
|
-
it "raises error if a class/task cannot be found for a setup without thorfiles" do
|
48
|
-
when_no_thorfiles_exist do
|
49
|
-
Thor::Runner.should_receive :exit
|
50
|
-
content = capture(:stderr){ Thor::Runner.start(["help", "unknown"]) }
|
51
|
-
content.strip.should == 'Could not find task "unknown".'
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
describe "#start" do
|
57
|
-
it "invokes a task from Thor::Runner" do
|
58
|
-
ARGV.replace ["list"]
|
59
|
-
capture(:stdout){ Thor::Runner.start }.should =~ /my_counter N/
|
60
|
-
end
|
61
|
-
|
62
|
-
it "invokes a task from a specific Thor class" do
|
63
|
-
ARGV.replace ["my_script:zoo"]
|
64
|
-
Thor::Runner.start.should be_true
|
65
|
-
end
|
66
|
-
|
67
|
-
it "invokes the default task from a specific Thor class if none is specified" do
|
68
|
-
ARGV.replace ["my_script"]
|
69
|
-
Thor::Runner.start.should == "default task"
|
70
|
-
end
|
71
|
-
|
72
|
-
it "forwads arguments to the invoked task" do
|
73
|
-
ARGV.replace ["my_script:animal", "horse"]
|
74
|
-
Thor::Runner.start.should == ["horse"]
|
75
|
-
end
|
76
|
-
|
77
|
-
it "invokes tasks through shortcuts" do
|
78
|
-
ARGV.replace ["my_script", "-T", "horse"]
|
79
|
-
Thor::Runner.start.should == ["horse"]
|
80
|
-
end
|
81
|
-
|
82
|
-
it "invokes a Thor::Group" do
|
83
|
-
ARGV.replace ["my_counter", "1", "2", "--third", "3"]
|
84
|
-
Thor::Runner.start.should == [1, 2, 3]
|
85
|
-
end
|
86
|
-
|
87
|
-
it "raises an error if class/task can't be found" do
|
88
|
-
ARGV.replace ["unknown"]
|
89
|
-
content = capture(:stderr){ Thor::Runner.start }
|
90
|
-
content.strip.should == 'Could not find task "unknown" in "default" namespace.'
|
91
|
-
end
|
92
|
-
|
93
|
-
it "raises an error if class/task can't be found in a setup without thorfiles" do
|
94
|
-
when_no_thorfiles_exist do
|
95
|
-
ARGV.replace ["unknown"]
|
96
|
-
Thor::Runner.should_receive :exit
|
97
|
-
content = capture(:stderr){ Thor::Runner.start }
|
98
|
-
content.strip.should == 'Could not find task "unknown".'
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
it "does not swallow NoMethodErrors that occur inside the called method" do
|
103
|
-
ARGV.replace ["my_script:call_unexistent_method"]
|
104
|
-
lambda { Thor::Runner.start }.should raise_error(NoMethodError)
|
105
|
-
end
|
106
|
-
|
107
|
-
it "does not swallow Thor::Group InvocationError" do
|
108
|
-
ARGV.replace ["whiny_generator"]
|
109
|
-
lambda { Thor::Runner.start }.should raise_error(ArgumentError, /thor wrong_arity takes 1 argument, but it should not/)
|
110
|
-
end
|
111
|
-
|
112
|
-
it "does not swallow Thor InvocationError" do
|
113
|
-
ARGV.replace ["my_script:animal"]
|
114
|
-
content = capture(:stderr) { Thor::Runner.start }
|
115
|
-
content.strip.should == 'thor animal requires at least 1 argument: "thor my_script:animal TYPE".'
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
describe "tasks" do
|
120
|
-
before do
|
121
|
-
@location = "#{File.dirname(__FILE__)}/fixtures/task.thor"
|
122
|
-
@original_yaml = {
|
123
|
-
"random" => {
|
124
|
-
:location => @location,
|
125
|
-
:filename => "4a33b894ffce85d7b412fc1b36f88fe0",
|
126
|
-
:namespaces => ["amazing"]
|
127
|
-
}
|
128
|
-
}
|
129
|
-
|
130
|
-
root_file = File.join(Thor::Util.thor_root, "thor.yml")
|
131
|
-
|
132
|
-
# Stub load and save to avoid thor.yaml from being overwritten
|
133
|
-
YAML.stub!(:load_file).and_return(@original_yaml)
|
134
|
-
File.stub!(:exists?).with(root_file).and_return(true)
|
135
|
-
File.stub!(:open).with(root_file, "w")
|
136
|
-
end
|
137
|
-
|
138
|
-
describe "list" do
|
139
|
-
it "gives a list of the available tasks" do
|
140
|
-
ARGV.replace ["list"]
|
141
|
-
content = capture(:stdout) { Thor::Runner.start }
|
142
|
-
content.should =~ /amazing:describe NAME\s+# say that someone is amazing/m
|
143
|
-
end
|
144
|
-
|
145
|
-
it "gives a list of the available Thor::Group classes" do
|
146
|
-
ARGV.replace ["list"]
|
147
|
-
capture(:stdout) { Thor::Runner.start }.should =~ /my_counter N/
|
148
|
-
end
|
149
|
-
|
150
|
-
it "can filter a list of the available tasks by --group" do
|
151
|
-
ARGV.replace ["list", "--group", "standard"]
|
152
|
-
capture(:stdout) { Thor::Runner.start }.should =~ /amazing:describe NAME/
|
153
|
-
ARGV.replace []
|
154
|
-
capture(:stdout) { Thor::Runner.start }.should_not =~ /my_script:animal TYPE/
|
155
|
-
ARGV.replace ["list", "--group", "script"]
|
156
|
-
capture(:stdout) { Thor::Runner.start }.should =~ /my_script:animal TYPE/
|
157
|
-
end
|
158
|
-
|
159
|
-
it "can skip all filters to show all tasks using --all" do
|
160
|
-
ARGV.replace ["list", "--all"]
|
161
|
-
content = capture(:stdout) { Thor::Runner.start }
|
162
|
-
content.should =~ /amazing:describe NAME/
|
163
|
-
content.should =~ /my_script:animal TYPE/
|
164
|
-
end
|
165
|
-
|
166
|
-
it "doesn't list superclass tasks in the subclass" do
|
167
|
-
ARGV.replace ["list"]
|
168
|
-
capture(:stdout) { Thor::Runner.start }.should_not =~ /amazing:help/
|
169
|
-
end
|
170
|
-
|
171
|
-
it "presents tasks in the default namespace with an empty namespace" do
|
172
|
-
ARGV.replace ["list"]
|
173
|
-
capture(:stdout) { Thor::Runner.start }.should =~ /^thor :cow\s+# prints 'moo'/m
|
174
|
-
end
|
175
|
-
|
176
|
-
it "runs tasks with an empty namespace from the default namespace" do
|
177
|
-
ARGV.replace [":task_conflict"]
|
178
|
-
capture(:stdout) { Thor::Runner.start }.should == "task\n"
|
179
|
-
end
|
180
|
-
|
181
|
-
it "runs groups even when there is a task with the same name" do
|
182
|
-
ARGV.replace ["task_conflict"]
|
183
|
-
capture(:stdout) { Thor::Runner.start }.should == "group\n"
|
184
|
-
end
|
185
|
-
|
186
|
-
it "runs tasks with no colon in the default namespace" do
|
187
|
-
ARGV.replace ["cow"]
|
188
|
-
capture(:stdout) { Thor::Runner.start }.should == "moo\n"
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
describe "uninstall" do
|
193
|
-
before do
|
194
|
-
path = File.join(Thor::Util.thor_root, @original_yaml["random"][:filename])
|
195
|
-
FileUtils.should_receive(:rm_rf).with(path)
|
196
|
-
end
|
197
|
-
|
198
|
-
it "uninstalls existing thor modules" do
|
199
|
-
silence(:stdout) { Thor::Runner.start(["uninstall", "random"]) }
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
describe "installed" do
|
204
|
-
before do
|
205
|
-
Dir.should_receive(:[]).and_return([])
|
206
|
-
end
|
207
|
-
|
208
|
-
it "displays the modules installed in a pretty way" do
|
209
|
-
stdout = capture(:stdout) { Thor::Runner.start(["installed"]) }
|
210
|
-
stdout.should =~ /random\s*amazing/
|
211
|
-
stdout.should =~ /amazing:describe NAME\s+# say that someone is amazing/m
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
|
-
describe "install/update" do
|
216
|
-
before do
|
217
|
-
FileUtils.stub!(:mkdir_p)
|
218
|
-
FileUtils.stub!(:touch)
|
219
|
-
$stdin.stub!(:gets).and_return("Y")
|
220
|
-
|
221
|
-
path = File.join(Thor::Util.thor_root, Digest::MD5.hexdigest(@location + "random"))
|
222
|
-
File.should_receive(:open).with(path, "w")
|
223
|
-
end
|
224
|
-
|
225
|
-
it "updates existing thor files" do
|
226
|
-
path = File.join(Thor::Util.thor_root, @original_yaml["random"][:filename])
|
227
|
-
if File.directory? path
|
228
|
-
FileUtils.should_receive(:rm_rf).with(path)
|
229
|
-
else
|
230
|
-
File.should_receive(:delete).with(path)
|
231
|
-
end
|
232
|
-
silence(:stdout) { Thor::Runner.start(["update", "random"]) }
|
233
|
-
end
|
234
|
-
|
235
|
-
it "installs thor files" do
|
236
|
-
ARGV.replace ["install", @location]
|
237
|
-
silence(:stdout) { Thor::Runner.start }
|
238
|
-
end
|
239
|
-
end
|
240
|
-
end
|
241
|
-
end
|
data/spec/shell/basic_spec.rb
DELETED
@@ -1,300 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
4
|
-
|
5
|
-
describe Thor::Shell::Basic do
|
6
|
-
def shell
|
7
|
-
@shell ||= Thor::Shell::Basic.new
|
8
|
-
end
|
9
|
-
|
10
|
-
describe "#padding" do
|
11
|
-
it "cannot be set to below zero" do
|
12
|
-
shell.padding = 10
|
13
|
-
shell.padding.should == 10
|
14
|
-
|
15
|
-
shell.padding = -1
|
16
|
-
shell.padding.should == 0
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
describe "#ask" do
|
21
|
-
it "prints a message to the user and gets the response" do
|
22
|
-
$stdout.should_receive(:print).with("Should I overwrite it? ")
|
23
|
-
$stdin.should_receive(:gets).and_return('Sure')
|
24
|
-
shell.ask("Should I overwrite it?").should == "Sure"
|
25
|
-
end
|
26
|
-
|
27
|
-
it "prints a message to the user with the available options and determines the correctness of the answer" do
|
28
|
-
$stdout.should_receive(:print).with('What\'s your favorite Neopolitan flavor? ["strawberry", "chocolate", "vanilla"] ')
|
29
|
-
$stdin.should_receive(:gets).and_return('chocolate')
|
30
|
-
shell.ask("What's your favorite Neopolitan flavor?", :limited_to => ["strawberry", "chocolate", "vanilla"]).should == "chocolate"
|
31
|
-
end
|
32
|
-
|
33
|
-
it "prints a message to the user with the available options and reasks the question after an incorrect repsonse" do
|
34
|
-
$stdout.should_receive(:print).with('What\'s your favorite Neopolitan flavor? ["strawberry", "chocolate", "vanilla"] ').twice
|
35
|
-
$stdout.should_receive(:puts).with('Your response must be one of: ["strawberry", "chocolate", "vanilla"]. Please try again.')
|
36
|
-
$stdin.should_receive(:gets).and_return('moose tracks', 'chocolate')
|
37
|
-
shell.ask("What's your favorite Neopolitan flavor?", :limited_to => ["strawberry", "chocolate", "vanilla"]).should == "chocolate"
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
describe "#yes?" do
|
42
|
-
it "asks the user and returns true if the user replies yes" do
|
43
|
-
$stdout.should_receive(:print).with("Should I overwrite it? ")
|
44
|
-
$stdin.should_receive(:gets).and_return('y')
|
45
|
-
shell.yes?("Should I overwrite it?").should === true
|
46
|
-
|
47
|
-
$stdout.should_receive(:print).with("Should I overwrite it? ")
|
48
|
-
$stdin.should_receive(:gets).and_return('n')
|
49
|
-
shell.yes?("Should I overwrite it?").should_not === true
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
describe "#no?" do
|
54
|
-
it "asks the user and returns true if the user replies no" do
|
55
|
-
$stdout.should_receive(:print).with("Should I overwrite it? ")
|
56
|
-
$stdin.should_receive(:gets).and_return('n')
|
57
|
-
shell.no?("Should I overwrite it?").should === true
|
58
|
-
|
59
|
-
$stdout.should_receive(:print).with("Should I overwrite it? ")
|
60
|
-
$stdin.should_receive(:gets).and_return('Yes')
|
61
|
-
shell.no?("Should I overwrite it?").should === false
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
describe "#say" do
|
66
|
-
it "prints a message to the user" do
|
67
|
-
$stdout.should_receive(:puts).with("Running...")
|
68
|
-
shell.say("Running...")
|
69
|
-
end
|
70
|
-
|
71
|
-
it "prints a message to the user without new line if it ends with a whitespace" do
|
72
|
-
$stdout.should_receive(:print).with("Running... ")
|
73
|
-
shell.say("Running... ")
|
74
|
-
end
|
75
|
-
|
76
|
-
it "prints a message to the user without new line" do
|
77
|
-
$stdout.should_receive(:print).with("Running...")
|
78
|
-
shell.say("Running...", nil, false)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
describe "#say_status" do
|
83
|
-
it "prints a message to the user with status" do
|
84
|
-
$stdout.should_receive(:puts).with(" create ~/.thor/task.thor")
|
85
|
-
shell.say_status(:create, "~/.thor/task.thor")
|
86
|
-
end
|
87
|
-
|
88
|
-
it "always use new line" do
|
89
|
-
$stdout.should_receive(:puts).with(" create ")
|
90
|
-
shell.say_status(:create, "")
|
91
|
-
end
|
92
|
-
|
93
|
-
it "does not print a message if base is muted" do
|
94
|
-
shell.should_receive(:mute?).and_return(true)
|
95
|
-
$stdout.should_not_receive(:puts)
|
96
|
-
|
97
|
-
shell.mute do
|
98
|
-
shell.say_status(:created, "~/.thor/task.thor")
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
it "does not print a message if base is set to quiet" do
|
103
|
-
base = MyCounter.new [1,2]
|
104
|
-
base.should_receive(:options).and_return(:quiet => true)
|
105
|
-
|
106
|
-
$stdout.should_not_receive(:puts)
|
107
|
-
shell.base = base
|
108
|
-
shell.say_status(:created, "~/.thor/task.thor")
|
109
|
-
end
|
110
|
-
|
111
|
-
it "does not print a message if log status is set to false" do
|
112
|
-
$stdout.should_not_receive(:puts)
|
113
|
-
shell.say_status(:created, "~/.thor/task.thor", false)
|
114
|
-
end
|
115
|
-
|
116
|
-
it "uses padding to set messages left margin" do
|
117
|
-
shell.padding = 2
|
118
|
-
$stdout.should_receive(:puts).with(" create ~/.thor/task.thor")
|
119
|
-
shell.say_status(:create, "~/.thor/task.thor")
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
describe "#print_in_columns" do
|
124
|
-
before do
|
125
|
-
@array = [1234567890]
|
126
|
-
@array += ('a'..'e').to_a
|
127
|
-
end
|
128
|
-
|
129
|
-
it "prints in columns" do
|
130
|
-
content = capture(:stdout){ shell.print_in_columns(@array) }
|
131
|
-
content.rstrip.should == "1234567890 a b c d e"
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
describe "#print_table" do
|
136
|
-
before do
|
137
|
-
@table = []
|
138
|
-
@table << ["abc", "#123", "first three"]
|
139
|
-
@table << ["", "#0", "empty"]
|
140
|
-
@table << ["xyz", "#786", "last three"]
|
141
|
-
end
|
142
|
-
|
143
|
-
it "prints a table" do
|
144
|
-
content = capture(:stdout){ shell.print_table(@table) }
|
145
|
-
content.should == <<-TABLE
|
146
|
-
abc #123 first three
|
147
|
-
#0 empty
|
148
|
-
xyz #786 last three
|
149
|
-
TABLE
|
150
|
-
end
|
151
|
-
|
152
|
-
it "prints a table with indentation" do
|
153
|
-
content = capture(:stdout){ shell.print_table(@table, :indent => 2) }
|
154
|
-
content.should == <<-TABLE
|
155
|
-
abc #123 first three
|
156
|
-
#0 empty
|
157
|
-
xyz #786 last three
|
158
|
-
TABLE
|
159
|
-
end
|
160
|
-
|
161
|
-
it "uses maximum terminal width" do
|
162
|
-
@table << ["def", "#456", "Lançam foo bar"]
|
163
|
-
@table << ["ghi", "#789", "بالله عليكم"]
|
164
|
-
shell.should_receive(:terminal_width).and_return(20)
|
165
|
-
content = capture(:stdout){ shell.print_table(@table, :indent => 2, :truncate => true) }
|
166
|
-
content.should == <<-TABLE
|
167
|
-
abc #123 firs...
|
168
|
-
#0 empty
|
169
|
-
xyz #786 last...
|
170
|
-
def #456 Lanç...
|
171
|
-
ghi #789 بالل...
|
172
|
-
TABLE
|
173
|
-
end
|
174
|
-
|
175
|
-
it "honors the colwidth option" do
|
176
|
-
content = capture(:stdout){ shell.print_table(@table, :colwidth => 10)}
|
177
|
-
content.should == <<-TABLE
|
178
|
-
abc #123 first three
|
179
|
-
#0 empty
|
180
|
-
xyz #786 last three
|
181
|
-
TABLE
|
182
|
-
end
|
183
|
-
|
184
|
-
it "prints tables with implicit columns" do
|
185
|
-
2.times { @table.first.pop }
|
186
|
-
content = capture(:stdout){ shell.print_table(@table) }
|
187
|
-
content.should == <<-TABLE
|
188
|
-
abc
|
189
|
-
#0 empty
|
190
|
-
xyz #786 last three
|
191
|
-
TABLE
|
192
|
-
end
|
193
|
-
|
194
|
-
it "prints a table with small numbers and right-aligns them" do
|
195
|
-
table = [
|
196
|
-
["Name", "Number", "Color"],
|
197
|
-
["Erik", 1, "green"]
|
198
|
-
]
|
199
|
-
content = capture(:stdout){ shell.print_table(table) }
|
200
|
-
content.should == <<-TABLE
|
201
|
-
Name Number Color
|
202
|
-
Erik 1 green
|
203
|
-
TABLE
|
204
|
-
end
|
205
|
-
|
206
|
-
it "doesn't output extra spaces for right-aligned columns in the last column" do
|
207
|
-
table = [
|
208
|
-
["Name", "Number"],
|
209
|
-
["Erik", 1]
|
210
|
-
]
|
211
|
-
content = capture(:stdout){ shell.print_table(table) }
|
212
|
-
content.should == <<-TABLE
|
213
|
-
Name Number
|
214
|
-
Erik 1
|
215
|
-
TABLE
|
216
|
-
end
|
217
|
-
|
218
|
-
it "prints a table with big numbers" do
|
219
|
-
table = [
|
220
|
-
["Name", "Number", "Color"],
|
221
|
-
["Erik", 1234567890123, "green"]
|
222
|
-
]
|
223
|
-
content = capture(:stdout){ shell.print_table(table) }
|
224
|
-
content.should == <<-TABLE
|
225
|
-
Name Number Color
|
226
|
-
Erik 1234567890123 green
|
227
|
-
TABLE
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
231
|
-
describe "#file_collision" do
|
232
|
-
it "shows a menu with options" do
|
233
|
-
$stdout.should_receive(:print).with('Overwrite foo? (enter "h" for help) [Ynaqh] ')
|
234
|
-
$stdin.should_receive(:gets).and_return('n')
|
235
|
-
shell.file_collision('foo')
|
236
|
-
end
|
237
|
-
|
238
|
-
it "returns true if the user choose default option" do
|
239
|
-
$stdout.stub!(:print)
|
240
|
-
$stdin.should_receive(:gets).and_return('')
|
241
|
-
shell.file_collision('foo').should be_true
|
242
|
-
end
|
243
|
-
|
244
|
-
it "returns false if the user choose no" do
|
245
|
-
$stdout.stub!(:print)
|
246
|
-
$stdin.should_receive(:gets).and_return('n')
|
247
|
-
shell.file_collision('foo').should be_false
|
248
|
-
end
|
249
|
-
|
250
|
-
it "returns true if the user choose yes" do
|
251
|
-
$stdout.stub!(:print)
|
252
|
-
$stdin.should_receive(:gets).and_return('y')
|
253
|
-
shell.file_collision('foo').should be_true
|
254
|
-
end
|
255
|
-
|
256
|
-
it "shows help usage if the user choose help" do
|
257
|
-
$stdout.stub!(:print)
|
258
|
-
$stdin.should_receive(:gets).and_return('h')
|
259
|
-
$stdin.should_receive(:gets).and_return('n')
|
260
|
-
help = capture(:stdout){ shell.file_collision('foo') }
|
261
|
-
help.should =~ /h \- help, show this help/
|
262
|
-
end
|
263
|
-
|
264
|
-
it "quits if the user choose quit" do
|
265
|
-
$stdout.stub!(:print)
|
266
|
-
$stdout.should_receive(:puts).with('Aborting...')
|
267
|
-
$stdin.should_receive(:gets).and_return('q')
|
268
|
-
|
269
|
-
lambda {
|
270
|
-
shell.file_collision('foo')
|
271
|
-
}.should raise_error(SystemExit)
|
272
|
-
end
|
273
|
-
|
274
|
-
it "always returns true if the user choose always" do
|
275
|
-
$stdout.should_receive(:print).with('Overwrite foo? (enter "h" for help) [Ynaqh] ')
|
276
|
-
$stdin.should_receive(:gets).and_return('a')
|
277
|
-
|
278
|
-
shell.file_collision('foo').should be_true
|
279
|
-
|
280
|
-
$stdout.should_not_receive(:print)
|
281
|
-
shell.file_collision('foo').should be_true
|
282
|
-
end
|
283
|
-
|
284
|
-
describe "when a block is given" do
|
285
|
-
it "displays diff options to the user" do
|
286
|
-
$stdout.should_receive(:print).with('Overwrite foo? (enter "h" for help) [Ynaqdh] ')
|
287
|
-
$stdin.should_receive(:gets).and_return('s')
|
288
|
-
shell.file_collision('foo'){ }
|
289
|
-
end
|
290
|
-
|
291
|
-
it "invokes the diff command" do
|
292
|
-
$stdout.stub!(:print)
|
293
|
-
$stdin.should_receive(:gets).and_return('d')
|
294
|
-
$stdin.should_receive(:gets).and_return('n')
|
295
|
-
shell.should_receive(:system).with(/diff -u/)
|
296
|
-
capture(:stdout){ shell.file_collision('foo'){ } }
|
297
|
-
end
|
298
|
-
end
|
299
|
-
end
|
300
|
-
end
|