rspec-core 2.9.0 → 2.10.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +4 -1
- data/Changelog.md +20 -0
- data/README.md +10 -4
- data/features/command_line/format_option.feature +1 -1
- data/features/expectation_framework_integration/configure_expectation_framework.feature +20 -7
- data/features/hooks/around_hooks.feature +1 -1
- data/features/hooks/before_and_after_hooks.feature +5 -5
- data/features/hooks/filtering.feature +2 -2
- data/features/pending/pending_examples.feature +2 -2
- data/lib/rspec/core/configuration_options.rb +4 -3
- data/lib/rspec/core/example.rb +37 -22
- data/lib/rspec/core/example_group.rb +18 -20
- data/lib/rspec/core/formatters/base_formatter.rb +2 -8
- data/lib/rspec/core/formatters/base_text_formatter.rb +13 -4
- data/lib/rspec/core/hooks.rb +120 -77
- data/lib/rspec/core/let.rb +14 -6
- data/lib/rspec/core/metadata.rb +10 -2
- data/lib/rspec/core/subject.rb +34 -13
- data/lib/rspec/core/version.rb +1 -1
- data/lib/rspec/core/world.rb +0 -4
- data/spec/rspec/core/configuration_options_spec.rb +8 -2
- data/spec/rspec/core/drb_options_spec.rb +1 -1
- data/spec/rspec/core/example_group_spec.rb +2 -2
- data/spec/rspec/core/example_spec.rb +39 -16
- data/spec/rspec/core/formatters/base_text_formatter_spec.rb +17 -7
- data/spec/rspec/core/hooks_spec.rb +117 -10
- data/spec/rspec/core/metadata_spec.rb +13 -3
- data/spec/rspec/core/pending_example_spec.rb +3 -2
- data/spec/rspec/core/subject_spec.rb +2 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/support/config_options_helper.rb +0 -3
- data/spec/support/helper_methods.rb +5 -0
- metadata +153 -142
data/.yardopts
CHANGED
data/Changelog.md
CHANGED
@@ -1,3 +1,23 @@
|
|
1
|
+
### 2.10.0 / 2012-05-03
|
2
|
+
[full changelog](http://github.com/rspec/rspec-core/compare/v2.9.0...v2.10.0)
|
3
|
+
|
4
|
+
Enhancements
|
5
|
+
|
6
|
+
* Add `prepend_before` and `append_after` hooks (preethiramdev)
|
7
|
+
* intended for extension libs
|
8
|
+
* restores rspec-1 behavior
|
9
|
+
* Reporting of profiled examples (moro)
|
10
|
+
* Report the total amount of time taken for the top slowest examples.
|
11
|
+
* Report what percentage the slowest examples took from the total runtime.
|
12
|
+
|
13
|
+
Bug fixes
|
14
|
+
|
15
|
+
* Properly parse `SPEC_OPTS` options.
|
16
|
+
* `example.description` returns the location of the example if there is no
|
17
|
+
explicit description or matcher-generated description.
|
18
|
+
* RDoc fixes (Grzegorz Świrski)
|
19
|
+
* Do not modify example ancestry when dumping errors (Michael Grosser)
|
20
|
+
|
1
21
|
### 2.9.0 / 2012-03-17
|
2
22
|
[full changelog](http://github.com/rspec/rspec-core/compare/v2.8.0...v2.9.0)
|
3
23
|
|
data/README.md
CHANGED
@@ -154,11 +154,17 @@ end
|
|
154
154
|
When you install the rspec-core gem, it installs the `rspec` executable,
|
155
155
|
which you'll use to run rspec. The `rspec` comes with many useful options.
|
156
156
|
Run `rspec --help` to see the complete list.
|
157
|
-
## see also
|
158
157
|
|
159
|
-
|
160
|
-
|
161
|
-
|
158
|
+
## store command line options `.rspec`
|
159
|
+
|
160
|
+
You can store command line options in a `.rspec` file in the project's root
|
161
|
+
directory, and the `rspec` command will read them as though you typed them on
|
162
|
+
the command line.
|
163
|
+
|
164
|
+
## autotest integration
|
165
|
+
|
166
|
+
rspec-core ships with an Autotest extension, which is loaded automatically if
|
167
|
+
there is a `.rspec` file in the project's root directory.
|
162
168
|
|
163
169
|
## get started
|
164
170
|
|
@@ -29,7 +29,7 @@ Feature: configure expectation framework
|
|
29
29
|
When I run `rspec example_spec.rb`
|
30
30
|
Then the examples should all pass
|
31
31
|
|
32
|
-
Scenario: configure test/unit assertions
|
32
|
+
Scenario: configure test/unit assertions (passing examples)
|
33
33
|
Given a file named "example_spec.rb" with:
|
34
34
|
"""
|
35
35
|
RSpec.configure do |config|
|
@@ -45,12 +45,25 @@ Feature: configure expectation framework
|
|
45
45
|
end
|
46
46
|
"""
|
47
47
|
When I run `rspec example_spec.rb`
|
48
|
-
Then the output should contain "2 examples,
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
48
|
+
Then the output should contain "2 examples, 0 failures"
|
49
|
+
|
50
|
+
Scenario: configure test/unit assertions (failing examples)
|
51
|
+
Given a file named "example_spec.rb" with:
|
52
|
+
"""
|
53
|
+
RSpec.configure do |config|
|
54
|
+
config.expect_with :stdlib
|
55
|
+
end
|
56
|
+
|
57
|
+
describe 5 do
|
58
|
+
it "is greater than 6 (no it isn't!)" do
|
59
|
+
assert 5 > 6, "errantly expected 5 to be greater than 5"
|
60
|
+
end
|
61
|
+
|
62
|
+
specify { assert 5 > 6 }
|
63
|
+
end
|
64
|
+
"""
|
65
|
+
When I run `rspec example_spec.rb`
|
66
|
+
Then the output should contain "2 examples, 2 failures"
|
54
67
|
|
55
68
|
Scenario: configure rspec/expecations AND test/unit assertions
|
56
69
|
Given a file named "example_spec.rb" with:
|
@@ -227,7 +227,7 @@ Feature: before and after hooks
|
|
227
227
|
end
|
228
228
|
end
|
229
229
|
"""
|
230
|
-
When I run `rspec ensure_block_order_spec.rb`
|
230
|
+
When I run `rspec --format progress ensure_block_order_spec.rb`
|
231
231
|
Then the output should contain:
|
232
232
|
"""
|
233
233
|
before all
|
@@ -272,7 +272,7 @@ Feature: before and after hooks
|
|
272
272
|
end
|
273
273
|
end
|
274
274
|
"""
|
275
|
-
When I run `rspec configuration_spec.rb`
|
275
|
+
When I run `rspec --format progress configuration_spec.rb`
|
276
276
|
Then the output should contain:
|
277
277
|
"""
|
278
278
|
before suite
|
@@ -313,7 +313,7 @@ Feature: before and after hooks
|
|
313
313
|
|
314
314
|
end
|
315
315
|
"""
|
316
|
-
When I run `rspec before_and_after_all_spec.rb`
|
316
|
+
When I run `rspec --format progress before_and_after_all_spec.rb`
|
317
317
|
Then the examples should all pass
|
318
318
|
And the output should contain:
|
319
319
|
"""
|
@@ -323,7 +323,7 @@ Feature: before and after hooks
|
|
323
323
|
outer after all
|
324
324
|
"""
|
325
325
|
|
326
|
-
When I run `rspec before_and_after_all_spec.rb:14`
|
326
|
+
When I run `rspec --format progress before_and_after_all_spec.rb:14`
|
327
327
|
Then the examples should all pass
|
328
328
|
And the output should contain:
|
329
329
|
"""
|
@@ -333,7 +333,7 @@ Feature: before and after hooks
|
|
333
333
|
outer after all
|
334
334
|
"""
|
335
335
|
|
336
|
-
When I run `rspec before_and_after_all_spec.rb:6`
|
336
|
+
When I run `rspec --format progress before_and_after_all_spec.rb:6`
|
337
337
|
Then the examples should all pass
|
338
338
|
And the output should contain:
|
339
339
|
"""
|
@@ -182,7 +182,7 @@ Feature: filters
|
|
182
182
|
end
|
183
183
|
end
|
184
184
|
"""
|
185
|
-
When I run `rspec filter_after_all_hooks_spec.rb`
|
185
|
+
When I run `rspec --format progress filter_after_all_hooks_spec.rb`
|
186
186
|
Then the examples should all pass
|
187
187
|
And the output should contain:
|
188
188
|
"""
|
@@ -216,7 +216,7 @@ Feature: filters
|
|
216
216
|
it("", :around_each) { puts "example 4" }
|
217
217
|
end
|
218
218
|
"""
|
219
|
-
When I run `rspec less_verbose_metadata_filter.rb`
|
219
|
+
When I run `rspec --format progress less_verbose_metadata_filter.rb`
|
220
220
|
Then the examples should all pass
|
221
221
|
And the output should contain:
|
222
222
|
"""
|
@@ -127,7 +127,7 @@ Feature: pending examples
|
|
127
127
|
"""
|
128
128
|
an example
|
129
129
|
checks something
|
130
|
-
|
130
|
+
example at ./pending_with_no_docstring_spec.rb:5 (PENDING: No reason given)
|
131
131
|
"""
|
132
132
|
|
133
133
|
Scenario: pending with no docstring using documentation formatter
|
@@ -149,7 +149,7 @@ Feature: pending examples
|
|
149
149
|
"""
|
150
150
|
an example
|
151
151
|
checks something
|
152
|
-
|
152
|
+
example at ./pending_with_no_docstring_spec.rb:5 (PENDING: No reason given)
|
153
153
|
"""
|
154
154
|
|
155
155
|
Scenario: conditionally pending examples
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'erb'
|
2
|
+
require 'shellwords'
|
2
3
|
|
3
4
|
module RSpec
|
4
5
|
module Core
|
@@ -16,7 +17,7 @@ module RSpec
|
|
16
17
|
config.filter_manager = filter_manager
|
17
18
|
|
18
19
|
order(options.keys, :libs, :requires, :default_path, :pattern).each do |key|
|
19
|
-
force?(key) ? config.force(key => options[key]) : config.send("#{key}=", options[key])
|
20
|
+
force?(key) ? config.force(key => options[key]) : config.send("#{key}=", options[key])
|
20
21
|
end
|
21
22
|
|
22
23
|
formatters.each {|pair| config.add_formatter(*pair) } if formatters
|
@@ -70,7 +71,7 @@ module RSpec
|
|
70
71
|
end
|
71
72
|
|
72
73
|
def env_options
|
73
|
-
ENV["SPEC_OPTS"] ? Parser.parse!(ENV["SPEC_OPTS"]
|
74
|
+
ENV["SPEC_OPTS"] ? Parser.parse!(Shellwords.split(ENV["SPEC_OPTS"])) : {}
|
74
75
|
end
|
75
76
|
|
76
77
|
def command_line_options
|
@@ -96,7 +97,7 @@ module RSpec
|
|
96
97
|
def args_from_options_file(path)
|
97
98
|
return [] unless path && File.exist?(path)
|
98
99
|
config_string = options_file_as_erb_string(path)
|
99
|
-
config_string.split(/\n+/).map {|l| l.
|
100
|
+
config_string.split(/\n+/).map {|l| l.shellsplit}.flatten
|
100
101
|
end
|
101
102
|
|
102
103
|
def options_file_as_erb_string(path)
|
data/lib/rspec/core/example.rb
CHANGED
@@ -12,12 +12,19 @@ module RSpec
|
|
12
12
|
#
|
13
13
|
# Used to define methods that delegate to this example's metadata
|
14
14
|
def self.delegate_to_metadata(*keys)
|
15
|
-
keys.each
|
16
|
-
define_method(key) {@metadata[key]}
|
17
|
-
end
|
15
|
+
keys.each { |key| define_method(key) { @metadata[key] } }
|
18
16
|
end
|
19
17
|
|
20
|
-
delegate_to_metadata :
|
18
|
+
delegate_to_metadata :full_description, :execution_result, :file_path, :pending, :location
|
19
|
+
|
20
|
+
# Returns the string submitted to `example` or its aliases (e.g.
|
21
|
+
# `specify`, `it`, etc). If no string is submitted (e.g. `it { should
|
22
|
+
# do_something }`) it returns the message generated by the matcher if
|
23
|
+
# there is one, otherwise returns a message including the location of the
|
24
|
+
# example.
|
25
|
+
def description
|
26
|
+
metadata[:description].to_s.empty? ? "example at #{location}" : metadata[:description]
|
27
|
+
end
|
21
28
|
|
22
29
|
# @attr_reader
|
23
30
|
#
|
@@ -74,7 +81,7 @@ module RSpec
|
|
74
81
|
|
75
82
|
begin
|
76
83
|
unless pending
|
77
|
-
|
84
|
+
with_around_each_hooks do
|
78
85
|
begin
|
79
86
|
run_before_each
|
80
87
|
@example_group_instance.instance_eval(&@example_block)
|
@@ -110,7 +117,7 @@ module RSpec
|
|
110
117
|
# Wraps the example block in a Proc so it can invoked using `run` or
|
111
118
|
# `call` in [around](../Hooks#around-instance_method) hooks.
|
112
119
|
def self.procsy(metadata, &proc)
|
113
|
-
|
120
|
+
proc.extend(Procsy).with(metadata)
|
114
121
|
end
|
115
122
|
|
116
123
|
# @private
|
@@ -144,8 +151,8 @@ module RSpec
|
|
144
151
|
end
|
145
152
|
|
146
153
|
# @private
|
147
|
-
def
|
148
|
-
@
|
154
|
+
def around_each_hooks
|
155
|
+
@around_each_hooks ||= example_group.around_each_hooks_for(self)
|
149
156
|
end
|
150
157
|
|
151
158
|
# @private
|
@@ -166,13 +173,28 @@ module RSpec
|
|
166
173
|
finish(reporter)
|
167
174
|
end
|
168
175
|
|
176
|
+
# @private
|
177
|
+
def instance_eval(&block)
|
178
|
+
@example_group_instance.instance_eval(&block)
|
179
|
+
end
|
180
|
+
|
181
|
+
# @private
|
182
|
+
def instance_eval_with_rescue(&block)
|
183
|
+
@example_group_instance.instance_eval_with_rescue(&block)
|
184
|
+
end
|
185
|
+
|
186
|
+
# @private
|
187
|
+
def instance_eval_with_args(*args, &block)
|
188
|
+
@example_group_instance.instance_eval_with_args(*args, &block)
|
189
|
+
end
|
190
|
+
|
169
191
|
private
|
170
192
|
|
171
|
-
def
|
172
|
-
if
|
193
|
+
def with_around_each_hooks(&block)
|
194
|
+
if around_each_hooks.empty?
|
173
195
|
yield
|
174
196
|
else
|
175
|
-
@example_group_class.run_around_each_hooks(self, Example.procsy(metadata, &block))
|
197
|
+
@example_group_class.run_around_each_hooks(self, Example.procsy(metadata, &block))
|
176
198
|
end
|
177
199
|
end
|
178
200
|
|
@@ -225,23 +247,16 @@ module RSpec
|
|
225
247
|
end
|
226
248
|
|
227
249
|
def assign_auto_description
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
RSpec::Matchers.clear_generated_description
|
232
|
-
else
|
233
|
-
raise NotImplementedError.new(
|
234
|
-
"Generated descriptions are only supported when you use rspec-expectations. " +
|
235
|
-
"You must give every example an explicit description."
|
236
|
-
)
|
237
|
-
end
|
250
|
+
return unless RSpec.configuration.expecting_with_rspec?
|
251
|
+
if metadata[:description].empty? and !pending?
|
252
|
+
metadata[:description] = RSpec::Matchers.generated_description
|
238
253
|
end
|
254
|
+
RSpec::Matchers.clear_generated_description
|
239
255
|
end
|
240
256
|
|
241
257
|
def record(results={})
|
242
258
|
execution_result.update(results)
|
243
259
|
end
|
244
|
-
|
245
260
|
end
|
246
261
|
end
|
247
262
|
end
|
@@ -247,6 +247,19 @@ module RSpec
|
|
247
247
|
args.unshift(symbol_description) if symbol_description
|
248
248
|
@metadata = RSpec::Core::Metadata.new(superclass_metadata).process(*args)
|
249
249
|
world.configure_group(self)
|
250
|
+
[:before, :after, :around].each do |_when|
|
251
|
+
RSpec.configuration.hooks[_when][:each].each do |hook|
|
252
|
+
unless ancestors.any? {|a| a.hooks[_when][:each].include? hook }
|
253
|
+
hooks[_when][:each] << hook # each's get filtered later per example
|
254
|
+
end
|
255
|
+
end
|
256
|
+
next if _when == :around # no around(:all) hooks
|
257
|
+
RSpec.configuration.hooks[_when][:all].each do |hook|
|
258
|
+
unless ancestors.any? {|a| a.hooks[_when][:all].include? hook }
|
259
|
+
hooks[_when][:all] << hook if hook.options_apply?(self)
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
250
263
|
end
|
251
264
|
|
252
265
|
# @private
|
@@ -264,7 +277,6 @@ module RSpec
|
|
264
277
|
|
265
278
|
# @private
|
266
279
|
def self.assign_before_all_ivars(ivars, example_group_instance)
|
267
|
-
return if ivars.empty?
|
268
280
|
ivars.each { |ivar, val| example_group_instance.instance_variable_set(ivar, val) }
|
269
281
|
end
|
270
282
|
|
@@ -272,30 +284,23 @@ module RSpec
|
|
272
284
|
def self.run_before_all_hooks(example_group_instance)
|
273
285
|
return if descendant_filtered_examples.empty?
|
274
286
|
assign_before_all_ivars(superclass.before_all_ivars, example_group_instance)
|
275
|
-
|
276
|
-
run_hook!(:before, :all, example_group_instance)
|
287
|
+
run_hook(:before, :all, example_group_instance)
|
277
288
|
store_before_all_ivars(example_group_instance)
|
278
289
|
end
|
279
290
|
|
280
291
|
# @private
|
281
292
|
def self.run_around_each_hooks(example, initial_procsy)
|
282
|
-
|
283
|
-
Example.procsy(procsy.metadata) do
|
284
|
-
example.example_group_instance.instance_eval_with_args(procsy, &around_hook)
|
285
|
-
end
|
286
|
-
end
|
293
|
+
run_hook(:around, :each, example, initial_procsy)
|
287
294
|
end
|
288
295
|
|
289
296
|
# @private
|
290
297
|
def self.run_before_each_hooks(example)
|
291
|
-
|
292
|
-
ancestors.reverse.each { |ancestor| ancestor.run_hook(:before, :each, example.example_group_instance) }
|
298
|
+
run_hook(:before, :each, example)
|
293
299
|
end
|
294
300
|
|
295
301
|
# @private
|
296
302
|
def self.run_after_each_hooks(example)
|
297
|
-
|
298
|
-
world.run_hook_filtered(:after, :each, self, example.example_group_instance, example)
|
303
|
+
run_hook(:after, :each, example)
|
299
304
|
end
|
300
305
|
|
301
306
|
# @private
|
@@ -304,7 +309,7 @@ module RSpec
|
|
304
309
|
assign_before_all_ivars(before_all_ivars, example_group_instance)
|
305
310
|
|
306
311
|
begin
|
307
|
-
run_hook
|
312
|
+
run_hook(:after, :all, example_group_instance)
|
308
313
|
rescue => e
|
309
314
|
# TODO: come up with a better solution for this.
|
310
315
|
RSpec.configuration.reporter.message <<-EOS
|
@@ -315,13 +320,6 @@ An error occurred in an after(:all) hook.
|
|
315
320
|
|
316
321
|
EOS
|
317
322
|
end
|
318
|
-
|
319
|
-
world.run_hook_filtered(:after, :all, self, example_group_instance)
|
320
|
-
end
|
321
|
-
|
322
|
-
# @private
|
323
|
-
def self.around_hooks_for(example)
|
324
|
-
world.find_hook(:around, :each, self, example) + ancestors.reverse.inject([]){|l,a| l + a.find_hook(:around, :each, self, example)}
|
325
323
|
end
|
326
324
|
|
327
325
|
# Runs all the examples in this group
|
@@ -12,13 +12,6 @@ module RSpec
|
|
12
12
|
attr_reader :example_count, :pending_count, :failure_count
|
13
13
|
attr_reader :failed_examples, :pending_examples
|
14
14
|
|
15
|
-
def self.relative_path(line)
|
16
|
-
line = line.sub(File.expand_path("."), ".")
|
17
|
-
line = line.sub(/\A([^:]+:\d+)$/, '\\1')
|
18
|
-
return nil if line == '-e:1'
|
19
|
-
line
|
20
|
-
end
|
21
|
-
|
22
15
|
def initialize(output)
|
23
16
|
@output = output || StringIO.new
|
24
17
|
@example_count = @pending_count = @failure_count = 0
|
@@ -123,7 +116,7 @@ module RSpec
|
|
123
116
|
|
124
117
|
def backtrace_line(line)
|
125
118
|
return nil if configuration.cleaned_from_backtrace?(line)
|
126
|
-
|
119
|
+
RSpec::Core::Metadata::relative_path(line)
|
127
120
|
end
|
128
121
|
|
129
122
|
def read_failed_line(exception, example)
|
@@ -141,6 +134,7 @@ module RSpec
|
|
141
134
|
end
|
142
135
|
|
143
136
|
def find_failed_line(backtrace, path)
|
137
|
+
path = File.expand_path(path)
|
144
138
|
backtrace.detect { |line|
|
145
139
|
match = line.match(/(.+?):(\d+)(|:\d+)/)
|
146
140
|
match && match[1].downcase == path.downcase
|