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.
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,135 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'thor/actions'
3
+
4
+ describe Thor::Actions::InjectIntoFile do
5
+ before(:each) do
6
+ ::FileUtils.rm_rf(destination_root)
7
+ ::FileUtils.cp_r(source_root, destination_root)
8
+ end
9
+
10
+ def invoker(options={})
11
+ @invoker ||= MyCounter.new([1,2], options, { :destination_root => destination_root })
12
+ end
13
+
14
+ def revoker
15
+ @revoker ||= MyCounter.new([1,2], {}, { :destination_root => destination_root, :behavior => :revoke })
16
+ end
17
+
18
+ def invoke!(*args, &block)
19
+ capture(:stdout){ invoker.insert_into_file(*args, &block) }
20
+ end
21
+
22
+ def revoke!(*args, &block)
23
+ capture(:stdout){ revoker.insert_into_file(*args, &block) }
24
+ end
25
+
26
+ def file
27
+ File.join(destination_root, "doc/README")
28
+ end
29
+
30
+ describe "#invoke!" do
31
+ it "changes the file adding content after the flag" do
32
+ invoke! "doc/README", "\nmore content", :after => "__start__"
33
+ File.read(file).should == "__start__\nmore content\nREADME\n__end__\n"
34
+ end
35
+
36
+ it "changes the file adding content before the flag" do
37
+ invoke! "doc/README", "more content\n", :before => "__end__"
38
+ File.read(file).should == "__start__\nREADME\nmore content\n__end__\n"
39
+ end
40
+
41
+ it "accepts data as a block" do
42
+ invoke! "doc/README", :before => "__end__" do
43
+ "more content\n"
44
+ end
45
+
46
+ File.read(file).should == "__start__\nREADME\nmore content\n__end__\n"
47
+ end
48
+
49
+ it "logs status" do
50
+ invoke!("doc/README", "\nmore content", :after => "__start__").should == " insert doc/README\n"
51
+ end
52
+
53
+ it "does not change the file if pretending" do
54
+ invoker :pretend => true
55
+ invoke! "doc/README", "\nmore content", :after => "__start__"
56
+ File.read(file).should == "__start__\nREADME\n__end__\n"
57
+ end
58
+
59
+ it "does not change the file if already include content" do
60
+ invoke! "doc/README", :before => "__end__" do
61
+ "more content\n"
62
+ end
63
+
64
+ File.read(file).should == "__start__\nREADME\nmore content\n__end__\n"
65
+
66
+ invoke! "doc/README", :before => "__end__" do
67
+ "more content\n"
68
+ end
69
+
70
+ File.read(file).should == "__start__\nREADME\nmore content\n__end__\n"
71
+ end
72
+
73
+ it "does change the file if already include content and :force == true" do
74
+ invoke! "doc/README", :before => "__end__" do
75
+ "more content\n"
76
+ end
77
+
78
+ File.read(file).should == "__start__\nREADME\nmore content\n__end__\n"
79
+
80
+ invoke! "doc/README", :before => "__end__", :force => true do
81
+ "more content\n"
82
+ end
83
+
84
+ File.read(file).should == "__start__\nREADME\nmore content\nmore content\n__end__\n"
85
+ end
86
+
87
+ end
88
+
89
+ describe "#revoke!" do
90
+ it "substracts the destination file after injection" do
91
+ invoke! "doc/README", "\nmore content", :after => "__start__"
92
+ revoke! "doc/README", "\nmore content", :after => "__start__"
93
+ File.read(file).should == "__start__\nREADME\n__end__\n"
94
+ end
95
+
96
+ it "substracts the destination file before injection" do
97
+ invoke! "doc/README", "more content\n", :before => "__start__"
98
+ revoke! "doc/README", "more content\n", :before => "__start__"
99
+ File.read(file).should == "__start__\nREADME\n__end__\n"
100
+ end
101
+
102
+ it "substracts even with double after injection" do
103
+ invoke! "doc/README", "\nmore content", :after => "__start__"
104
+ invoke! "doc/README", "\nanother stuff", :after => "__start__"
105
+ revoke! "doc/README", "\nmore content", :after => "__start__"
106
+ File.read(file).should == "__start__\nanother stuff\nREADME\n__end__\n"
107
+ end
108
+
109
+ it "substracts even with double before injection" do
110
+ invoke! "doc/README", "more content\n", :before => "__start__"
111
+ invoke! "doc/README", "another stuff\n", :before => "__start__"
112
+ revoke! "doc/README", "more content\n", :before => "__start__"
113
+ File.read(file).should == "another stuff\n__start__\nREADME\n__end__\n"
114
+ end
115
+
116
+ it "substracts when prepending" do
117
+ invoke! "doc/README", "more content\n", :after => /\A/
118
+ invoke! "doc/README", "another stuff\n", :after => /\A/
119
+ revoke! "doc/README", "more content\n", :after => /\A/
120
+ File.read(file).should == "another stuff\n__start__\nREADME\n__end__\n"
121
+ end
122
+
123
+ it "substracts when appending" do
124
+ invoke! "doc/README", "more content\n", :before => /\z/
125
+ invoke! "doc/README", "another stuff\n", :before => /\z/
126
+ revoke! "doc/README", "more content\n", :before => /\z/
127
+ File.read(file).should == "__start__\nREADME\n__end__\nanother stuff\n"
128
+ end
129
+
130
+ it "shows progress information to the user" do
131
+ invoke!("doc/README", "\nmore content", :after => "__start__")
132
+ revoke!("doc/README", "\nmore content", :after => "__start__").should == " subtract doc/README\n"
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,322 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Thor::Actions do
4
+ def runner(options={})
5
+ @runner ||= MyCounter.new([1], options, { :destination_root => destination_root })
6
+ end
7
+
8
+ def action(*args, &block)
9
+ capture(:stdout){ runner.send(*args, &block) }
10
+ end
11
+
12
+ def file
13
+ File.join(destination_root, "foo")
14
+ end
15
+
16
+ describe "on include" do
17
+ it "adds runtime options to the base class" do
18
+ MyCounter.class_options.keys.should include(:pretend)
19
+ MyCounter.class_options.keys.should include(:force)
20
+ MyCounter.class_options.keys.should include(:quiet)
21
+ MyCounter.class_options.keys.should include(:skip)
22
+ end
23
+ end
24
+
25
+ describe "#initialize" do
26
+ it "has default behavior invoke" do
27
+ runner.behavior.should == :invoke
28
+ end
29
+
30
+ it "can have behavior revoke" do
31
+ MyCounter.new([1], {}, :behavior => :revoke).behavior.should == :revoke
32
+ end
33
+
34
+ it "when behavior is set to force, overwrite options" do
35
+ runner = MyCounter.new([1], { :force => false, :skip => true }, :behavior => :force)
36
+ runner.behavior.should == :invoke
37
+ runner.options.force.should be_true
38
+ runner.options.skip.should_not be_true
39
+ end
40
+
41
+ it "when behavior is set to skip, overwrite options" do
42
+ runner = MyCounter.new([1], ["--force"], :behavior => :skip)
43
+ runner.behavior.should == :invoke
44
+ runner.options.force.should_not be_true
45
+ runner.options.skip.should be_true
46
+ end
47
+ end
48
+
49
+ describe "accessors" do
50
+ describe "#destination_root=" do
51
+ it "gets the current directory and expands the path to set the root" do
52
+ base = MyCounter.new([1])
53
+ base.destination_root = "here"
54
+ base.destination_root.should == File.expand_path(File.join(File.dirname(__FILE__), "..", "here"))
55
+ end
56
+
57
+ it "does not use the current directory if one is given" do
58
+ root = File.expand_path("/")
59
+ base = MyCounter.new([1])
60
+ base.destination_root = root
61
+ base.destination_root.should == root
62
+ end
63
+
64
+ it "uses the current directory if none is given" do
65
+ base = MyCounter.new([1])
66
+ base.destination_root.should == File.expand_path(File.join(File.dirname(__FILE__), ".."))
67
+ end
68
+ end
69
+
70
+ describe "#relative_to_original_destination_root" do
71
+ it "returns the path relative to the absolute root" do
72
+ runner.relative_to_original_destination_root(file).should == "foo"
73
+ end
74
+
75
+ it "does not remove dot if required" do
76
+ runner.relative_to_original_destination_root(file, false).should == "./foo"
77
+ end
78
+
79
+ it "always use the absolute root" do
80
+ runner.inside("foo") do
81
+ runner.relative_to_original_destination_root(file).should == "foo"
82
+ end
83
+ end
84
+
85
+ describe "#source_paths_for_search" do
86
+ it "add source_root to source_paths_for_search" do
87
+ MyCounter.source_paths_for_search.should include(File.expand_path("fixtures", File.dirname(__FILE__)))
88
+ end
89
+
90
+ it "keeps only current source root in source paths" do
91
+ ClearCounter.source_paths_for_search.should include(File.expand_path("fixtures/bundle", File.dirname(__FILE__)))
92
+ ClearCounter.source_paths_for_search.should_not include(File.expand_path("fixtures", File.dirname(__FILE__)))
93
+ end
94
+
95
+ it "customized source paths should be before source roots" do
96
+ ClearCounter.source_paths_for_search[0].should == File.expand_path("fixtures/doc", File.dirname(__FILE__))
97
+ ClearCounter.source_paths_for_search[1].should == File.expand_path("fixtures/bundle", File.dirname(__FILE__))
98
+ end
99
+
100
+ it "keeps inherited source paths at the end" do
101
+ ClearCounter.source_paths_for_search.last.should == File.expand_path("fixtures/broken", File.dirname(__FILE__))
102
+ end
103
+ end
104
+ end
105
+
106
+ describe "#find_in_source_paths" do
107
+ it "raises an error if source path is empty" do
108
+ lambda {
109
+ A.new.find_in_source_paths("foo")
110
+ }.should raise_error(Thor::Error, /Currently you have no source paths/)
111
+ end
112
+
113
+ it "finds a template inside the source path" do
114
+ runner.find_in_source_paths("doc").should == File.expand_path("doc", source_root)
115
+ lambda { runner.find_in_source_paths("README") }.should raise_error
116
+
117
+ new_path = File.join(source_root, "doc")
118
+ runner.instance_variable_set(:@source_paths, nil)
119
+ runner.source_paths.unshift(new_path)
120
+ runner.find_in_source_paths("README").should == File.expand_path("README", new_path)
121
+ end
122
+ end
123
+ end
124
+
125
+ describe "#inside" do
126
+ it "executes the block inside the given folder" do
127
+ runner.inside("foo") do
128
+ Dir.pwd.should == file
129
+ end
130
+ end
131
+
132
+ it "changes the base root" do
133
+ runner.inside("foo") do
134
+ runner.destination_root.should == file
135
+ end
136
+ end
137
+
138
+ it "creates the directory if it does not exist" do
139
+ runner.inside("foo") do
140
+ File.exists?(file).should be_true
141
+ end
142
+ end
143
+
144
+ describe "when pretending" do
145
+ it "no directories should be created" do
146
+ runner.inside("bar", :pretend => true) {}
147
+ File.exists?("bar").should be_false
148
+ end
149
+ end
150
+
151
+ describe "when verbose" do
152
+ it "logs status" do
153
+ capture(:stdout) do
154
+ runner.inside("foo", :verbose => true) {}
155
+ end.should =~ /inside foo/
156
+ end
157
+
158
+ it "uses padding in next status" do
159
+ capture(:stdout) do
160
+ runner.inside("foo", :verbose => true) do
161
+ runner.say_status :cool, :padding
162
+ end
163
+ end.should =~ /cool padding/
164
+ end
165
+
166
+ it "removes padding after block" do
167
+ capture(:stdout) do
168
+ runner.inside("foo", :verbose => true) {}
169
+ runner.say_status :no, :padding
170
+ end.should =~ /no padding/
171
+ end
172
+ end
173
+ end
174
+
175
+ describe "#in_root" do
176
+ it "executes the block in the root folder" do
177
+ runner.inside("foo") do
178
+ runner.in_root { Dir.pwd.should == destination_root }
179
+ end
180
+ end
181
+
182
+ it "changes the base root" do
183
+ runner.inside("foo") do
184
+ runner.in_root { runner.destination_root.should == destination_root }
185
+ end
186
+ end
187
+
188
+ it "returns to the previous state" do
189
+ runner.inside("foo") do
190
+ runner.in_root { }
191
+ runner.destination_root.should == file
192
+ end
193
+ end
194
+ end
195
+
196
+ describe "#apply" do
197
+ before(:each) do
198
+ @template = <<-TEMPLATE
199
+ @foo = "FOO"
200
+ say_status :cool, :padding
201
+ TEMPLATE
202
+ @template.stub(:read).and_return(@template)
203
+
204
+ @file = '/'
205
+ runner.stub(:open).and_return(@template)
206
+ end
207
+
208
+ it "accepts a URL as the path" do
209
+ @file = "http://gist.github.com/103208.txt"
210
+ runner.should_receive(:open).with(@file, "Accept" => "application/x-thor-template").and_return(@template)
211
+ action(:apply, @file)
212
+ end
213
+
214
+ it "accepts a secure URL as the path" do
215
+ @file = "https://gist.github.com/103208.txt"
216
+ runner.should_receive(:open).with(@file, "Accept" => "application/x-thor-template").and_return(@template)
217
+ action(:apply, @file)
218
+ end
219
+
220
+ it "accepts a local file path with spaces" do
221
+ @file = File.expand_path("fixtures/path with spaces", File.dirname(__FILE__))
222
+ runner.should_receive(:open).with(@file).and_return(@template)
223
+ action(:apply, @file)
224
+ end
225
+
226
+ it "opens a file and executes its content in the instance binding" do
227
+ action :apply, @file
228
+ runner.instance_variable_get("@foo").should == "FOO"
229
+ end
230
+
231
+ it "applies padding to the content inside the file" do
232
+ action(:apply, @file).should =~ /cool padding/
233
+ end
234
+
235
+ it "logs its status" do
236
+ action(:apply, @file).should =~ / apply #{@file}\n/
237
+ end
238
+
239
+ it "does not log status" do
240
+ content = action(:apply, @file, :verbose => false)
241
+ content.should =~ /cool padding/
242
+ content.should_not =~ /apply http/
243
+ end
244
+ end
245
+
246
+ describe "#run" do
247
+ before(:each) do
248
+ runner.should_receive(:system).with("ls")
249
+ end
250
+
251
+ it "executes the command given" do
252
+ action :run, "ls"
253
+ end
254
+
255
+ it "logs status" do
256
+ action(:run, "ls").should == " run ls from \".\"\n"
257
+ end
258
+
259
+ it "does not log status if required" do
260
+ action(:run, "ls", :verbose => false).should be_empty
261
+ end
262
+
263
+ it "accepts a color as status" do
264
+ runner.shell.should_receive(:say_status).with(:run, 'ls from "."', :yellow)
265
+ action :run, "ls", :verbose => :yellow
266
+ end
267
+ end
268
+
269
+ describe "#run_ruby_script" do
270
+ before(:each) do
271
+ Thor::Util.stub!(:ruby_command).and_return("/opt/jruby")
272
+ runner.should_receive(:system).with("/opt/jruby script.rb")
273
+ end
274
+
275
+ it "executes the ruby script" do
276
+ action :run_ruby_script, "script.rb"
277
+ end
278
+
279
+ it "logs status" do
280
+ action(:run_ruby_script, "script.rb").should == " run jruby script.rb from \".\"\n"
281
+ end
282
+
283
+ it "does not log status if required" do
284
+ action(:run_ruby_script, "script.rb", :verbose => false).should be_empty
285
+ end
286
+ end
287
+
288
+ describe "#thor" do
289
+ it "executes the thor command" do
290
+ runner.should_receive(:system).with("thor list")
291
+ action :thor, :list, :verbose => true
292
+ end
293
+
294
+ it "converts extra arguments to command arguments" do
295
+ runner.should_receive(:system).with("thor list foo bar")
296
+ action :thor, :list, "foo", "bar"
297
+ end
298
+
299
+ it "converts options hash to switches" do
300
+ runner.should_receive(:system).with("thor list foo bar --foo")
301
+ action :thor, :list, "foo", "bar", :foo => true
302
+
303
+ runner.should_receive(:system).with("thor list --foo 1 2 3")
304
+ action :thor, :list, :foo => [1,2,3]
305
+ end
306
+
307
+ it "logs status" do
308
+ runner.should_receive(:system).with("thor list")
309
+ action(:thor, :list).should == " run thor list from \".\"\n"
310
+ end
311
+
312
+ it "does not log status if required" do
313
+ runner.should_receive(:system).with("thor list --foo 1 2 3")
314
+ action(:thor, :list, :foo => [1,2,3], :verbose => false).should be_empty
315
+ end
316
+
317
+ it "captures the output when :capture is given" do
318
+ runner.should_receive(:`).with("thor foo bar")
319
+ action(:thor, "foo", "bar", :capture => true)
320
+ end
321
+ end
322
+ end