-
Notifications
You must be signed in to change notification settings - Fork 2
Add support for config.around(:all) and config.around(:all_nested) #2
base: master
Are you sure you want to change the base?
Changes from 2 commits
9d09d3b
2eb4b2a
057ecfd
790976b
d982b55
29cd2ac
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,25 +10,48 @@ def run_examples | |
def to_proc | ||
proc { run_examples } | ||
end | ||
|
||
def class | ||
__getobj__.class | ||
end | ||
end | ||
|
||
def around(scope = :each, &block) | ||
return around_all &block if scope == :all | ||
# let RSpec handle around(:each) hooks... | ||
return super(scope, &block) unless scope == :all | ||
return super(scope, &block) unless scope == :all_nested | ||
around_all do |group| | ||
group.children.each {|c| c.around(:all_nested, &block) } | ||
block[group] | ||
end | ||
end | ||
|
||
group, fiber = self, nil | ||
before(:all) do | ||
private | ||
|
||
FIBERS_STACK = [] | ||
|
||
def around_all(&block) | ||
prepend_before(:all) do |group| | ||
fiber = Fiber.new(&block) | ||
fiber.resume(FiberAwareGroup.new(group)) | ||
FIBERS_STACK << fiber | ||
fiber.resume(FiberAwareGroup.new(group.class)) | ||
end | ||
|
||
after(:all) do | ||
prepend_after(:all) do | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this be append_after to properly nest? (spec coverage to validate this would be useful) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought it validated, but I've also thought about that. Maybe I should use |
||
fiber = FIBERS_STACK.pop | ||
fiber.resume | ||
end | ||
end | ||
end | ||
|
||
RSpec.configure do |c| | ||
c.extend RSpecAroundAll | ||
|
||
# Add config.around(:all): | ||
# c.extend overrides the original Object#extend method. | ||
# See discussion in https://github.com/rspec/rspec-core/issues/1031#issuecomment-22264638 | ||
Object.instance_method(:extend).bind(c).call RSpecAroundAll | ||
# Ruby 2 alternative: | ||
# RSpec::Core::Configuration.send :prepend, RSpecAroundAll | ||
end | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,17 @@ | ||
require_relative '../lib/rspec_around_all' | ||
|
||
RSpec.configure do |c| | ||
[:all, :all_nested].each do |all_type| | ||
c.around(all_type) do |group| | ||
(group.run_examples; next) unless order = group.metadata[:order] | ||
count = group.metadata[:count][all_type] += 1 | ||
order << "config.before(:#{all_type}) #{count}" | ||
group.run_examples | ||
order << "config.after(:#{all_type}) #{count}" | ||
end | ||
end | ||
end | ||
|
||
module RSpec | ||
module Core | ||
describe "around(:all) hook" do | ||
|
@@ -89,6 +101,44 @@ def self.transactionally | |
order.should eq([:before, :e1, :after, :before, :e2, :after]) | ||
end | ||
end | ||
|
||
describe "config.around(:all) hook", order: [], count: {all_nested: 0, all: 0} do | ||
order = nil | ||
context "part 1" do | ||
around(:all) do |g| | ||
order = g.metadata[:order] | ||
order << 'inner.before(:all)' | ||
g.run_examples | ||
order << 'inner.after(:all)' | ||
end | ||
|
||
specify { order << 'first' } | ||
specify { order << 'second' } | ||
|
||
example "blocks are executed in the right order" do | ||
expect(order).to eq [ | ||
'config.before(:all_nested) 1', | ||
'config.before(:all) 1', | ||
'config.before(:all_nested) 2', | ||
'inner.before(:all)', | ||
'first', | ||
'second', | ||
] | ||
end | ||
end | ||
|
||
# this context won't pass if run alone (rspec -e "part 2") since it depends on part 1 to run before it | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think there's a different way you can structure this to avoid this problem: rather than creating nested example groups directly here, define an example that, within it, defines an example group with all the nesting that you need. You can define an example group (using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That approach doesn't work either. Try to run the spec with |
||
context "part 2" do | ||
example "before and after hooks order is correct" do | ||
expect(order[-3..-1]).to eq [ | ||
'inner.after(:all)', # part 1 | ||
'config.after(:all_nested) 2', # inner config.around | ||
'config.before(:all_nested) 3', # config.before part 2 | ||
] | ||
end | ||
end | ||
|
||
end | ||
end | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I'd like to see a new scope (:all_nested) introduced here in this helper gem -- I'd like to keep this gem as minimal as possible. If all the other changes in this PR were merged, would you be able to achieve this same result via logic in your own spec configuration/setup instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really see any value in config.before/after/around(:all) blocks. Do you have any use case where it could be useful? I only really care about config.around(:all_nested). Maybe we could rename
:all_nested
to:group
or:context
. What do you think?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The change here (introducing :all_nested scope) is not limited to config.around() usage. I'm wondering if we can leave all of the changes in this method out of this PR, if you could then do nesting of around-alls in your configuration without requiring further changes here.