thor 0.12.2 → 0.12.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -76,8 +76,10 @@ class Thor
76
76
  # Returns the thor classes declared inside the given class.
77
77
  #
78
78
  def self.thor_classes_in(klass)
79
+ stringfied_constants = klass.constants.map { |c| c.to_s }
79
80
  Thor::Base.subclasses.select do |subclass|
80
- klass.constants.include?(subclass.name.gsub("#{klass.name}::", ''))
81
+ next unless subclass.name
82
+ stringfied_constants.include?(subclass.name.gsub("#{klass.name}::", ''))
81
83
  end
82
84
  end
83
85
 
@@ -155,7 +157,7 @@ class Thor
155
157
  # inside the sandbox to avoid namespacing conflicts.
156
158
  #
157
159
  def self.load_thorfile(path, content=nil)
158
- content ||= File.read(path)
160
+ content ||= File.binread(path)
159
161
 
160
162
  begin
161
163
  Thor::Sandbox.class_eval(content, path)
@@ -164,26 +166,6 @@ class Thor
164
166
  end
165
167
  end
166
168
 
167
- # Receives a yaml (hash) and updates all constants entries to namespace.
168
- # This was added to deal with deprecated versions of Thor.
169
- #
170
- # TODO Deprecate this method in the future.
171
- #
172
- # ==== Returns
173
- # TrueClass|FalseClass:: Returns true if any change to the yaml file was made.
174
- #
175
- def self.convert_constants_to_namespaces(yaml)
176
- yaml_changed = false
177
-
178
- yaml.each do |k, v|
179
- next unless v[:constants] && v[:namespaces].nil?
180
- yaml_changed = true
181
- yaml[k][:namespaces] = v[:constants].map{|c| Thor::Util.namespace_from_thor_class(c)}
182
- end
183
-
184
- yaml_changed
185
- end
186
-
187
169
  def self.user_home
188
170
  @@user_home ||= if ENV["HOME"]
189
171
  ENV["HOME"]
@@ -1,3 +1,3 @@
1
1
  class Thor
2
- VERSION = "0.12.2".freeze
2
+ VERSION = "0.12.3".freeze
3
3
  end
@@ -8,7 +8,7 @@ describe Thor::Actions::CreateFile do
8
8
 
9
9
  def create_file(destination=nil, config={}, options={})
10
10
  @base = MyCounter.new([1,2], options, { :destination_root => destination_root })
11
- stub(@base).file_name { 'rdoc' }
11
+ @base.stub!(:file_name).and_return('rdoc')
12
12
 
13
13
  @action = Thor::Actions::CreateFile.new(@base, destination, "CONFIGURATION",
14
14
  { :verbose => !@silence }.merge(config))
@@ -103,7 +103,7 @@ describe Thor::Actions::CreateFile do
103
103
 
104
104
  it "shows conflict status to ther user" do
105
105
  create_file("doc/config.rb").must_not be_identical
106
- mock($stdin).gets{ 's' }
106
+ $stdin.should_receive(:gets).and_return('s')
107
107
  file = File.join(destination_root, 'doc/config.rb')
108
108
 
109
109
  content = invoke!
@@ -114,21 +114,21 @@ describe Thor::Actions::CreateFile do
114
114
 
115
115
  it "creates the file if the file collision menu returns true" do
116
116
  create_file("doc/config.rb")
117
- mock($stdin).gets{ 'y' }
117
+ $stdin.should_receive(:gets).and_return('y')
118
118
  invoke!.must =~ /force doc\/config\.rb/
119
119
  end
120
120
 
121
121
  it "skips the file if the file collision menu returns false" do
122
122
  create_file("doc/config.rb")
123
- mock($stdin).gets{ 'n' }
123
+ $stdin.should_receive(:gets).and_return('n')
124
124
  invoke!.must =~ /skip doc\/config\.rb/
125
125
  end
126
126
 
127
127
  it "executes the block given to show file content" do
128
128
  create_file("doc/config.rb")
129
- mock($stdin).gets{ 'd' }
130
- mock($stdin).gets{ 'n' }
131
- mock(@base.shell).system(/diff -u/)
129
+ $stdin.should_receive(:gets).and_return('d')
130
+ $stdin.should_receive(:gets).and_return('n')
131
+ @base.shell.should_receive(:system).with(/diff -u/)
132
132
  invoke!
133
133
  end
134
134
  end
@@ -4,7 +4,7 @@ require 'thor/actions'
4
4
  describe Thor::Actions::Directory do
5
5
  before(:each) do
6
6
  ::FileUtils.rm_rf(destination_root)
7
- stub(invoker).file_name{ "rdoc" }
7
+ invoker.stub!(:file_name).and_return("rdoc")
8
8
  end
9
9
 
10
10
  def invoker
@@ -29,23 +29,23 @@ describe Thor::Actions do
29
29
 
30
30
  describe "#chmod" do
31
31
  it "executes the command given" do
32
- mock(FileUtils).chmod_R(0755, file)
32
+ FileUtils.should_receive(:chmod_R).with(0755, file)
33
33
  action :chmod, "foo", 0755
34
34
  end
35
35
 
36
36
  it "does not execute the command if pretending given" do
37
- dont_allow(FileUtils).chmod_R(0755, file)
37
+ FileUtils.should_not_receive(:chmod_R)
38
38
  runner(:pretend => true)
39
39
  action :chmod, "foo", 0755
40
40
  end
41
41
 
42
42
  it "logs status" do
43
- mock(FileUtils).chmod_R(0755, file)
43
+ FileUtils.should_receive(:chmod_R).with(0755, file)
44
44
  action(:chmod, "foo", 0755).must == " chmod foo\n"
45
45
  end
46
46
 
47
47
  it "does not log status if required" do
48
- mock(FileUtils).chmod_R(0755, file)
48
+ FileUtils.should_receive(:chmod_R).with(0755, file)
49
49
  action(:chmod, "foo", 0755, :verbose => false).must be_empty
50
50
  end
51
51
  end
@@ -123,7 +123,7 @@ describe Thor::Actions do
123
123
  end
124
124
 
125
125
  it "converts enconded instructions" do
126
- mock(runner).file_name{ "rdoc" }
126
+ runner.should_receive(:file_name).and_return("rdoc")
127
127
  action :template, "doc/%file_name%.rb.tt"
128
128
  file = File.join(destination_root, "doc/rdoc.rb.tt")
129
129
  File.exists?(file).must be_true
@@ -179,18 +179,18 @@ describe Thor::Actions do
179
179
  describe "#gsub_file" do
180
180
  it "replaces the content in the file" do
181
181
  action :gsub_file, "doc/README", "__start__", "START"
182
- File.open(file).read.must == "START\nREADME\n__end__\n"
182
+ File.binread(file).must == "START\nREADME\n__end__\n"
183
183
  end
184
184
 
185
185
  it "does not replace if pretending" do
186
186
  runner(:pretend => true)
187
187
  action :gsub_file, "doc/README", "__start__", "START"
188
- File.open(file).read.must == "__start__\nREADME\n__end__\n"
188
+ File.binread(file).must == "__start__\nREADME\n__end__\n"
189
189
  end
190
190
 
191
191
  it "accepts a block" do
192
192
  action(:gsub_file, "doc/README", "__start__"){ |match| match.gsub('__', '').upcase }
193
- File.open(file).read.must == "START\nREADME\n__end__\n"
193
+ File.binread(file).must == "START\nREADME\n__end__\n"
194
194
  end
195
195
 
196
196
  it "logs status" do
@@ -205,12 +205,12 @@ describe Thor::Actions do
205
205
  describe "#append_file" do
206
206
  it "appends content to the file" do
207
207
  action :append_file, "doc/README", "END\n"
208
- File.open(file).read.must == "__start__\nREADME\n__end__\nEND\n"
208
+ File.binread(file).must == "__start__\nREADME\n__end__\nEND\n"
209
209
  end
210
210
 
211
211
  it "accepts a block" do
212
212
  action(:append_file, "doc/README"){ "END\n" }
213
- File.open(file).read.must == "__start__\nREADME\n__end__\nEND\n"
213
+ File.binread(file).must == "__start__\nREADME\n__end__\nEND\n"
214
214
  end
215
215
 
216
216
  it "logs status" do
@@ -221,12 +221,12 @@ describe Thor::Actions do
221
221
  describe "#prepend_file" do
222
222
  it "prepends content to the file" do
223
223
  action :prepend_file, "doc/README", "START\n"
224
- File.open(file).read.must == "START\n__start__\nREADME\n__end__\n"
224
+ File.binread(file).must == "START\n__start__\nREADME\n__end__\n"
225
225
  end
226
226
 
227
227
  it "accepts a block" do
228
228
  action(:prepend_file, "doc/README"){ "START\n" }
229
- File.open(file).read.must == "START\n__start__\nREADME\n__end__\n"
229
+ File.binread(file).must == "START\n__start__\nREADME\n__end__\n"
230
230
  end
231
231
 
232
232
  it "logs status" do
@@ -241,12 +241,12 @@ describe Thor::Actions do
241
241
 
242
242
  it "appends content to a class" do
243
243
  action :inject_into_class, "application.rb", Application, " filter_parameters :password\n"
244
- File.open(file).read.must == "class Application < Base\n filter_parameters :password\nend\n"
244
+ File.binread(file).must == "class Application < Base\n filter_parameters :password\nend\n"
245
245
  end
246
246
 
247
247
  it "accepts a block" do
248
248
  action(:inject_into_class, "application.rb", Application){ " filter_parameters :password\n" }
249
- File.open(file).read.must == "class Application < Base\n filter_parameters :password\nend\n"
249
+ File.binread(file).must == "class Application < Base\n filter_parameters :password\nend\n"
250
250
  end
251
251
 
252
252
  it "logs status" do
@@ -255,7 +255,7 @@ describe Thor::Actions do
255
255
 
256
256
  it "does not append if class name does not match" do
257
257
  action :inject_into_class, "application.rb", "App", " filter_parameters :password\n"
258
- File.open(file).read.must == "class Application < Base\nend\n"
258
+ File.binread(file).must == "class Application < Base\nend\n"
259
259
  end
260
260
  end
261
261
  end
@@ -55,9 +55,10 @@ describe Thor::Actions do
55
55
  end
56
56
 
57
57
  it "does not use the current directory if one is given" do
58
+ root = File.expand_path("/")
58
59
  base = MyCounter.new([1])
59
- base.destination_root = "/"
60
- base.destination_root.must == "/"
60
+ base.destination_root = root
61
+ base.destination_root.must == root
61
62
  end
62
63
 
63
64
  it "uses the current directory if none is given" do
@@ -194,7 +195,7 @@ describe Thor::Actions do
194
195
  @template.instance_eval "def read; self; end" # Make the string respond to read
195
196
 
196
197
  @file = "http://gist.github.com/103208.txt"
197
- mock(runner).open(@file){ @template }
198
+ runner.should_receive(:open).and_return(@template)
198
199
  end
199
200
 
200
201
  it "opens a file and executes its content in the instance binding" do
@@ -219,7 +220,7 @@ describe Thor::Actions do
219
220
 
220
221
  describe "#run" do
221
222
  before(:each) do
222
- mock(runner).system("ls")
223
+ runner.should_receive(:system).with("ls")
223
224
  end
224
225
 
225
226
  it "executes the command given" do
@@ -235,15 +236,15 @@ describe Thor::Actions do
235
236
  end
236
237
 
237
238
  it "accepts a color as status" do
238
- mock(runner.shell).say_status(:run, 'ls from "."', :yellow)
239
+ runner.shell.should_receive(:say_status).with(:run, 'ls from "."', :yellow)
239
240
  action :run, "ls", :verbose => :yellow
240
241
  end
241
242
  end
242
243
 
243
244
  describe "#run_ruby_script" do
244
245
  before(:each) do
245
- stub(Thor::Util).ruby_command{ "/opt/jruby" }
246
- mock(runner).system("/opt/jruby script.rb")
246
+ Thor::Util.stub!(:ruby_command).and_return("/opt/jruby")
247
+ runner.should_receive(:system).with("/opt/jruby script.rb")
247
248
  end
248
249
 
249
250
  it "executes the ruby script" do
@@ -261,30 +262,30 @@ describe Thor::Actions do
261
262
 
262
263
  describe "#thor" do
263
264
  it "executes the thor command" do
264
- mock(runner).system("thor list")
265
+ runner.should_receive(:system).with("thor list")
265
266
  action :thor, :list, :verbose => true
266
267
  end
267
268
 
268
269
  it "converts extra arguments to command arguments" do
269
- mock(runner).system("thor list foo bar")
270
+ runner.should_receive(:system).with("thor list foo bar")
270
271
  action :thor, :list, "foo", "bar"
271
272
  end
272
273
 
273
274
  it "converts options hash to switches" do
274
- mock(runner).system("thor list foo bar --foo")
275
+ runner.should_receive(:system).with("thor list foo bar --foo")
275
276
  action :thor, :list, "foo", "bar", :foo => true
276
277
 
277
- mock(runner).system("thor list --foo 1 2 3")
278
+ runner.should_receive(:system).with("thor list --foo 1 2 3")
278
279
  action :thor, :list, :foo => [1,2,3]
279
280
  end
280
281
 
281
282
  it "logs status" do
282
- mock(runner).system("thor list")
283
+ runner.should_receive(:system).with("thor list")
283
284
  action(:thor, :list).must == " run thor list from \".\"\n"
284
285
  end
285
286
 
286
287
  it "does not log status if required" do
287
- mock(runner).system("thor list --foo 1 2 3")
288
+ runner.should_receive(:system).with("thor list --foo 1 2 3")
288
289
  action(:thor, :list, :foo => [1,2,3], :verbose => false).must be_empty
289
290
  end
290
291
  end
@@ -29,7 +29,7 @@ describe Thor::Group do
29
29
  end
30
30
 
31
31
  it "invokes help message if any of the shortcuts is given" do
32
- stub(MyCounter).help
32
+ MyCounter.should_receive(:help)
33
33
  MyCounter.start(["-h"])
34
34
  end
35
35
  end
@@ -66,12 +66,6 @@ describe Thor::Group do
66
66
  @content.must =~ /Options/
67
67
  @content.must =~ /\[\-\-third=THREE\]/
68
68
  end
69
-
70
- it "shows only usage if a short help is required" do
71
- content = capture(:stdout){ MyCounter.help(Thor::Base.shell.new, :short => true) }
72
- content.must =~ /my_counter N \[N\]/
73
- content.must_not =~ /Options/
74
- end
75
69
  end
76
70
 
77
71
  describe "#invoke" do
@@ -26,11 +26,11 @@ describe Thor::Runner do
26
26
 
27
27
  it "shows information about a specific Thor group class" do
28
28
  content = capture(:stdout){ Thor::Runner.start(["help", "my_counter"]) }
29
- content.must =~ /my_counter N \[N\]/
29
+ content.must =~ /my_counter N/
30
30
  end
31
31
 
32
32
  it "raises error if a class/task cannot be found" do
33
- mock(Thor::Runner).exit(1)
33
+ Thor::Runner.should_receive(:exit).with(1)
34
34
  content = capture(:stderr){ Thor::Runner.start(["help", "unknown"]) }
35
35
  content.must =~ /could not find Thor class or task 'unknown'/
36
36
  end
@@ -39,7 +39,7 @@ describe Thor::Runner do
39
39
  describe "#start" do
40
40
  it "invokes a task from Thor::Runner" do
41
41
  ARGV.replace ["list"]
42
- capture(:stdout){ Thor::Runner.start }.must =~ /my_counter N \[N\]/
42
+ capture(:stdout){ Thor::Runner.start }.must =~ /my_counter N/
43
43
  end
44
44
 
45
45
  it "invokes a task from a specific Thor class" do
@@ -68,7 +68,7 @@ describe Thor::Runner do
68
68
  end
69
69
 
70
70
  it "raises an error if class/task can't be found" do
71
- mock(Thor::Runner).exit(1)
71
+ Thor::Runner.should_receive(:exit).with(1)
72
72
  ARGV.replace ["unknown"]
73
73
  capture(:stderr){ Thor::Runner.start }.must =~ /could not find Thor class or task 'unknown'/
74
74
  end
@@ -96,14 +96,16 @@ describe Thor::Runner do
96
96
  "random" => {
97
97
  :location => @location,
98
98
  :filename => "4a33b894ffce85d7b412fc1b36f88fe0",
99
- :constants => ["Amazing"]
99
+ :namespaces => ["amazing"]
100
100
  }
101
101
  }
102
102
 
103
+ root_file = File.join(Thor::Util.thor_root, "thor.yml")
104
+
103
105
  # Stub load and save to avoid thor.yaml from being overwritten
104
- stub(YAML).load_file { @original_yaml }
105
- stub(File).exists?(File.join(Thor::Util.thor_root, "thor.yml")){ true }
106
- stub(File).open(File.join(Thor::Util.thor_root, "thor.yml"), "w")
106
+ YAML.stub!(:load_file).and_return(@original_yaml)
107
+ File.stub!(:exists?).with(root_file).and_return(true)
108
+ File.stub!(:open).with(root_file, "w")
107
109
  end
108
110
 
109
111
  describe "list" do
@@ -115,7 +117,7 @@ describe Thor::Runner do
115
117
 
116
118
  it "gives a list of the available Thor::Group classes" do
117
119
  ARGV.replace ["list"]
118
- capture(:stdout) { Thor::Runner.start }.must =~ /my_counter N \[N\]/
120
+ capture(:stdout) { Thor::Runner.start }.must =~ /my_counter N/
119
121
  end
120
122
 
121
123
  it "can filter a list of the available tasks by --group" do
@@ -148,26 +150,12 @@ describe Thor::Runner do
148
150
  ARGV.replace [":test"]
149
151
  capture(:stdout) { Thor::Runner.start }.must == "test\n"
150
152
  end
151
-
152
- it "updates the yaml file when invoked" do
153
- capture(:stdout) { Thor::Runner.start(["list"]) }
154
- @original_yaml["random"][:namespaces].must == ["amazing"]
155
- end
156
- end
157
-
158
- describe "update" do
159
- it "updates existing thor files" do
160
- mock.instance_of(Thor::Runner).install(@original_yaml["random"][:location]) { true }
161
- stub(File).delete(File.join(Thor::Util.thor_root, @original_yaml["random"][:filename]))
162
- silence(:stdout) { Thor::Runner.start(["update", "random"]) }
163
- end
164
153
  end
165
154
 
166
155
  describe "uninstall" do
167
156
  before(:each) do
168
- stub.instance_of(Thor::Runner).save_yaml(anything)
169
- stub(File).delete(anything)
170
- stub(@original_yaml).delete(anything)
157
+ path = File.join(Thor::Util.thor_root, @original_yaml["random"][:filename])
158
+ FileUtils.should_receive(:rm_rf).with(path)
171
159
  end
172
160
 
173
161
  it "uninstalls existing thor modules" do
@@ -177,7 +165,7 @@ describe Thor::Runner do
177
165
 
178
166
  describe "installed" do
179
167
  before(:each) do
180
- stub(Dir).[](anything) { [] }
168
+ Dir.should_receive(:[]).and_return([])
181
169
  end
182
170
 
183
171
  it "displays the modules installed in a pretty way" do
@@ -187,16 +175,24 @@ describe Thor::Runner do
187
175
  end
188
176
  end
189
177
 
190
- describe "install" do
191
- it "installs thor files" do
192
- ARGV.replace ["install", @location]
178
+ describe "install/update" do
179
+ before(:each) do
180
+ FileUtils.stub!(:mkdir_p)
181
+ FileUtils.stub!(:touch)
182
+ $stdin.stub!(:gets).and_return("Y")
193
183
 
194
- # Stubs for the file system interactions
195
- stub.instance_of(Thor::Base.shell).no? { false }
196
- stub(FileUtils).mkdir_p
197
- stub(FileUtils).touch
184
+ path = File.join(Thor::Util.thor_root, Digest::MD5.hexdigest(@location + "random"))
185
+ File.should_receive(:open).with(path, "w")
186
+ end
198
187
 
199
- mock(File).open(File.join(Thor::Util.thor_root, Digest::MD5.hexdigest(@location + "random")), "w")
188
+ it "updates existing thor files" do
189
+ path = File.join(Thor::Util.thor_root, @original_yaml["random"][:filename])
190
+ File.should_receive(:delete).with(path)
191
+ silence(:stdout) { Thor::Runner.start(["update", "random"]) }
192
+ end
193
+
194
+ it "installs thor files" do
195
+ ARGV.replace ["install", @location]
200
196
  silence(:stdout) { Thor::Runner.start }
201
197
  end
202
198
  end