rspec-core 2.0.0.rc → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -16,7 +16,7 @@ module RSpec
16
16
  @example_group_class, @options, @example_block = example_group_class, options, example_block
17
17
  @metadata = @example_group_class.metadata.for_example(desc, options)
18
18
  @exception = nil
19
- @pending_declared_in_example = @in_block = false
19
+ @pending_declared_in_example = false
20
20
  end
21
21
 
22
22
  def example_group
@@ -28,10 +28,6 @@ module RSpec
28
28
  example_group
29
29
  end
30
30
 
31
- def in_block?
32
- @in_block
33
- end
34
-
35
31
  def pending?
36
32
  !!pending
37
33
  end
@@ -48,12 +44,10 @@ module RSpec
48
44
  with_around_hooks do
49
45
  begin
50
46
  run_before_each
51
- @in_block = true
52
47
  @example_group_instance.instance_eval(&@example_block)
53
48
  rescue Exception => e
54
49
  set_exception(e)
55
50
  ensure
56
- @in_block = false
57
51
  run_after_each
58
52
  end
59
53
  end
@@ -159,12 +159,14 @@ module RSpec
159
159
  end
160
160
 
161
161
  def self.store_before_all_ivars(example_group_instance)
162
+ return if example_group_instance.instance_variables.empty?
162
163
  example_group_instance.instance_variables.each { |ivar|
163
164
  before_all_ivars[ivar] = example_group_instance.instance_variable_get(ivar)
164
165
  }
165
166
  end
166
167
 
167
168
  def self.assign_before_all_ivars(ivars, example_group_instance)
169
+ return if ivars.empty?
168
170
  ivars.each { |ivar, val| example_group_instance.instance_variable_set(ivar, val) }
169
171
  end
170
172
 
@@ -196,7 +198,20 @@ module RSpec
196
198
  def self.eval_after_alls(example_group_instance)
197
199
  return if descendant_filtered_examples.empty?
198
200
  assign_before_all_ivars(before_all_ivars, example_group_instance)
199
- run_hook!(:after, :all, example_group_instance)
201
+
202
+ begin
203
+ run_hook!(:after, :all, example_group_instance)
204
+ rescue => e
205
+ # TODO: come up with a better solution for this.
206
+ RSpec.configuration.reporter.message <<-EOS
207
+
208
+ An error occurred in an after(:all) hook.
209
+ #{e.class}: #{e.message}
210
+ occurred at #{e.backtrace.first}
211
+
212
+ EOS
213
+ end
214
+
200
215
  world.run_hook_filtered(:after, :all, self, example_group_instance) if top_level?
201
216
  end
202
217
 
@@ -209,7 +224,6 @@ module RSpec
209
224
  RSpec.clear_remaining_example_groups if top_level?
210
225
  return
211
226
  end
212
- @reporter = reporter
213
227
  example_group_instance = new
214
228
  reporter.example_group_started(self)
215
229
 
@@ -289,6 +303,7 @@ module RSpec
289
303
  begin
290
304
  instance_eval(&hook)
291
305
  rescue Exception => e
306
+ raise unless example
292
307
  example.set_exception(e)
293
308
  end
294
309
  end
@@ -5,7 +5,7 @@ module RSpec
5
5
  class Hook
6
6
  attr_reader :options
7
7
 
8
- def initialize(options, block)
8
+ def initialize(options, &block)
9
9
  @options = options
10
10
  @block = block
11
11
  end
@@ -85,16 +85,19 @@ module RSpec
85
85
  }
86
86
  end
87
87
 
88
- def before(scope=:each, options={}, &block)
89
- hooks[:before][scope] << BeforeHook.new(options, block)
88
+ def before(*args, &block)
89
+ scope, options = scope_and_options_from(*args)
90
+ hooks[:before][scope] << BeforeHook.new(options, &block)
90
91
  end
91
92
 
92
- def after(scope=:each, options={}, &block)
93
- hooks[:after][scope] << AfterHook.new(options, block)
93
+ def after(*args, &block)
94
+ scope, options = scope_and_options_from(*args)
95
+ hooks[:after][scope] << AfterHook.new(options, &block)
94
96
  end
95
97
 
96
- def around(scope=:each, options={}, &block)
97
- hooks[:around][scope] << AroundHook.new(options, block)
98
+ def around(*args, &block)
99
+ scope, options = scope_and_options_from(*args)
100
+ hooks[:around][scope] << AroundHook.new(options, &block)
98
101
  end
99
102
 
100
103
  # Runs all of the blocks stored with the hook in the context of the
@@ -116,6 +119,16 @@ module RSpec
116
119
  def find_hook(hook, scope, example_group_class)
117
120
  hooks[hook][scope].find_hooks_for(example_group_class)
118
121
  end
122
+
123
+ private
124
+
125
+ def scope_and_options_from(scope=:each, options={})
126
+ if Hash === scope
127
+ options = scope
128
+ scope = :each
129
+ end
130
+ return scope, options
131
+ end
119
132
  end
120
133
  end
121
134
  end
@@ -52,7 +52,7 @@ module RSpec::Core
52
52
  end
53
53
 
54
54
  parser.on('-o', '--out FILE', 'output to a file instead of STDOUT') do |o|
55
- options[:output_stream] = o
55
+ options[:output_stream] = File.open(o,'w')
56
56
  end
57
57
 
58
58
  parser.on_tail('-h', '--help', "You're looking at it.") do
@@ -95,6 +95,10 @@ module RSpec::Core
95
95
  parser.on('--drb-port [PORT]', 'Port to connect to on the DRb server') do |o|
96
96
  options[:drb_port] = o.to_i
97
97
  end
98
+
99
+ parser.on('--autotest') do |o|
100
+ options[:autotest] = true
101
+ end
98
102
  end
99
103
  end
100
104
  end
@@ -73,6 +73,12 @@ module RSpec
73
73
  # nil
74
74
  attr_accessor :ruby_opts
75
75
 
76
+ # Path to rspec
77
+ #
78
+ # default:
79
+ # 'rspec'
80
+ attr_accessor :rspec_path
81
+
76
82
  # Command line options to pass to rspec.
77
83
  #
78
84
  # default:
@@ -93,8 +99,9 @@ module RSpec
93
99
 
94
100
  yield self if block_given?
95
101
 
96
- @rcov_path ||= 'rcov'
97
- @pattern ||= './spec/**/*_spec.rb'
102
+ @rcov_path ||= 'rcov'
103
+ @rspec_path ||= 'rspec'
104
+ @pattern ||= './spec/**/*_spec.rb'
98
105
 
99
106
  desc("Run RSpec code examples") unless ::Rake.application.last_comment
100
107
 
@@ -117,7 +124,11 @@ module RSpec
117
124
  private
118
125
 
119
126
  def files_to_run # :nodoc:
120
- FileList[ pattern ].map { |f| %["#{f}"] }
127
+ if ENV['SPEC']
128
+ FileList[ ENV['SPEC'] ]
129
+ else
130
+ FileList[ pattern ].map { |f| %["#{f}"] }
131
+ end
121
132
  end
122
133
 
123
134
  def spec_command
@@ -127,8 +138,15 @@ module RSpec
127
138
  cmd_parts << "-S"
128
139
  cmd_parts << "bundle exec" if bundler?
129
140
  cmd_parts << runner
130
- cmd_parts << runner_options
141
+ if rcov
142
+ cmd_parts << ["-Ispec", rcov_opts]
143
+ else
144
+ cmd_parts << rspec_opts
145
+ end
131
146
  cmd_parts << files_to_run
147
+ if rcov && rspec_opts
148
+ cmd_parts << ["--", rspec_opts]
149
+ end
132
150
  cmd_parts.flatten.compact.reject(&blank).join(" ")
133
151
  end
134
152
  end
@@ -136,11 +154,7 @@ module RSpec
136
154
  private
137
155
 
138
156
  def runner
139
- rcov ? rcov_path : 'rspec'
140
- end
141
-
142
- def runner_options
143
- rcov ? [rcov_opts] : [rspec_opts]
157
+ rcov ? rcov_path : rspec_path
144
158
  end
145
159
 
146
160
  def bundler?
@@ -1,7 +1,7 @@
1
1
  module RSpec # :nodoc:
2
2
  module Core # :nodoc:
3
3
  module Version # :nodoc:
4
- STRING = '2.0.0.rc'
4
+ STRING = '2.0.0'
5
5
  end
6
6
  end
7
7
  end
@@ -5,17 +5,16 @@ describe "failed_results_re for autotest" do
5
5
  let(:formatter) { RSpec::Core::Formatters::BaseTextFormatter.new(output) }
6
6
  let(:example_output) do
7
7
  group = RSpec::Core::ExampleGroup.describe("group name")
8
- example = group.example("example name") { "this".should eq("that") }
8
+ group.example("example name") { "this".should eq("that") }
9
9
  group.run(formatter)
10
10
  RSpec.configuration.stub(:color_enabled?) { false }
11
11
  formatter.dump_failures
12
12
  output.string
13
13
  end
14
-
15
- it "should match a failure" do
14
+
15
+ it "matches a failure" do
16
16
  re = Autotest::Rspec2.new.failed_results_re
17
- re =~ example_output
18
- $1.should == "group name example name\n Failure/Error: example = group.example(\"example name\") { \"this\".should eq(\"that\") }"
19
- $2.should == __FILE__.sub(File.expand_path('.'),'.')
17
+ example_output.should =~ re
18
+ example_output[re, 2].should == __FILE__.sub(File.expand_path('.'),'.')
20
19
  end
21
20
  end
@@ -66,39 +66,32 @@ describe Autotest::Rspec2 do
66
66
  end
67
67
 
68
68
  describe "consolidating failures" do
69
- before do
70
- @spec_file = "spec/autotest/some_spec.rb"
71
- rspec_autotest.instance_variable_set("@files", {@spec_file => Time.now})
72
- rspec_autotest.stub!(:find_files_to_test).and_return true
73
- end
69
+ let(:subject_file) { "lib/autotest/some.rb" }
70
+ let(:spec_file) { "spec/autotest/some_spec.rb" }
74
71
 
75
72
  it "returns no failures if no failures were given in the output" do
76
73
  rspec_autotest.consolidate_failures([[]]).should == {}
77
74
  end
78
75
 
79
76
  it "returns a hash with the spec filename => spec name for each failure or error" do
80
- rspec_autotest.stub!(:test_files_for).and_return "spec/autotest/some_spec.rb"
81
- failures = [
82
- [
83
- "false should be false",
84
- "#{@spec_file}"
85
- ]
86
- ]
77
+ failures = [ [ "false should be false", spec_file ] ]
87
78
  rspec_autotest.consolidate_failures(failures).should == {
88
- @spec_file => ["false should be false"]
79
+ spec_file => ["false should be false"]
89
80
  }
90
81
  end
91
82
 
92
- it "does not include the subject file" do
93
- subject_file = "lib/autotest/some.rb"
94
- rspec_autotest.stub!(:test_files_for).and_return "spec/autotest/some_spec.rb"
95
- failures = [
96
- [
97
- "false should be false",
98
- "expected: true,\n got: false (using ==)\n#{subject_file}:143:\n#{@spec_file}:203:"
99
- ]
100
- ]
101
- rspec_autotest.consolidate_failures(failures).keys.should_not include(subject_file)
83
+ context "when subject file appears before the spec file in the backtrace" do
84
+ let(:failures) do
85
+ [ [ "false should be false", "#{subject_file}:143:\n#{spec_file}:203:" ] ]
86
+ end
87
+
88
+ it "excludes the subject file" do
89
+ rspec_autotest.consolidate_failures(failures).keys.should_not include(subject_file)
90
+ end
91
+
92
+ it "includes the spec file" do
93
+ rspec_autotest.consolidate_failures(failures).keys.should include(spec_file)
94
+ end
102
95
  end
103
96
  end
104
97
 
@@ -116,16 +109,14 @@ describe Autotest::Rspec2 do
116
109
  context "using bundler" do
117
110
  it "returns 'bundle exec'" do
118
111
  File.stub(:exists?).with("./Gemfile") { true }
119
- rspec_autotest.ruby.should eq("bundle exec")
112
+ rspec_autotest.make_test_cmd({'a' => 'b'}).should =~ /bundle exec .*ruby/
120
113
  end
121
114
  end
122
115
 
123
116
  context "not using bundler" do
124
117
  it "returns the ruby command generated by Autotest" do
125
- autotest = Autotest.new
126
- autotest_ruby_command = autotest.ruby
127
118
  File.stub(:exists?).with("./Gemfile") { false }
128
- rspec_autotest.ruby.should eq(autotest_ruby_command)
119
+ rspec_autotest.make_test_cmd({'a' => 'b'}).should_not =~ /bundle exec/
129
120
  end
130
121
  end
131
122
  end
@@ -39,20 +39,29 @@ module RSpec::Core
39
39
  RSpec::Core::Configuration.new
40
40
  end
41
41
 
42
+ let(:err) { ::StringIO.new }
42
43
  let(:out) { ::StringIO.new }
43
44
 
44
45
  before do
45
46
  config.stub(:run_hook)
46
47
  end
47
48
 
49
+ it "configures streams before command line options" do
50
+ # this is necessary to ensure that color works correctly on windows
51
+ config.should_receive(:error_stream=).ordered
52
+ config.should_receive(:output_stream=).ordered
53
+ config.should_receive(:color_enabled=).ordered
54
+ command_line.run(err, out) rescue nil
55
+ end
56
+
48
57
  it "runs before suite hooks" do
49
58
  config.should_receive(:run_hook).with(:before, :suite)
50
- command_line.run(out, out)
59
+ command_line.run(err, out)
51
60
  end
52
61
 
53
62
  it "runs after suite hooks" do
54
63
  config.should_receive(:run_hook).with(:after, :suite)
55
- command_line.run(out, out)
64
+ command_line.run(err, out)
56
65
  end
57
66
 
58
67
  it "runs after suite hooks even after an error" do
@@ -66,10 +75,11 @@ module RSpec::Core
66
75
  end
67
76
  end
68
77
  expect do
69
- command_line.run(out, out)
78
+ command_line.run(err, out)
70
79
  end.to raise_error
71
80
  after_suite_called.should be_true
72
81
  end
82
+
73
83
  end
74
84
 
75
85
  describe "#run with custom output" do
@@ -204,9 +204,41 @@ module RSpec::Core
204
204
 
205
205
  describe "#color_enabled=" do
206
206
  context "given true" do
207
+ context "with non-tty output and no autotest" do
208
+ it "does not set color_enabled" do
209
+ config.output_stream = StringIO.new
210
+ config.output_stream.stub(:tty?) { false }
211
+ config.autotest = false
212
+ config.color_enabled = true
213
+ config.color_enabled.should be_false
214
+ end
215
+ end
216
+
217
+ context "with tty output" do
218
+ it "does not set color_enabled" do
219
+ config.output_stream = StringIO.new
220
+ config.output_stream.stub(:tty?) { true }
221
+ config.autotest = false
222
+ config.color_enabled = true
223
+ config.color_enabled.should be_true
224
+ end
225
+ end
226
+
227
+ context "with autotest output" do
228
+ it "does not set color_enabled" do
229
+ config.output_stream = StringIO.new
230
+ config.output_stream.stub(:tty?) { false }
231
+ config.autotest = true
232
+ config.color_enabled = true
233
+ config.color_enabled.should be_true
234
+ end
235
+ end
236
+
207
237
  context "on windows" do
208
238
  before do
209
239
  @original_host = RbConfig::CONFIG['host_os']
240
+ @original_stdout = $stdout
241
+ @original_stderr = $stderr
210
242
  RbConfig::CONFIG['host_os'] = 'mswin'
211
243
  config.stub(:require)
212
244
  config.stub(:warn)
@@ -214,6 +246,8 @@ module RSpec::Core
214
246
 
215
247
  after do
216
248
  RbConfig::CONFIG['host_os'] = @original_host
249
+ $stdout = @original_stdout
250
+ $stderr = @original_stderr
217
251
  end
218
252
 
219
253
  context "with win32console available" do
@@ -223,14 +257,48 @@ module RSpec::Core
223
257
  config.color_enabled = true
224
258
  end
225
259
 
226
- it "leaves output stream intact" do
227
- config.output_stream = $stdout
228
- config.stub(:require) do |what|
229
- config.output_stream = 'foo' if what =~ /Win32/
260
+ context "with $stdout/err assigned to config.output/error_stream" do
261
+ it "reassigns new $stdout to output_stream" do
262
+ config.output_stream = $stdout
263
+ substitute_stdout = StringIO.new
264
+ config.stub(:require) do |what|
265
+ $stdout = substitute_stdout if what =~ /Win32/
266
+ end
267
+ config.color_enabled = true
268
+ config.output_stream.should eq(substitute_stdout)
269
+ end
270
+
271
+ it "reassigns new $stderr to error_stream" do
272
+ config.error_stream = $stderr
273
+ substitute_stderr = StringIO.new
274
+ config.stub(:require) do |what|
275
+ $stderr = substitute_stderr if what =~ /Win32/
276
+ end
277
+ config.color_enabled = true
278
+ config.error_stream.should eq(substitute_stderr)
230
279
  end
231
- config.color_enabled = true
232
- config.output_stream.should eq($stdout)
233
280
  end
281
+
282
+ context "without $stdout/err assigned to config.output/error_stream" do
283
+ it "leaves output stream intact" do
284
+ config.output_stream = output_stream = StringIO.new
285
+ config.stub(:require) do |what|
286
+ $stdout = StringIO.new if what =~ /Win32/
287
+ end
288
+ config.color_enabled = true
289
+ config.output_stream.should eq(output_stream)
290
+ end
291
+
292
+ it "leaves error stream intact" do
293
+ config.error_stream = error_stream = StringIO.new
294
+ config.stub(:require) do |what|
295
+ $stderr = StringIO.new if what =~ /Win32/
296
+ end
297
+ config.color_enabled = true
298
+ config.error_stream.should eq(error_stream)
299
+ end
300
+ end
301
+
234
302
  end
235
303
 
236
304
  context "with win32console NOT available" do