Skip to content

Commit

Permalink
Merge pull request #1935 from eugeneius/configure_existing_example_gr…
Browse files Browse the repository at this point in the history
…oups

Apply helper modules to existing groups when added
  • Loading branch information
JonRowe committed Apr 14, 2015
2 parents 42e4ceb + b261081 commit 2e6c8d6
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 2 deletions.
11 changes: 11 additions & 0 deletions lib/rspec/core/configuration.rb
Expand Up @@ -1134,6 +1134,7 @@ def exclusion_filter
def include(mod, *filters)
meta = Metadata.build_hash_from(filters, :warn_about_example_group_filtering)
@include_modules.append(mod, meta)
configure_existing_groups(mod, meta, :safe_include)
end

# Tells RSpec to extend example groups with `mod`. Methods defined in
Expand Down Expand Up @@ -1169,6 +1170,7 @@ def include(mod, *filters)
def extend(mod, *filters)
meta = Metadata.build_hash_from(filters, :warn_about_example_group_filtering)
@extend_modules.append(mod, meta)
configure_existing_groups(mod, meta, :safe_extend)
end

if RSpec::Support::RubyFeatures.module_prepends_supported?
Expand Down Expand Up @@ -1207,6 +1209,7 @@ def extend(mod, *filters)
def prepend(mod, *filters)
meta = Metadata.build_hash_from(filters, :warn_about_example_group_filtering)
@prepend_modules.append(mod, meta)
configure_existing_groups(mod, meta, :safe_prepend)
end
end

Expand All @@ -1227,6 +1230,14 @@ def configure_group_with(group, module_list, application_method)
end
end

# @private
def configure_existing_groups(mod, meta, application_method)
RSpec.world.all_example_groups.each do |group|
next unless meta.empty? || MetadataFilter.apply?(:any?, meta, group.metadata)
__send__(application_method, mod, group)
end
end

# @private
#
# Used internally to extend the singleton class of a single example's
Expand Down
8 changes: 6 additions & 2 deletions lib/rspec/core/world.rb
Expand Up @@ -77,10 +77,14 @@ def example_count(groups=example_groups)
inject(0) { |a, e| a + e.filtered_examples.size }
end

# @private
def all_example_groups
FlatMap.flat_map(example_groups) { |g| g.descendants }
end

# @private
def all_examples
flattened_groups = FlatMap.flat_map(example_groups) { |g| g.descendants }
FlatMap.flat_map(flattened_groups) { |g| g.examples }
FlatMap.flat_map(all_example_groups) { |g| g.examples }
end

# @api private
Expand Down
51 changes: 51 additions & 0 deletions spec/rspec/core/configuration_spec.rb
Expand Up @@ -879,6 +879,17 @@ def metadata_hash(*args)
expect(group).not_to respond_to(:you_call_this_a_blt?)
expect(group.new.you_call_this_a_blt?).to eq("egad man, where's the mayo?!?!?")
end

it "includes the given module into each existing example group" do
group = RSpec.describe('does like, stuff and junk', :magic_key => :include) { }

RSpec.configure do |c|
c.include(InstanceLevelMethods)
end

expect(group).not_to respond_to(:you_call_this_a_blt?)
expect(group.new.you_call_this_a_blt?).to eq("egad man, where's the mayo?!?!?")
end
end

context "with a filter" do
Expand All @@ -892,6 +903,17 @@ def metadata_hash(*args)
expect(group.new.you_call_this_a_blt?).to eq("egad man, where's the mayo?!?!?")
end

it "includes the given module into each existing matching example group" do
group = RSpec.describe('does like, stuff and junk', :magic_key => :include) { }

RSpec.configure do |c|
c.include(InstanceLevelMethods, :magic_key => :include)
end

expect(group).not_to respond_to(:you_call_this_a_blt?)
expect(group.new.you_call_this_a_blt?).to eq("egad man, where's the mayo?!?!?")
end

it "includes the given module into the singleton class of matching examples" do
RSpec.configure do |c|
c.include(InstanceLevelMethods, :magic_key => :include)
Expand Down Expand Up @@ -981,6 +1003,15 @@ def metadata_hash(*args)
expect(group).to respond_to(:that_thing)
end

it "extends the given module into each existing matching example group" do
group = RSpec.describe(ThatThingISentYou, :magic_key => :extend) { }

RSpec.configure do |c|
c.extend(ThatThingISentYou, :magic_key => :extend)
end

expect(group).to respond_to(:that_thing)
end
end

describe "#prepend", :if => RSpec::Support::RubyFeatures.module_prepends_supported? do
Expand Down Expand Up @@ -1008,6 +1039,16 @@ def metadata_hash(*args)
group = RSpec.describe('yo') { }
expect(group.new.foo).to eq("foobar")
end

it "prepends the given module into each existing example group" do
group = RSpec.describe('yo') { }

RSpec.configure do |c|
c.prepend(SomeRandomMod)
end

expect(group.new.foo).to eq("foobar")
end
end

context "with a filter" do
Expand All @@ -1019,6 +1060,16 @@ def metadata_hash(*args)
group = RSpec.describe('yo', :magic_key => :include) { }
expect(group.new.foo).to eq("foobar")
end

it "prepends the given module into each existing matching example group" do
group = RSpec.describe('yo', :magic_key => :include) { }

RSpec.configure do |c|
c.prepend(SomeRandomMod, :magic_key => :include)
end

expect(group.new.foo).to eq("foobar")
end
end

end
Expand Down
21 changes: 21 additions & 0 deletions spec/rspec/core/world_spec.rb
Expand Up @@ -23,6 +23,27 @@ module RSpec::Core
end
end

describe "#all_example_groups" do
it "contains all example groups from all levels of nesting" do
RSpec.describe "eg1" do
context "eg2" do
context "eg3"
context "eg4"
end

context "eg5"
end

RSpec.describe "eg6" do
example
end

expect(RSpec.world.all_example_groups.map(&:description)).to match_array(%w[
eg1 eg2 eg3 eg4 eg5 eg6
])
end
end

describe "#all_examples" do
it "contains all examples from all levels of nesting" do
RSpec.describe do
Expand Down

0 comments on commit 2e6c8d6

Please sign in to comment.