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.
Files changed (93) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.md +15 -0
  3. data/README.md +23 -6
  4. data/bin/thor +1 -1
  5. data/lib/thor/actions/create_file.rb +34 -35
  6. data/lib/thor/actions/create_link.rb +9 -5
  7. data/lib/thor/actions/directory.rb +33 -23
  8. data/lib/thor/actions/empty_directory.rb +75 -85
  9. data/lib/thor/actions/file_manipulation.rb +103 -36
  10. data/lib/thor/actions/inject_into_file.rb +46 -36
  11. data/lib/thor/actions.rb +90 -68
  12. data/lib/thor/base.rb +302 -244
  13. data/lib/thor/command.rb +142 -0
  14. data/lib/thor/core_ext/hash_with_indifferent_access.rb +52 -24
  15. data/lib/thor/error.rb +90 -10
  16. data/lib/thor/group.rb +70 -74
  17. data/lib/thor/invocation.rb +63 -55
  18. data/lib/thor/line_editor/basic.rb +37 -0
  19. data/lib/thor/line_editor/readline.rb +88 -0
  20. data/lib/thor/line_editor.rb +17 -0
  21. data/lib/thor/nested_context.rb +29 -0
  22. data/lib/thor/parser/argument.rb +24 -28
  23. data/lib/thor/parser/arguments.rb +110 -102
  24. data/lib/thor/parser/option.rb +53 -15
  25. data/lib/thor/parser/options.rb +174 -97
  26. data/lib/thor/parser.rb +4 -4
  27. data/lib/thor/rake_compat.rb +12 -11
  28. data/lib/thor/runner.rb +159 -155
  29. data/lib/thor/shell/basic.rb +216 -93
  30. data/lib/thor/shell/color.rb +53 -40
  31. data/lib/thor/shell/html.rb +61 -58
  32. data/lib/thor/shell.rb +29 -36
  33. data/lib/thor/util.rb +231 -213
  34. data/lib/thor/version.rb +1 -1
  35. data/lib/thor.rb +303 -166
  36. data/thor.gemspec +27 -24
  37. metadata +36 -226
  38. data/.gitignore +0 -44
  39. data/.rspec +0 -2
  40. data/.travis.yml +0 -7
  41. data/CHANGELOG.rdoc +0 -134
  42. data/Gemfile +0 -15
  43. data/Thorfile +0 -30
  44. data/bin/rake2thor +0 -86
  45. data/lib/thor/core_ext/dir_escape.rb +0 -0
  46. data/lib/thor/core_ext/file_binary_read.rb +0 -9
  47. data/lib/thor/core_ext/ordered_hash.rb +0 -100
  48. data/lib/thor/task.rb +0 -132
  49. data/spec/actions/create_file_spec.rb +0 -170
  50. data/spec/actions/create_link_spec.rb +0 -81
  51. data/spec/actions/directory_spec.rb +0 -149
  52. data/spec/actions/empty_directory_spec.rb +0 -130
  53. data/spec/actions/file_manipulation_spec.rb +0 -370
  54. data/spec/actions/inject_into_file_spec.rb +0 -135
  55. data/spec/actions_spec.rb +0 -331
  56. data/spec/base_spec.rb +0 -279
  57. data/spec/core_ext/hash_with_indifferent_access_spec.rb +0 -43
  58. data/spec/core_ext/ordered_hash_spec.rb +0 -115
  59. data/spec/exit_condition_spec.rb +0 -19
  60. data/spec/fixtures/application.rb +0 -2
  61. data/spec/fixtures/app{1}/README +0 -3
  62. data/spec/fixtures/bundle/execute.rb +0 -6
  63. data/spec/fixtures/bundle/main.thor +0 -1
  64. data/spec/fixtures/doc/%file_name%.rb.tt +0 -1
  65. data/spec/fixtures/doc/COMMENTER +0 -10
  66. data/spec/fixtures/doc/README +0 -3
  67. data/spec/fixtures/doc/block_helper.rb +0 -3
  68. data/spec/fixtures/doc/components/.empty_directory +0 -0
  69. data/spec/fixtures/doc/config.rb +0 -1
  70. data/spec/fixtures/doc/config.yaml.tt +0 -1
  71. data/spec/fixtures/enum.thor +0 -10
  72. data/spec/fixtures/group.thor +0 -114
  73. data/spec/fixtures/invoke.thor +0 -112
  74. data/spec/fixtures/path with spaces +0 -0
  75. data/spec/fixtures/script.thor +0 -190
  76. data/spec/fixtures/task.thor +0 -10
  77. data/spec/group_spec.rb +0 -216
  78. data/spec/invocation_spec.rb +0 -100
  79. data/spec/parser/argument_spec.rb +0 -53
  80. data/spec/parser/arguments_spec.rb +0 -66
  81. data/spec/parser/option_spec.rb +0 -202
  82. data/spec/parser/options_spec.rb +0 -330
  83. data/spec/rake_compat_spec.rb +0 -72
  84. data/spec/register_spec.rb +0 -135
  85. data/spec/runner_spec.rb +0 -241
  86. data/spec/shell/basic_spec.rb +0 -300
  87. data/spec/shell/color_spec.rb +0 -81
  88. data/spec/shell/html_spec.rb +0 -32
  89. data/spec/shell_spec.rb +0 -47
  90. data/spec/spec_helper.rb +0 -59
  91. data/spec/task_spec.rb +0 -80
  92. data/spec/thor_spec.rb +0 -418
  93. data/spec/util_spec.rb +0 -196
@@ -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
@@ -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