Skip to content

Commit

Permalink
clean up shared example specs
Browse files Browse the repository at this point in the history
  • Loading branch information
dchelimsky committed Jul 17, 2010
1 parent cefe961 commit 4668138
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 185 deletions.
2 changes: 1 addition & 1 deletion lib/rspec/core/example_group.rb
Expand Up @@ -61,7 +61,7 @@ class << self

def self.it_should_behave_like(*names, &customization_block)
names.map do |name|
shared_block = RSpec.world.shared_example_groups[name]
shared_block = world.shared_example_groups[name]
raise "Could not find shared example group named #{name.inspect}" unless shared_block
shared_group = describe("it should behave like #{name}", &shared_block)
shared_group.class_eval &customization_block if customization_block
Expand Down
248 changes: 64 additions & 184 deletions spec/rspec/core/shared_example_group_spec.rb
Expand Up @@ -3,71 +3,34 @@
module RSpec::Core

describe SharedExampleGroup do
it "should add the 'share_examples_for' method to the global namespace" do
Kernel.should respond_to(:share_examples_for)
end

it "should add the 'shared_examples_for' method to the global namespace" do
Kernel.should respond_to(:shared_examples_for)
end

it "should add the 'share_as' method to the global namespace" do
Kernel.should respond_to(:share_as)
end

it "should raise an ArgumentError when adding a second shared example group with the same name" do
group = ExampleGroup.describe('example group')
group.share_examples_for('really important business value') { }
lambda do
group.share_examples_for('really important business value') { }
end.should raise_error(ArgumentError, "Shared example group 'really important business value' already exists")
end

describe "share_examples_for" do

it "should capture the given name and block in the Worlds collection of shared example groups" do
RSpec.world.shared_example_groups.should_receive(:[]=).with(:foo, anything)
share_examples_for(:foo) { }
end

end

describe "including shared example_groups using #it_should_behave_like" do

it "should make any shared example_group available at the correct level" do
group = ExampleGroup.describe('fake group')
block = lambda {
def self.class_helper; end
def extra_helper; end
}
RSpec.world.stub(:shared_example_groups).and_return({ :shared_example_group => block })
shared_group = group.it_should_behave_like(:shared_example_group).first
shared_group.instance_methods.map {|m| m.to_s }.should include('extra_helper')
shared_group.singleton_methods.map {|m| m.to_s}.should include('class_helper')
end
%w[share_examples_for shared_examples_for].each do |method_name|
describe method_name do

it "raises when named shared example_group can not be found" do
group = ExampleGroup.describe("example_group")
lambda do
group.it_should_behave_like("a group that does not exist")
end.should raise_error(/Could not find shared example group named/)
end

it "does not add examples to current example_group using it_should_behave_like" do
group = ExampleGroup.describe("example_group") do
it("i was already here") {}
it "is exposed to the global namespace" do
Kernel.should respond_to(method_name)
end

group.examples.size.should == 1
it "raises an ArgumentError when adding a second shared example group with the same name" do
group = ExampleGroup.describe('example group')
group.send(method_name, 'shared group') {}
lambda do
group.send(method_name, 'shared group') {}
end.should raise_error(ArgumentError, "Shared example group 'shared group' already exists")
end

group.share_examples_for('shared example_group') do
it("shared example") {}
it("shared example 2") {}
it "captures the given name and block in the Worlds collection of shared example groups" do
implementation = lambda {}
RSpec.world.shared_example_groups.should_receive(:[]=).with(:foo, implementation)
send(method_name, :foo, &implementation)
end

group.it_should_behave_like("shared example_group")
end
end

group.examples.size.should == 1
describe "#share_as" do
it "is exposed to the global namespace" do
Kernel.should respond_to("share_as")
end

it "adds examples to current example_group using include", :compat => 'rspec-1.2' do
Expand All @@ -80,153 +43,70 @@ def extra_helper; end
group.examples.length.should == 1
group.examples.first.metadata[:description].should == "is plentiful"
end
end

it "adds the helper methods from the block provided to it_should_behave_like" do
group = ExampleGroup.describe("example group") {}
group.shared_examples_for("shared group") {}
shared_groups = group.it_should_behave_like("shared group") do
def helper_method; end
def self.class_helper; end
end

shared_group = shared_groups.first

shared_group.instance_methods.map { |m| m.to_sym }.should include(:helper_method)
shared_group.singleton_methods.map { |m| m.to_sym }.should include(:class_helper)
describe "#it_should_behave_like" do
it "creates a nested group" do
shared_examples_for("thing") {}
group = ExampleGroup.describe('fake group')
group.it_should_behave_like("thing")
group.should have(1).children
end

it "overrides the instance helper methods with the definitions from the block provided to it_should_behave_like" do
pending("decide that we really want this behavior")
group = ExampleGroup.describe("example group") {}
group.shared_examples_for("shared group") do
def helper_method; 'base helper'; end
it "adds shared examples to nested group" do
shared_examples_for("thing") do
it("does something")
end

shared_groups = group.it_should_behave_like("shared group") do
def helper_method; [super, 'overridden helper'].join('; '); end
end

shared_groups.first.new.helper_method.should == 'base helper; overridden helper'
group = ExampleGroup.describe('fake group')
shared_group = group.it_should_behave_like("thing").first
shared_group.should have(1).examples
end

it "overrides the class helper methods with the definitions from the block provided to it_should_behave_like" do
pending("decide that we really want this behavior")
group = ExampleGroup.describe("example group") {}
group.shared_examples_for("shared group") do
def self.helper_method; 'base helper'; end
it "adds shared instance methods to nested group" do
shared_examples_for("thing") do
def foo; end
end

shared_groups = group.it_should_behave_like("shared group") do
def self.helper_method; [super, 'overridden helper'].join('; '); end
end

shared_groups.first.helper_method.should == 'base helper; overridden helper'
group = ExampleGroup.describe('fake group')
shared_group = group.it_should_behave_like("thing").first
shared_group.public_instance_methods.should include("foo")
end

it "allows the RSpec DSL to be used in the block provided to it_should_behave_like" do
results = {}
group = ExampleGroup.describe("example group") {}
group.shared_examples_for("shared group") do
it 'assigns the results of using the RSpec DSL' do
results[:subject] = subject
results[:foo] = foo
results[:before_each] = @before_each
end
end

group.it_should_behave_like("shared group") do
subject { :the_subject }
let(:foo) { :foo_value }
before(:each) { @before_each = :before_each_ivar }
it "adds shared class methods to nested group" do
shared_examples_for("thing") do
def self.foo; end
end

group.run_all
results.should == {
:subject => :the_subject,
:foo => :foo_value,
:before_each => :before_each_ivar
}
group = ExampleGroup.describe('fake group')
shared_group = group.it_should_behave_like("thing").first
shared_group.methods.should include("foo")
end

describe "running shared examples", :pending => true do
module ::RunningSharedExamplesJustForTesting; end

let(:group) do
ExampleGroup.describe("example group")
end

before(:each) do
group.share_examples_for("it runs shared examples") do
include ::RunningSharedExamplesJustForTesting

class << self
def magic
$magic ||= {}
end

def count(scope)
@counters ||= {
:before_all => 0,
:before_each => 0,
:after_each => 0,
:after_all => 0
}
@counters[scope] += 1
end
end

# TODO - necessary?
def magic
$magic ||= {}
end

def count(scope)
self.class.count(scope)
context "given a block" do
it "evaluates the block in nested group" do
scopes = []
shared_examples_for("thing") do
it("gets run in the nested group") do
scopes << self.class
end

before(:all) { magic[:before_all] = "before all #{count(:before_all)}" }
before(:each) { magic[:before_each] = "before each #{count(:before_each)}" }
after(:each) { magic[:after_each] = "after each #{count(:after_each)}" }
after(:all) { magic[:after_all] = "after all #{count(:after_all)}" }
end
end

before do
group.it_should_behave_like "it runs shared examples"
group.it "has one example" do; end
group.it "has another example" do; end
group.it "includes modules, included into shared example_group, into current example_group", :compat => 'rspec-1.2' do
raise "FAIL" unless example.example_group.included_modules.include?(RunningSharedExamplesJustForTesting)
group = ExampleGroup.describe("group") do
it_should_behave_like "thing" do
it("gets run in the same nested group") do
scopes << self.class
end
end
end
group.run_all
end

let(:shared_group) { group.children.first }

it "runs before(:all) only once from shared example_group", :compat => 'rspec-1.2' do
shared_group.magic[:before_all].should eq("before all 1")
end

it "runs before(:each) from shared example_group", :compat => 'rspec-1.2' do
group.magic[:before_each].should eq("before each 3")
end

it "runs after(:each) from shared example_group", :compat => 'rspec-1.2' do
group.magic[:after_each].should eq("after each 3")
end

it "runs after(:all) only once from shared example_group", :compat => 'rspec-1.2' do
group.magic[:after_all].should eq("after all 1")
end

it "makes methods defined in the shared example_group available in consuming example_group", :compat => 'rspec-1.2' do
group.magic.should be_a(Hash)
scopes[0].should be(scopes[1])
end

end

it "raises when named shared example_group can not be found" do
group = ExampleGroup.describe("example_group")
lambda do
group.it_should_behave_like("a group that does not exist")
end.should raise_error(/Could not find shared example group named/)
end
end

end

end

0 comments on commit 4668138

Please sign in to comment.