rspec-core 2.13.0 → 2.13.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Changelog.md +32 -0
- data/README.md +7 -4
- data/features/step_definitions/additional_cli_steps.rb +0 -4
- data/features/support/env.rb +10 -8
- data/lib/rspec/core/example_group.rb +5 -1
- data/lib/rspec/core/formatters/base_text_formatter.rb +1 -0
- data/lib/rspec/core/hooks.rb +15 -21
- data/lib/rspec/core/memoized_helpers.rb +83 -7
- data/lib/rspec/core/version.rb +1 -1
- data/spec/rspec/core/configuration_spec.rb +1 -1
- data/spec/rspec/core/example_spec.rb +1 -1
- data/spec/rspec/core/formatters/base_formatter_spec.rb +10 -10
- data/spec/rspec/core/hooks_spec.rb +17 -0
- data/spec/rspec/core/memoized_helpers_spec.rb +188 -4
- data/spec/rspec/core/pending_example_spec.rb +8 -8
- data/spec/rspec/core/reporter_spec.rb +2 -2
- metadata +11 -11
data/Changelog.md
CHANGED
@@ -1,3 +1,33 @@
|
|
1
|
+
### 2.13.1 / 2013-03-12
|
2
|
+
[full changelog](http://github.com/rspec/rspec-core/compare/v2.13.0...v2.13.1)
|
3
|
+
|
4
|
+
Bug fixes
|
5
|
+
|
6
|
+
* Use hook classes as proxies rather than extending hook blocks to support
|
7
|
+
lambdas for before/after/around hooks. (David Chelimsky)
|
8
|
+
* Fix regression in 2.13.0 that caused confusing behavior when overriding
|
9
|
+
a named subject with an unnamed subject in an inner group and then
|
10
|
+
referencing the outer group subject's name. The fix for this required
|
11
|
+
us to disallow using `super` in a named subject (which is confusing,
|
12
|
+
anyway -- named subjects create 2 methods, so which method on the
|
13
|
+
parent example group are you `super`ing to?) but `super` in an unnamed
|
14
|
+
subject continues to work (Myron Marston).
|
15
|
+
* Do not allow a referenced `let` or `subject` in `before(:all)` to cause
|
16
|
+
other `let` declarations to leak across examples (Myron Marston).
|
17
|
+
* Work around odd ruby 1.9 bug with `String#match` that was triggered
|
18
|
+
by passing it a regex from a `let` declaration. For more info, see
|
19
|
+
http://bugs.ruby-lang.org/issues/8059 (Aaron Kromer).
|
20
|
+
* Add missing `require 'set'` to `base_text_formatter.rb` (Tom
|
21
|
+
Anderson).
|
22
|
+
|
23
|
+
Deprecations
|
24
|
+
|
25
|
+
* Deprecate accessing `let` or `subject` declarations in `before(:all)`.
|
26
|
+
These were not intended to be called in a `before(:all)` hook, as
|
27
|
+
they exist to define state that is reset between each example, while
|
28
|
+
`before(:all)` exists to define state that is shared across examples
|
29
|
+
in an example group (Myron Marston).
|
30
|
+
|
1
31
|
### 2.13.0 / 2013-02-23
|
2
32
|
[full changelog](http://github.com/rspec/rspec-core/compare/v2.12.2...v2.13.0)
|
3
33
|
|
@@ -14,6 +44,8 @@ Enhancements
|
|
14
44
|
method. (Myron Marston)
|
15
45
|
* Allow output colors to be configured individually.
|
16
46
|
(Charlie Maffitt)
|
47
|
+
* Always dump slow examples when `--profile` option is given,
|
48
|
+
even when an example failed (Myron Marston).
|
17
49
|
|
18
50
|
Bug fixes
|
19
51
|
|
data/README.md
CHANGED
@@ -198,8 +198,10 @@ this before you write any implementation code:
|
|
198
198
|
```ruby
|
199
199
|
# in spec/calculator_spec.rb
|
200
200
|
describe Calculator do
|
201
|
-
|
202
|
-
|
201
|
+
describe '#add' do
|
202
|
+
it 'returns the sum of its arguments' do
|
203
|
+
expect(Calculator.new.add(1, 2)).to eq(3)
|
204
|
+
end
|
203
205
|
end
|
204
206
|
end
|
205
207
|
```
|
@@ -244,8 +246,9 @@ Use the `documentation` formatter to see the resulting spec:
|
|
244
246
|
|
245
247
|
```
|
246
248
|
$ rspec spec/calculator_spec.rb --format doc
|
247
|
-
Calculator
|
248
|
-
|
249
|
+
Calculator
|
250
|
+
#add
|
251
|
+
returns the sum of its arguments
|
249
252
|
|
250
253
|
Finished in 0.000379 seconds
|
251
254
|
1 example, 0 failures
|
@@ -31,10 +31,6 @@ Then /^the process should succeed even though no examples were run$/ do
|
|
31
31
|
step %q{the exit status should be 0}
|
32
32
|
end
|
33
33
|
|
34
|
-
Then /^the file "([^"]*)" should contain:$/ do |file, partial_content|
|
35
|
-
check_file_content(file, partial_content, true)
|
36
|
-
end
|
37
|
-
|
38
34
|
Then /^the backtrace\-normalized output should contain:$/ do |partial_output|
|
39
35
|
# ruby 1.9 includes additional stuff in the backtrace,
|
40
36
|
# so we need to normalize it to compare it with our expected output.
|
data/features/support/env.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
require 'aruba/cucumber'
|
2
2
|
|
3
|
+
timeouts = { 'java' => 60 }
|
4
|
+
|
3
5
|
Before do
|
4
|
-
|
5
|
-
# ideas taken from: http://blog.headius.com/2010/03/jruby-startup-time-tips.html
|
6
|
-
set_env('JRUBY_OPTS', '-X-C') # disable JIT since these processes are so short lived
|
7
|
-
set_env('JAVA_OPTS', '-d32') # force jRuby to use client JVM for faster startup times
|
8
|
-
@aruba_timeout_seconds = 60
|
9
|
-
else
|
10
|
-
@aruba_timeout_seconds = 10
|
11
|
-
end
|
6
|
+
@aruba_timeout_seconds = timeouts.fetch(RUBY_PLATFORM) { 10 }
|
12
7
|
end
|
8
|
+
|
9
|
+
Aruba.configure do |config|
|
10
|
+
config.before_cmd do |cmd|
|
11
|
+
set_env('JRUBY_OPTS', "-X-C #{ENV['JRUBY_OPTS']}") # disable JIT since these processes are so short lived
|
12
|
+
end
|
13
|
+
end if RUBY_PLATFORM == 'java'
|
14
|
+
|
@@ -299,6 +299,7 @@ module RSpec
|
|
299
299
|
# @private
|
300
300
|
def self.store_before_all_ivars(example_group_instance)
|
301
301
|
return if example_group_instance.instance_variables.empty?
|
302
|
+
|
302
303
|
example_group_instance.instance_variables.each { |ivar|
|
303
304
|
before_all_ivars[ivar] = example_group_instance.instance_variable_get(ivar)
|
304
305
|
}
|
@@ -314,7 +315,10 @@ module RSpec
|
|
314
315
|
return if descendant_filtered_examples.empty?
|
315
316
|
begin
|
316
317
|
assign_before_all_ivars(superclass.before_all_ivars, example_group_instance)
|
317
|
-
|
318
|
+
|
319
|
+
BeforeAllMemoizedHash.isolate_for_before_all(example_group_instance) do
|
320
|
+
run_hook(:before, :all, example_group_instance)
|
321
|
+
end
|
318
322
|
ensure
|
319
323
|
store_before_all_ivars(example_group_instance)
|
320
324
|
end
|
data/lib/rspec/core/hooks.rb
CHANGED
@@ -3,12 +3,12 @@ module RSpec
|
|
3
3
|
module Hooks
|
4
4
|
include MetadataHashBuilder::WithConfigWarning
|
5
5
|
|
6
|
-
|
7
|
-
attr_reader :options
|
6
|
+
class Hook
|
7
|
+
attr_reader :block, :options
|
8
8
|
|
9
|
-
def
|
9
|
+
def initialize(block, options)
|
10
|
+
@block = block
|
10
11
|
@options = options
|
11
|
-
self
|
12
12
|
end
|
13
13
|
|
14
14
|
def options_apply?(example_or_group)
|
@@ -16,11 +16,9 @@ module RSpec
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
include HookExtension
|
21
|
-
|
19
|
+
class BeforeHook < Hook
|
22
20
|
def run(example)
|
23
|
-
example.instance_eval(&
|
21
|
+
example.instance_eval(&block)
|
24
22
|
end
|
25
23
|
|
26
24
|
def display_name
|
@@ -28,11 +26,9 @@ module RSpec
|
|
28
26
|
end
|
29
27
|
end
|
30
28
|
|
31
|
-
|
32
|
-
include HookExtension
|
33
|
-
|
29
|
+
class AfterHook < Hook
|
34
30
|
def run(example)
|
35
|
-
example.instance_eval_with_rescue("in an after hook", &
|
31
|
+
example.instance_eval_with_rescue("in an after hook", &block)
|
36
32
|
end
|
37
33
|
|
38
34
|
def display_name
|
@@ -40,9 +36,7 @@ module RSpec
|
|
40
36
|
end
|
41
37
|
end
|
42
38
|
|
43
|
-
|
44
|
-
include HookExtension
|
45
|
-
|
39
|
+
class AroundHook < Hook
|
46
40
|
def display_name
|
47
41
|
"around hook"
|
48
42
|
end
|
@@ -90,7 +84,7 @@ module RSpec
|
|
90
84
|
def run
|
91
85
|
inject(@initial_procsy) do |procsy, around_hook|
|
92
86
|
Example.procsy(procsy.metadata) do
|
93
|
-
@example.instance_eval_with_args(procsy, &around_hook)
|
87
|
+
@example.instance_eval_with_args(procsy, &around_hook.block)
|
94
88
|
end
|
95
89
|
end.call
|
96
90
|
end
|
@@ -433,10 +427,10 @@ module RSpec
|
|
433
427
|
|
434
428
|
SCOPES = [:each, :all, :suite]
|
435
429
|
|
436
|
-
|
437
|
-
:before =>
|
438
|
-
:after =>
|
439
|
-
:around =>
|
430
|
+
HOOK_TYPES = {
|
431
|
+
:before => BeforeHook,
|
432
|
+
:after => AfterHook,
|
433
|
+
:around => AroundHook
|
440
434
|
}
|
441
435
|
|
442
436
|
def before_all_hooks_for(group)
|
@@ -457,7 +451,7 @@ module RSpec
|
|
457
451
|
|
458
452
|
def register_hook prepend_or_append, hook, *args, &block
|
459
453
|
scope, options = scope_and_options_from(*args)
|
460
|
-
hooks[hook][scope].send(prepend_or_append,
|
454
|
+
hooks[hook][scope].send(prepend_or_append, HOOK_TYPES[hook].new(block, options))
|
461
455
|
end
|
462
456
|
|
463
457
|
def find_hook(hook, scope, example_or_group, initial_procsy)
|
@@ -78,6 +78,66 @@ module RSpec
|
|
78
78
|
@__memoized ||= {}
|
79
79
|
end
|
80
80
|
|
81
|
+
# Used internally to customize the behavior of the
|
82
|
+
# memoized hash when used in a `before(:all)` hook.
|
83
|
+
#
|
84
|
+
# @private
|
85
|
+
class BeforeAllMemoizedHash
|
86
|
+
def initialize(example_group_instance)
|
87
|
+
@example_group_instance = example_group_instance
|
88
|
+
@hash = {}
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.isolate_for_before_all(example_group_instance)
|
92
|
+
example_group_instance.instance_eval do
|
93
|
+
@__memoized = BeforeAllMemoizedHash.new(self)
|
94
|
+
|
95
|
+
begin
|
96
|
+
yield
|
97
|
+
ensure
|
98
|
+
@__memoized.preserve_accessed_lets
|
99
|
+
@__memoized = nil
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def fetch(key, &block)
|
105
|
+
description = if key == :subject
|
106
|
+
"subject"
|
107
|
+
else
|
108
|
+
"let declaration `#{key}`"
|
109
|
+
end
|
110
|
+
|
111
|
+
::RSpec.warn_deprecation <<-EOS
|
112
|
+
WARNING: #{description} accessed in a `before(:all)` hook at:
|
113
|
+
#{caller[1]}
|
114
|
+
|
115
|
+
This is deprecated behavior that will not be supported in RSpec 3.
|
116
|
+
|
117
|
+
`let` and `subject` declarations are not intended to be called
|
118
|
+
in a `before(:all)` hook, as they exist to define state that
|
119
|
+
is reset between each example, while `before(:all)` exists to
|
120
|
+
define state that is shared across examples in an example group.
|
121
|
+
EOS
|
122
|
+
|
123
|
+
@hash.fetch(key, &block)
|
124
|
+
end
|
125
|
+
|
126
|
+
def []=(key, value)
|
127
|
+
@hash[key] = value
|
128
|
+
end
|
129
|
+
|
130
|
+
def preserve_accessed_lets
|
131
|
+
hash = @hash
|
132
|
+
|
133
|
+
@example_group_instance.class.class_eval do
|
134
|
+
hash.each do |key, value|
|
135
|
+
define_method(key) { value }
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
81
141
|
def self.included(mod)
|
82
142
|
mod.extend(ClassMethods)
|
83
143
|
|
@@ -117,12 +177,12 @@ module RSpec
|
|
117
177
|
def let(name, &block)
|
118
178
|
# We have to pass the block directly to `define_method` to
|
119
179
|
# allow it to use method constructs like `super` and `return`.
|
120
|
-
|
180
|
+
MemoizedHelpers.module_for(self).define_method(name, &block)
|
121
181
|
|
122
182
|
# Apply the memoization. The method has been defined in an ancestor
|
123
183
|
# module so we can use `super` here to get the value.
|
124
184
|
define_method(name) do
|
125
|
-
__memoized.fetch(name) { |k| __memoized[k] = super() }
|
185
|
+
__memoized.fetch(name) { |k| __memoized[k] = super(&nil) }
|
126
186
|
end
|
127
187
|
end
|
128
188
|
|
@@ -214,8 +274,16 @@ module RSpec
|
|
214
274
|
#
|
215
275
|
# @see MemoizedHelpers#should
|
216
276
|
def subject(name=nil, &block)
|
217
|
-
|
218
|
-
|
277
|
+
if name
|
278
|
+
let(name, &block)
|
279
|
+
subject { __send__ name }
|
280
|
+
|
281
|
+
self::NamedSubjectPreventSuper.define_method(name) do
|
282
|
+
raise NotImplementedError, "`super` in named subjects is not supported"
|
283
|
+
end
|
284
|
+
else
|
285
|
+
let(:subject, &block)
|
286
|
+
end
|
219
287
|
end
|
220
288
|
|
221
289
|
# Just like `subject`, except the block is invoked by an implicit `before`
|
@@ -381,9 +449,17 @@ module RSpec
|
|
381
449
|
# in order to get the value to memoize.
|
382
450
|
def self.module_for(example_group)
|
383
451
|
get_constant_or_yield(example_group, :LetDefinitions) do
|
384
|
-
|
385
|
-
|
386
|
-
|
452
|
+
mod = Module.new do
|
453
|
+
include Module.new {
|
454
|
+
public_class_method :define_method
|
455
|
+
example_group.const_set(:NamedSubjectPreventSuper, self)
|
456
|
+
}
|
457
|
+
|
458
|
+
# Expose `define_method` as a public method, so we can
|
459
|
+
# easily use it below.
|
460
|
+
public_class_method :define_method
|
461
|
+
end
|
462
|
+
|
387
463
|
example_group.__send__(:include, mod)
|
388
464
|
example_group.const_set(:LetDefinitions, mod)
|
389
465
|
mod
|
data/lib/rspec/core/version.rb
CHANGED
@@ -330,7 +330,7 @@ describe RSpec::Core::Example, :parent_metadata => 'sample' do
|
|
330
330
|
it 'does not print mock expectation errors' do
|
331
331
|
group = RSpec::Core::ExampleGroup.describe do
|
332
332
|
example do
|
333
|
-
foo =
|
333
|
+
foo = double
|
334
334
|
foo.should_receive(:bar)
|
335
335
|
raise "boom"
|
336
336
|
end
|
@@ -28,21 +28,21 @@ describe RSpec::Core::Formatters::BaseFormatter do
|
|
28
28
|
|
29
29
|
describe "read_failed_line" do
|
30
30
|
it "deals gracefully with a heterogeneous language stack trace" do
|
31
|
-
exception =
|
31
|
+
exception = double(:Exception, :backtrace => [
|
32
32
|
"at Object.prototypeMethod (foo:331:18)",
|
33
33
|
"at Array.forEach (native)",
|
34
34
|
"at a_named_javascript_function (/some/javascript/file.js:39:5)",
|
35
35
|
"/some/line/of/ruby.rb:14"
|
36
36
|
])
|
37
|
-
example =
|
37
|
+
example = double(:Example, :file_path => __FILE__)
|
38
38
|
expect {
|
39
39
|
formatter.send(:read_failed_line, exception, example)
|
40
40
|
}.not_to raise_error
|
41
41
|
end
|
42
42
|
|
43
43
|
it "deals gracefully with a security error" do
|
44
|
-
exception =
|
45
|
-
example =
|
44
|
+
exception = double(:Exception, :backtrace => [ "#{__FILE__}:#{__LINE__}"])
|
45
|
+
example = double(:Example, :file_path => __FILE__)
|
46
46
|
safely do
|
47
47
|
expect {
|
48
48
|
formatter.send(:read_failed_line, exception, example)
|
@@ -52,8 +52,8 @@ describe RSpec::Core::Formatters::BaseFormatter do
|
|
52
52
|
|
53
53
|
context "when ruby reports a bogus line number in the stack trace" do
|
54
54
|
it "reports the filename and that it was unable to find the matching line" do
|
55
|
-
exception =
|
56
|
-
example =
|
55
|
+
exception = double(:Exception, :backtrace => [ "#{__FILE__}:10000000" ])
|
56
|
+
example = double(:Example, :file_path => __FILE__)
|
57
57
|
|
58
58
|
msg = formatter.send(:read_failed_line, exception, example)
|
59
59
|
expect(msg).to include("Unable to find matching line")
|
@@ -75,11 +75,11 @@ describe RSpec::Core::Formatters::BaseFormatter do
|
|
75
75
|
|
76
76
|
it "doesn't hang when file exists" do
|
77
77
|
pending("This issue still exists on JRuby, but should be resolved shortly: https://github.com/rspec/rspec-core/issues/295", :if => RUBY_PLATFORM == 'java')
|
78
|
-
exception =
|
78
|
+
exception = double(:Exception, :backtrace => [ "#{__FILE__}:#{__LINE__}"])
|
79
79
|
|
80
|
-
example =
|
80
|
+
example = double(:Example, :file_path => __FILE__)
|
81
81
|
expect(formatter.send(:read_failed_line, exception, example)).to eql(
|
82
|
-
%Q{ exception =
|
82
|
+
%Q{ exception = double(:Exception, :backtrace => [ "\#{__FILE__}:\#{__LINE__}"])\n})
|
83
83
|
end
|
84
84
|
|
85
85
|
end
|
@@ -101,7 +101,7 @@ describe RSpec::Core::Formatters::BaseFormatter do
|
|
101
101
|
end
|
102
102
|
|
103
103
|
it "removes lines from rspec and lines that come before the invocation of the at_exit autorun hook" do
|
104
|
-
expect(formatter.format_backtrace(backtrace,
|
104
|
+
expect(formatter.format_backtrace(backtrace, double.as_null_object)).to eq(["./my_spec.rb:5"])
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
@@ -246,5 +246,22 @@ module RSpec::Core
|
|
246
246
|
end
|
247
247
|
end
|
248
248
|
end
|
249
|
+
|
250
|
+
describe "lambda" do
|
251
|
+
it "can be used as a hook" do
|
252
|
+
messages = []
|
253
|
+
count = 0
|
254
|
+
hook = lambda {|e| messages << "hook #{count = count + 1}"; e.run }
|
255
|
+
|
256
|
+
RSpec.configure do |c|
|
257
|
+
c.around(:each, &hook)
|
258
|
+
c.around(:each, &hook)
|
259
|
+
end
|
260
|
+
|
261
|
+
group = ExampleGroup.describe { example { messages << "example" } }
|
262
|
+
group.run
|
263
|
+
expect(messages).to eq ["hook 1", "hook 2", "example"]
|
264
|
+
end
|
265
|
+
end
|
249
266
|
end
|
250
267
|
end
|
@@ -120,6 +120,67 @@ module RSpec::Core
|
|
120
120
|
|
121
121
|
expect(subject_value).to eq([4, 5, 6, :override])
|
122
122
|
end
|
123
|
+
|
124
|
+
context 'when referenced in a `before(:all)` hook' do
|
125
|
+
before do
|
126
|
+
expect(::RSpec).to respond_to(:warn_deprecation)
|
127
|
+
::RSpec.stub(:warn_deprecation)
|
128
|
+
end
|
129
|
+
|
130
|
+
def define_and_run_group
|
131
|
+
values = { :reference_lines => [] }
|
132
|
+
|
133
|
+
ExampleGroup.describe do
|
134
|
+
subject { [1, 2] }
|
135
|
+
let(:list) { %w[ a b ] }
|
136
|
+
|
137
|
+
before(:all) do
|
138
|
+
subject << 3; values[:reference_lines] << __LINE__
|
139
|
+
values[:final_subject_value_in_before_all] = subject; values[:reference_lines] << __LINE__
|
140
|
+
end
|
141
|
+
|
142
|
+
example do
|
143
|
+
list << '1'
|
144
|
+
values[:list_in_ex_1] = list
|
145
|
+
values[:subject_value_in_example] = subject
|
146
|
+
end
|
147
|
+
|
148
|
+
example do
|
149
|
+
list << '2'
|
150
|
+
values[:list_in_ex_2] = list
|
151
|
+
end
|
152
|
+
end.run
|
153
|
+
|
154
|
+
values
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'memoizes the value within the before(:all) hook' do
|
158
|
+
values = define_and_run_group
|
159
|
+
expect(values.fetch(:final_subject_value_in_before_all)).to eq([1, 2, 3])
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'preserves the memoization into the individual examples' do
|
163
|
+
values = define_and_run_group
|
164
|
+
expect(values.fetch(:subject_value_in_example)).to eq([1, 2, 3])
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'does not cause other lets to be shared across examples' do
|
168
|
+
values = define_and_run_group
|
169
|
+
expect(values.fetch(:list_in_ex_1)).to eq(%w[ a b 1 ])
|
170
|
+
expect(values.fetch(:list_in_ex_2)).to eq(%w[ a b 2 ])
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'prints a warning since `subject` declarations are not intended to be used in :all hooks' do
|
174
|
+
msgs = []
|
175
|
+
::RSpec.stub(:warn_deprecation) { |msg| msgs << msg }
|
176
|
+
|
177
|
+
values = define_and_run_group
|
178
|
+
|
179
|
+
expect(msgs).to include(*values[:reference_lines].map { |line|
|
180
|
+
match(/subject accessed.*#{__FILE__}:#{line}/m)
|
181
|
+
})
|
182
|
+
end
|
183
|
+
end
|
123
184
|
end
|
124
185
|
|
125
186
|
describe "with a name" do
|
@@ -157,21 +218,75 @@ module RSpec::Core
|
|
157
218
|
expect(inner_subject_value).to eq(1)
|
158
219
|
end
|
159
220
|
|
221
|
+
it 'can continue to be referenced by the name even when an inner group redefines the subject' do
|
222
|
+
named_value = nil
|
223
|
+
|
224
|
+
ExampleGroup.describe do
|
225
|
+
subject(:named) { :outer }
|
226
|
+
|
227
|
+
describe "inner" do
|
228
|
+
subject { :inner }
|
229
|
+
example do
|
230
|
+
subject # so the inner subject method is run and memoized
|
231
|
+
named_value = self.named
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end.run
|
235
|
+
|
236
|
+
expect(named_value).to eq(:outer)
|
237
|
+
end
|
238
|
+
|
239
|
+
it 'can continue to reference an inner subject after the outer subject name is referenced' do
|
240
|
+
subject_value = nil
|
241
|
+
|
242
|
+
ExampleGroup.describe do
|
243
|
+
subject(:named) { :outer }
|
244
|
+
|
245
|
+
describe "inner" do
|
246
|
+
subject { :inner }
|
247
|
+
example do
|
248
|
+
named # so the outer subject method is run and memoized
|
249
|
+
subject_value = self.subject
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end.run
|
253
|
+
|
254
|
+
expect(subject_value).to eq(:inner)
|
255
|
+
end
|
256
|
+
|
160
257
|
context 'when `super` is used' do
|
161
|
-
|
162
|
-
|
258
|
+
def should_raise_not_supported_error(&block)
|
259
|
+
ex = nil
|
163
260
|
|
164
261
|
ExampleGroup.describe do
|
165
262
|
let(:list) { ["a", "b", "c"] }
|
166
263
|
subject { [1, 2, 3] }
|
167
264
|
|
168
265
|
describe 'first' do
|
266
|
+
module_eval(&block) if block
|
267
|
+
|
169
268
|
subject(:list) { super().first(2) }
|
170
|
-
example {
|
269
|
+
ex = example { subject }
|
171
270
|
end
|
172
271
|
end.run
|
173
272
|
|
174
|
-
expect(
|
273
|
+
expect(ex.execution_result[:status]).to eq("failed")
|
274
|
+
expect(ex.execution_result[:exception].message).to match(/super.*not supported/)
|
275
|
+
end
|
276
|
+
|
277
|
+
it 'raises a "not supported" error' do
|
278
|
+
should_raise_not_supported_error
|
279
|
+
end
|
280
|
+
|
281
|
+
context 'with a `let` definition before the named subject' do
|
282
|
+
it 'raises a "not supported" error' do
|
283
|
+
should_raise_not_supported_error do
|
284
|
+
# My first pass implementation worked unless there was a `let`
|
285
|
+
# declared before the named subject -- this let is in place to
|
286
|
+
# ensure that bug doesn't return.
|
287
|
+
let(:foo) { 3 }
|
288
|
+
end
|
289
|
+
end
|
175
290
|
end
|
176
291
|
end
|
177
292
|
end
|
@@ -386,6 +501,13 @@ module RSpec::Core
|
|
386
501
|
expect(@nil_value_count).to eq(1)
|
387
502
|
end
|
388
503
|
|
504
|
+
let(:regex_with_capture) { %r[RegexWithCapture(\d)] }
|
505
|
+
|
506
|
+
it 'does not pass the block up the ancestor chain' do
|
507
|
+
# Test for Ruby bug http://bugs.ruby-lang.org/issues/8059
|
508
|
+
expect("RegexWithCapture1".match(regex_with_capture)[1]).to eq('1')
|
509
|
+
end
|
510
|
+
|
389
511
|
let(:a_value) { "a string" }
|
390
512
|
|
391
513
|
context 'when overriding let in a nested context' do
|
@@ -412,6 +534,67 @@ module RSpec::Core
|
|
412
534
|
expect(value).to eq(:late_exit)
|
413
535
|
end
|
414
536
|
end
|
537
|
+
|
538
|
+
context 'when referenced in a `before(:all)` hook' do
|
539
|
+
before do
|
540
|
+
expect(::RSpec).to respond_to(:warn_deprecation)
|
541
|
+
::RSpec.stub(:warn_deprecation)
|
542
|
+
end
|
543
|
+
|
544
|
+
def define_and_run_group
|
545
|
+
values = { :reference_lines => [] }
|
546
|
+
|
547
|
+
ExampleGroup.describe do
|
548
|
+
let(:list) { [1, 2] }
|
549
|
+
subject { %w[ a b ] }
|
550
|
+
|
551
|
+
before(:all) do
|
552
|
+
list << 3; values[:reference_lines] << __LINE__
|
553
|
+
values[:final_list_value_in_before_all] = list; values[:reference_lines] << __LINE__
|
554
|
+
end
|
555
|
+
|
556
|
+
example do
|
557
|
+
subject << "1"
|
558
|
+
values[:subject_in_ex_1] = subject
|
559
|
+
values[:list_value_in_example] = list
|
560
|
+
end
|
561
|
+
|
562
|
+
example do
|
563
|
+
subject << "2"
|
564
|
+
values[:subject_in_ex_2] = subject
|
565
|
+
end
|
566
|
+
end.run
|
567
|
+
|
568
|
+
values
|
569
|
+
end
|
570
|
+
|
571
|
+
it 'memoizes the value within the before(:all) hook' do
|
572
|
+
values = define_and_run_group
|
573
|
+
expect(values.fetch(:final_list_value_in_before_all)).to eq([1, 2, 3])
|
574
|
+
end
|
575
|
+
|
576
|
+
it 'preserves the memoized value into the examples' do
|
577
|
+
values = define_and_run_group
|
578
|
+
expect(values.fetch(:list_value_in_example)).to eq([1, 2, 3])
|
579
|
+
end
|
580
|
+
|
581
|
+
it 'does not cause the subject to be shared across examples' do
|
582
|
+
values = define_and_run_group
|
583
|
+
expect(values.fetch(:subject_in_ex_1)).to eq(%w[ a b 1 ])
|
584
|
+
expect(values.fetch(:subject_in_ex_2)).to eq(%w[ a b 2 ])
|
585
|
+
end
|
586
|
+
|
587
|
+
it 'prints a warning since `let` declarations are not intended to be used in :all hooks' do
|
588
|
+
msgs = []
|
589
|
+
::RSpec.stub(:warn_deprecation) { |msg| msgs << msg }
|
590
|
+
|
591
|
+
values = define_and_run_group
|
592
|
+
|
593
|
+
expect(msgs).to include(*values[:reference_lines].map { |line|
|
594
|
+
match(/let declaration `list` accessed.*#{__FILE__}:#{line}/m)
|
595
|
+
})
|
596
|
+
end
|
597
|
+
end
|
415
598
|
end
|
416
599
|
|
417
600
|
describe "#let!" do
|
@@ -456,3 +639,4 @@ module RSpec::Core
|
|
456
639
|
end
|
457
640
|
end
|
458
641
|
end
|
642
|
+
|
@@ -18,7 +18,7 @@ describe "an example" do
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
example = group.examples.first
|
21
|
-
example.run(group.new,
|
21
|
+
example.run(group.new, double.as_null_object)
|
22
22
|
expect(example).to be_pending_with('just because')
|
23
23
|
end
|
24
24
|
|
@@ -28,7 +28,7 @@ describe "an example" do
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
example = group.examples.first
|
31
|
-
example.run(group.new,
|
31
|
+
example.run(group.new, double.as_null_object)
|
32
32
|
expect(example).to be_pending_with('No reason given')
|
33
33
|
end
|
34
34
|
end
|
@@ -39,7 +39,7 @@ describe "an example" do
|
|
39
39
|
it "has no block"
|
40
40
|
end
|
41
41
|
example = group.examples.first
|
42
|
-
example.run(group.new,
|
42
|
+
example.run(group.new, double.as_null_object)
|
43
43
|
expect(example).to be_pending_with('Not yet implemented')
|
44
44
|
end
|
45
45
|
end
|
@@ -52,7 +52,7 @@ describe "an example" do
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
example = group.examples.first
|
55
|
-
example.run(group.new,
|
55
|
+
example.run(group.new, double.as_null_object)
|
56
56
|
expect(example).to be_pending_with(RSpec::Core::Pending::NO_REASON_GIVEN)
|
57
57
|
end
|
58
58
|
end
|
@@ -69,7 +69,7 @@ describe "an example" do
|
|
69
69
|
end
|
70
70
|
end
|
71
71
|
example = group.examples.last
|
72
|
-
example.run(group.new,
|
72
|
+
example.run(group.new, double.as_null_object)
|
73
73
|
expect(example.description).to match(/example at/)
|
74
74
|
end
|
75
75
|
end
|
@@ -85,7 +85,7 @@ describe "an example" do
|
|
85
85
|
end
|
86
86
|
end
|
87
87
|
example = group.examples.last
|
88
|
-
example.run(group.new,
|
88
|
+
example.run(group.new, double.as_null_object)
|
89
89
|
expect(example.description).to match(/example at/)
|
90
90
|
end
|
91
91
|
end
|
@@ -99,7 +99,7 @@ describe "an example" do
|
|
99
99
|
end
|
100
100
|
end
|
101
101
|
example = group.examples.first
|
102
|
-
example.run(group.new,
|
102
|
+
example.run(group.new, double.as_null_object)
|
103
103
|
expect(example).to be_pending_with('just because')
|
104
104
|
end
|
105
105
|
end
|
@@ -112,7 +112,7 @@ describe "an example" do
|
|
112
112
|
end
|
113
113
|
end
|
114
114
|
example = group.examples.first
|
115
|
-
example.run(group.new,
|
115
|
+
example.run(group.new, double.as_null_object)
|
116
116
|
example
|
117
117
|
end
|
118
118
|
|
@@ -30,7 +30,7 @@ module RSpec::Core
|
|
30
30
|
it "passes example_group_started and example_group_finished messages to that formatter in that order" do
|
31
31
|
order = []
|
32
32
|
|
33
|
-
formatter =
|
33
|
+
formatter = double("formatter").as_null_object
|
34
34
|
formatter.stub(:example_group_started) { |group| order << "Started: #{group.description}" }
|
35
35
|
formatter.stub(:example_group_finished) { |group| order << "Finished: #{group.description}" }
|
36
36
|
|
@@ -57,7 +57,7 @@ module RSpec::Core
|
|
57
57
|
|
58
58
|
context "given an example group with no examples" do
|
59
59
|
it "does not pass example_group_started or example_group_finished to formatter" do
|
60
|
-
formatter =
|
60
|
+
formatter = double("formatter").as_null_object
|
61
61
|
formatter.should_not_receive(:example_group_started)
|
62
62
|
formatter.should_not_receive(:example_group_finished)
|
63
63
|
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: rspec-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 2.13.
|
5
|
+
version: 2.13.1
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Steven Baker
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: exe
|
13
13
|
cert_chain: []
|
14
|
-
date: 2013-
|
14
|
+
date: 2013-03-12 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -50,7 +50,7 @@ dependencies:
|
|
50
50
|
requirements:
|
51
51
|
- - ~>
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: 0.
|
53
|
+
version: '0.5'
|
54
54
|
none: false
|
55
55
|
prerelease: false
|
56
56
|
name: aruba
|
@@ -58,23 +58,23 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.
|
61
|
+
version: '0.5'
|
62
62
|
none: false
|
63
63
|
type: :development
|
64
64
|
- !ruby/object:Gem::Dependency
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
|
-
- -
|
67
|
+
- - ~>
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version: 4.6
|
69
|
+
version: '4.6'
|
70
70
|
none: false
|
71
71
|
prerelease: false
|
72
72
|
name: ZenTest
|
73
73
|
requirement: !ruby/object:Gem::Requirement
|
74
74
|
requirements:
|
75
|
-
- -
|
75
|
+
- - ~>
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version: 4.6
|
77
|
+
version: '4.6'
|
78
78
|
none: false
|
79
79
|
type: :development
|
80
80
|
- !ruby/object:Gem::Dependency
|
@@ -372,7 +372,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
372
372
|
version: '0'
|
373
373
|
segments:
|
374
374
|
- 0
|
375
|
-
hash:
|
375
|
+
hash: 4384848023819144247
|
376
376
|
none: false
|
377
377
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
378
378
|
requirements:
|
@@ -381,14 +381,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
381
381
|
version: '0'
|
382
382
|
segments:
|
383
383
|
- 0
|
384
|
-
hash:
|
384
|
+
hash: 4384848023819144247
|
385
385
|
none: false
|
386
386
|
requirements: []
|
387
387
|
rubyforge_project: rspec
|
388
388
|
rubygems_version: 1.8.24
|
389
389
|
signing_key:
|
390
390
|
specification_version: 3
|
391
|
-
summary: rspec-core-2.13.
|
391
|
+
summary: rspec-core-2.13.1
|
392
392
|
test_files:
|
393
393
|
- features/Autotest.md
|
394
394
|
- features/README.md
|