rspec-core 2.13.0 → 2.13.1
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/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
|