Examples

Here is an example of a spec for a Stack. We start with a group of shared examples.
These won’t get run directly, but can be included by, and run in the context of
other example groups.

shared_examples_for "non-empty Stack" do

  it { @stack.should_not be_empty }
  
  it "should return the top item when sent #peek" do
    @stack.peek.should == @last_item_added
  end
  
  it "should NOT remove the top item when sent #peek" do
    @stack.peek.should == @last_item_added
    @stack.peek.should == @last_item_added
  end
  
  it "should return the top item when sent #pop" do
    @stack.pop.should == @last_item_added
  end
  
  it "should remove the top item when sent #pop" do
    @stack.pop.should == @last_item_added
    unless @stack.empty?
      @stack.pop.should_not == @last_item_added
    end
  end
  
end

shared_examples_for "non-full Stack" do

  it { @stack.should_not be_full }

  it "should add to the top when sent #push" do
    @stack.push "newly added top item"
    @stack.peek.should == "newly added top item"
  end

end

And here is the group that runs them. Note the nesting, which is a new feature in
RSpec 1.1.

require File.dirname(__FILE__) + '/spec_helper'
require File.dirname(__FILE__) + '/stack'
require File.dirname(__FILE__) + '/shared_stack_examples'

describe Stack do
  
  before(:each) do
    @stack = Stack.new
  end

  describe "(empty)" do

    it { @stack.should be_empty }
  
    it_should_behave_like "non-full Stack"
  
    it "should complain when sent #peek" do
      lambda { @stack.peek }.should raise_error(StackUnderflowError)
    end
  
    it "should complain when sent #pop" do
      lambda { @stack.pop }.should raise_error(StackUnderflowError)
    end

  end

  describe "(with one item)" do
    
    before(:each) do
      @stack.push 3
      @last_item_added = 3
    end

    it_should_behave_like "non-empty Stack"
    it_should_behave_like "non-full Stack"

  end

  describe "(with one item less than capacity)" do
    
    before(:each) do
      (1..9).each { |i| @stack.push i }
      @last_item_added = 9
    end
  
    it_should_behave_like "non-empty Stack"
    it_should_behave_like "non-full Stack"
  end

  describe "(full)" do
    
    before(:each) do
      (1..10).each { |i| @stack.push i }
      @last_item_added = 10
    end

    it { @stack.should be_full }  

    it_should_behave_like "non-empty Stack"

    it "should complain on #push" do
      lambda { @stack.push Object.new }.should raise_error(StackOverflowError)
    end
  
  end

end

And here is what you see when you run these examples in TextMate: