rspec-core 2.9.0 → 2.10.0
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/.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
|