thor 0.12.0 → 0.12.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/thor/task.rb CHANGED
@@ -1,11 +1,11 @@
1
1
  class Thor
2
2
  class Task < Struct.new(:name, :description, :usage, :options)
3
+ FILE_REGEXP = /^#{Regexp.escape(File.expand_path(__FILE__))}:[\w:]+ `run'$/
3
4
 
4
5
  # A dynamic task that handles method missing scenarios.
5
- #
6
6
  class Dynamic < Task
7
- def initialize(name)
8
- super(name.to_s, "A dynamically-generated task", name.to_s)
7
+ def initialize(name, options=nil)
8
+ super(name.to_s, "A dynamically-generated task", name.to_s, options)
9
9
  end
10
10
 
11
11
  def run(instance, args=[])
@@ -25,84 +25,73 @@ class Thor
25
25
  self.options = other.options.dup if other.options
26
26
  end
27
27
 
28
- def short_description
29
- description.split("\n").first if description
30
- end
31
-
32
28
  # By default, a task invokes a method in the thor class. You can change this
33
29
  # implementation to create custom tasks.
34
- #
35
30
  def run(instance, args=[])
36
31
  raise UndefinedTaskError, "the '#{name}' task of #{instance.class} is private" unless public_method?(instance)
37
32
  instance.send(name, *args)
38
33
  rescue ArgumentError => e
34
+ raise e if instance.class.respond_to?(:debugging) && instance.class.debugging
39
35
  parse_argument_error(instance, e, caller)
40
36
  rescue NoMethodError => e
37
+ raise e if instance.class.respond_to?(:debugging) && instance.class.debugging
41
38
  parse_no_method_error(instance, e)
42
39
  end
43
40
 
44
- # Returns the formatted usage. If a class is given, the class arguments are
45
- # injected in the usage.
46
- #
47
- def formatted_usage(klass=nil, namespace=false, show_options=true)
48
- formatted = if namespace.is_a?(String)
49
- "#{namespace}:"
50
- elsif klass && namespace
51
- "#{klass.namespace.gsub(/^default/,'')}:"
41
+ # Returns the formatted usage by injecting given required arguments
42
+ # and required options into the given usage.
43
+ def formatted_usage(klass, namespace=true)
44
+ namespace = klass.namespace unless namespace == false
45
+
46
+ # Add namespace
47
+ formatted = if namespace
48
+ "#{namespace.gsub(/^(default|thor:runner:)/,'')}:"
52
49
  else
53
50
  ""
54
51
  end
55
52
 
56
- formatted << formatted_arguments(klass)
57
- formatted << " #{formatted_options}" if show_options
58
- formatted.strip!
59
- formatted
60
- end
61
-
62
- # Injects the class arguments into the task usage.
63
- #
64
- def formatted_arguments(klass)
65
- if klass && !klass.arguments.empty?
53
+ # Add usage with required arguments
54
+ formatted << if klass && !klass.arguments.empty?
66
55
  usage.to_s.gsub(/^#{name}/) do |match|
67
- match << " " << klass.arguments.map{ |a| a.usage }.join(' ')
56
+ match << " " << klass.arguments.map{ |a| a.usage }.compact.join(' ')
68
57
  end
69
58
  else
70
59
  usage.to_s
71
60
  end
72
- end
73
61
 
74
- # Returns the options usage for this task.
75
- #
76
- def formatted_options
77
- @formatted_options ||= options.map{ |_, o| o.usage }.sort.join(" ")
62
+ # Add required options
63
+ formatted << " #{required_options}"
64
+
65
+ # Strip and go!
66
+ formatted.strip
78
67
  end
79
68
 
80
69
  protected
81
70
 
71
+ def required_options
72
+ @required_options ||= options.map{ |_, o| o.usage if o.required? }.compact.sort.join(" ")
73
+ end
74
+
82
75
  # Given a target, checks if this class name is not a private/protected method.
83
- #
84
76
  def public_method?(instance) #:nodoc:
85
77
  collection = instance.private_methods + instance.protected_methods
86
78
  (collection & [name.to_s, name.to_sym]).empty?
87
79
  end
88
80
 
89
- # Clean everything that comes from the Thor gempath and remove the caller.
90
- #
91
- def sans_backtrace(backtrace, caller) #:nodoc:
92
- dirname = /^#{Regexp.escape(File.dirname(__FILE__))}/
93
- saned = backtrace.reject { |frame| frame =~ dirname }
94
- saned -= caller
81
+ # For Ruby <= 1.8.7, we have to match the method name that we are trying to call.
82
+ # In Ruby >= 1.9.1, we have to match the method run in this file.
83
+ def backtrace_match?(backtrace) #:nodoc:
84
+ method_name = /`#{Regexp.escape(name.split(':').last)}'/
85
+ backtrace =~ method_name || backtrace =~ FILE_REGEXP
95
86
  end
96
87
 
97
88
  def parse_argument_error(instance, e, caller) #:nodoc:
98
- backtrace = sans_backtrace(e.backtrace, caller)
99
-
100
- if backtrace.empty? && e.message =~ /wrong number of arguments/
89
+ if e.message =~ /wrong number of arguments/ && backtrace_match?(e.backtrace.first.to_s)
101
90
  if instance.is_a?(Thor::Group)
102
91
  raise e, "'#{name}' was called incorrectly. Are you sure it has arity equals to 0?"
103
92
  else
104
93
  raise InvocationError, "'#{name}' was called incorrectly. Call as " <<
105
- "'#{formatted_usage(instance.class, true)}'"
94
+ "'#{formatted_usage(instance.class)}'"
106
95
  end
107
96
  else
108
97
  raise e
data/lib/thor/util.rb CHANGED
@@ -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"]
data/lib/thor/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class Thor
2
- VERSION = "0.12.0".freeze
2
+ VERSION = "0.12.3".freeze
3
3
  end
data/lib/thor.rb CHANGED
@@ -2,6 +2,7 @@ require 'thor/base'
2
2
  require 'thor/group'
3
3
  require 'thor/actions'
4
4
 
5
+ # TODO: Update thor to allow for git-style CLI (git bisect run)
5
6
  class Thor
6
7
  class << self
7
8
  # Sets the default task when thor is executed without an explicit task to be called.
@@ -78,14 +79,14 @@ class Thor
78
79
  @method_options
79
80
  end
80
81
 
81
- # Adds an option to the set of class options. If :for is given as option,
82
+ # Adds an option to the set of method options. If :for is given as option,
82
83
  # it allows you to change the options from a previous defined task.
83
84
  #
84
85
  # def previous_task
85
86
  # # magic
86
87
  # end
87
88
  #
88
- # method_options :foo => :bar, :for => :previous_task
89
+ # method_option :foo => :bar, :for => :previous_task
89
90
  #
90
91
  # def next_task
91
92
  # # magic
@@ -101,7 +102,6 @@ class Thor
101
102
  # :default - Default value for this argument. It cannot be required and have default values.
102
103
  # :aliases - Aliases for this option.
103
104
  # :type - The type of the argument, can be :string, :hash, :array, :numeric or :boolean.
104
- # :group - The group for this options. Use by class options to output options in different levels.
105
105
  # :banner - String to show on usage notes.
106
106
  #
107
107
  def method_option(name, options={})
@@ -140,49 +140,48 @@ class Thor
140
140
  end
141
141
  end
142
142
 
143
- # Prints help information. If a task name is given, it shows information
144
- # only about the specific task.
143
+ # Prints help information for the given task.
145
144
  #
146
145
  # ==== Parameters
147
- # meth<String>:: An optional task name to print usage information about.
146
+ # shell<Thor::Shell>
147
+ # task_name<String>
148
+ #
149
+ def task_help(shell, task_name)
150
+ task = all_tasks[task_name]
151
+ raise UndefinedTaskError, "task '#{task_name}' could not be found in namespace '#{self.namespace}'" unless task
152
+
153
+ shell.say "Usage:"
154
+ shell.say " #{banner(task)}"
155
+ shell.say
156
+ class_options_help(shell, nil => task.options.map { |_, o| o })
157
+ shell.say task.description
158
+ end
159
+
160
+ # Prints help information for this class.
148
161
  #
149
- # ==== Options
150
- # namespace:: When true, shows the namespace in the output before the usage.
151
- # skip_inherited:: When true, does not show tasks from superclass.
162
+ # ==== Parameters
163
+ # shell<Thor::Shell>
152
164
  #
153
- def help(shell, meth=nil, options={})
154
- meth, options = nil, meth if meth.is_a?(Hash)
155
-
156
- if meth
157
- task = all_tasks[meth]
158
- raise UndefinedTaskError, "task '#{meth}' could not be found in namespace '#{self.namespace}'" unless task
159
-
160
- shell.say "Usage:"
161
- shell.say " #{banner(task, options[:namespace], false)}"
162
- shell.say
163
- class_options_help(shell, "Class", :Method => task.options.map { |_, o| o })
164
- shell.say task.description
165
- else
166
- list = (options[:short] ? tasks : all_tasks).map do |_, task|
167
- item = [ banner(task, options[:namespace]) ]
168
- item << "# #{task.short_description}" if task.short_description
169
- item << " "
170
- end
171
-
172
- options[:ident] ||= 2
173
- if options[:short]
174
- shell.print_list(list, :ident => options[:ident])
175
- else
176
- shell.say "Tasks:"
177
- shell.print_list(list, :ident => options[:ident])
178
- end
165
+ def help(shell)
166
+ list = printable_tasks
167
+ Thor::Util.thor_classes_in(self).each do |klass|
168
+ list += klass.printable_tasks(false)
169
+ end
170
+ list.sort!{ |a,b| a[0] <=> b[0] }
179
171
 
180
- Thor::Util.thor_classes_in(self).each do |subclass|
181
- namespace = options[:namespace] == true || subclass.namespace.gsub(/^#{self.namespace}:/, '')
182
- subclass.help(shell, options.merge(:short => true, :namespace => namespace))
183
- end
172
+ shell.say "Tasks:"
173
+ shell.print_table(list, :ident => 2, :truncate => true)
174
+ shell.say
175
+ class_options_help(shell)
176
+ end
184
177
 
185
- class_options_help(shell, "Class") unless options[:short]
178
+ # Returns tasks ready to be printed.
179
+ def printable_tasks(all=true)
180
+ (all ? all_tasks : tasks).map do |_, task|
181
+ item = []
182
+ item << banner(task)
183
+ item << (task.description ? "# #{task.description.gsub(/\s+/m,' ')}" : "")
184
+ item
186
185
  end
187
186
  end
188
187
 
@@ -193,8 +192,9 @@ class Thor
193
192
  # the task that is going to be invoked and a boolean which indicates if
194
193
  # the namespace should be displayed as arguments.
195
194
  #
196
- def banner(task, namespace=true, show_options=true)
197
- task.formatted_usage(self, namespace, show_options)
195
+ def banner(task)
196
+ base = $thor_runner ? "thor" : File.basename($0.split(" ").first)
197
+ "#{base} #{task.formatted_usage(self, base == "thor")}"
198
198
  end
199
199
 
200
200
  def baseclass #:nodoc:
@@ -237,6 +237,6 @@ class Thor
237
237
 
238
238
  desc "help [TASK]", "Describe available tasks or one specific task"
239
239
  def help(task=nil)
240
- self.class.help(shell, task, :namespace => task && task.include?(?:))
240
+ task ? self.class.task_help(shell, task) : self.class.help(shell)
241
241
  end
242
242
  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
@@ -110,10 +110,11 @@ describe Thor::Actions::Directory do
110
110
  end
111
111
 
112
112
  it "yields a block" do
113
- invoke!("doc") do |f|
114
- %(doc/README doc/config.rb doc/rdoc.rb).must include(f)
115
- %(doc/components/).must_not include(f)
113
+ checked = false
114
+ invoke!("doc") do |content|
115
+ checked ||= !!(content =~ /FOO/)
116
116
  end
117
+ checked.must be_true
117
118
  end
118
119
  end
119
120
 
@@ -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
@@ -65,13 +65,19 @@ describe Thor::Actions do
65
65
  runner.inside("doc") do
66
66
  action :copy_file, "README"
67
67
  end
68
-
69
68
  exists_and_identical?("doc/README", "doc/README")
70
69
  end
71
70
 
72
71
  it "logs status" do
73
72
  action(:copy_file, "task.thor").must == " create task.thor\n"
74
73
  end
74
+
75
+ it "accepts a block to change output" do
76
+ action :copy_file, "task.thor" do |content|
77
+ "OMG" + content
78
+ end
79
+ File.read(File.join(destination_root, "task.thor")).must =~ /^OMG/
80
+ end
75
81
  end
76
82
 
77
83
  describe "#get" do
@@ -117,7 +123,7 @@ describe Thor::Actions do
117
123
  end
118
124
 
119
125
  it "converts enconded instructions" do
120
- mock(runner).file_name{ "rdoc" }
126
+ runner.should_receive(:file_name).and_return("rdoc")
121
127
  action :template, "doc/%file_name%.rb.tt"
122
128
  file = File.join(destination_root, "doc/rdoc.rb.tt")
123
129
  File.exists?(file).must be_true
@@ -126,6 +132,13 @@ describe Thor::Actions do
126
132
  it "logs status" do
127
133
  capture(:stdout){ runner.template("doc/config.rb") }.must == " create doc/config.rb\n"
128
134
  end
135
+
136
+ it "accepts a block to change output" do
137
+ action :template, "doc/config.rb" do |content|
138
+ "OMG" + content
139
+ end
140
+ File.read(File.join(destination_root, "doc/config.rb")).must =~ /^OMG/
141
+ end
129
142
  end
130
143
 
131
144
  describe "when changing existent files" do
@@ -166,18 +179,18 @@ describe Thor::Actions do
166
179
  describe "#gsub_file" do
167
180
  it "replaces the content in the file" do
168
181
  action :gsub_file, "doc/README", "__start__", "START"
169
- File.open(file).read.must == "START\nREADME\n__end__\n"
182
+ File.binread(file).must == "START\nREADME\n__end__\n"
170
183
  end
171
184
 
172
185
  it "does not replace if pretending" do
173
186
  runner(:pretend => true)
174
187
  action :gsub_file, "doc/README", "__start__", "START"
175
- File.open(file).read.must == "__start__\nREADME\n__end__\n"
188
+ File.binread(file).must == "__start__\nREADME\n__end__\n"
176
189
  end
177
190
 
178
191
  it "accepts a block" do
179
192
  action(:gsub_file, "doc/README", "__start__"){ |match| match.gsub('__', '').upcase }
180
- File.open(file).read.must == "START\nREADME\n__end__\n"
193
+ File.binread(file).must == "START\nREADME\n__end__\n"
181
194
  end
182
195
 
183
196
  it "logs status" do
@@ -192,12 +205,12 @@ describe Thor::Actions do
192
205
  describe "#append_file" do
193
206
  it "appends content to the file" do
194
207
  action :append_file, "doc/README", "END\n"
195
- File.open(file).read.must == "__start__\nREADME\n__end__\nEND\n"
208
+ File.binread(file).must == "__start__\nREADME\n__end__\nEND\n"
196
209
  end
197
210
 
198
211
  it "accepts a block" do
199
212
  action(:append_file, "doc/README"){ "END\n" }
200
- File.open(file).read.must == "__start__\nREADME\n__end__\nEND\n"
213
+ File.binread(file).must == "__start__\nREADME\n__end__\nEND\n"
201
214
  end
202
215
 
203
216
  it "logs status" do
@@ -208,12 +221,12 @@ describe Thor::Actions do
208
221
  describe "#prepend_file" do
209
222
  it "prepends content to the file" do
210
223
  action :prepend_file, "doc/README", "START\n"
211
- File.open(file).read.must == "START\n__start__\nREADME\n__end__\n"
224
+ File.binread(file).must == "START\n__start__\nREADME\n__end__\n"
212
225
  end
213
226
 
214
227
  it "accepts a block" do
215
228
  action(:prepend_file, "doc/README"){ "START\n" }
216
- File.open(file).read.must == "START\n__start__\nREADME\n__end__\n"
229
+ File.binread(file).must == "START\n__start__\nREADME\n__end__\n"
217
230
  end
218
231
 
219
232
  it "logs status" do
@@ -228,12 +241,12 @@ describe Thor::Actions do
228
241
 
229
242
  it "appends content to a class" do
230
243
  action :inject_into_class, "application.rb", Application, " filter_parameters :password\n"
231
- 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"
232
245
  end
233
246
 
234
247
  it "accepts a block" do
235
248
  action(:inject_into_class, "application.rb", Application){ " filter_parameters :password\n" }
236
- 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"
237
250
  end
238
251
 
239
252
  it "logs status" do
@@ -242,7 +255,7 @@ describe Thor::Actions do
242
255
 
243
256
  it "does not append if class name does not match" do
244
257
  action :inject_into_class, "application.rb", "App", " filter_parameters :password\n"
245
- File.open(file).read.must == "class Application < Base\nend\n"
258
+ File.binread(file).must == "class Application < Base\nend\n"
246
259
  end
247
260
  end
248
261
  end
data/spec/actions_spec.rb CHANGED
@@ -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
data/spec/base_spec.rb CHANGED
@@ -134,7 +134,7 @@ describe Thor::Base do
134
134
  it "allows extra options to be given" do
135
135
  hash = { "Foo" => B.class_options.values }
136
136
 
137
- content = capture(:stdout) { MyCounter.send(:class_options_help, Thor::Base.shell.new, nil, hash) }
137
+ content = capture(:stdout) { MyCounter.send(:class_options_help, Thor::Base.shell.new, hash) }
138
138
  content.must =~ /Foo options\:/
139
139
  content.must =~ /--last-name=LAST_NAME/
140
140
  end
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), 'execute')
@@ -0,0 +1 @@
1
+ FOO = <%= "FOO" %>
@@ -0,0 +1,3 @@
1
+ __start__
2
+ README
3
+ __end__