[~/local/src/ruby/LPP/rspec_examples/rpcalculator(master)]$ cat lib/math/rpcalc.rb module Math class RPCalc attr_accessor :stack def initialize() @stack = [] end def calc(expr) @stack = [] expr.split(/\s+/).each do |x| case x when '+', '*', '-', '/' op2 = @stack.pop op1 = @stack.pop @stack.push eval "(#{op1} #{x} #{op2})" when /^-?\s*\d+(\.\d+)?([eE][+-]?\d+)?\s*$/ @stack.push x else raise SyntaxError, "Error. found '#{x}'. Expected number or operator" end end @stack.pop end end # class RPCalc end # Math
[~/local/src/ruby/LPP/rspec_examples/rpcalculator(master)]$ cat spec/math/rpcalc_spec.rb #require File.join(File.dirname(__FILE__), "/../spec_helper") require "spec_helper" module Math describe RPCalc do before :each do @c = Math::RPCalc.new end context "When an erroneous input is given" do before :each do @e = proc { @c.calc('a') } end it "must raise an exception" do expect { @e[] }.to raise_error(SyntaxError) expect { @e[] }.to raise_error("Error. found 'a'. Expected number or operator") end end context "When a correct input is given" do it "must give the correct answer for integer expressions" do r = @c.calc('2 3 + 4 *') r.should eq 20 @c.stack.should eq [] end it "must give the correct answer for float expressions" do r = @c.calc('4 3 + 2.5 3.5 +') r.should be_within(0.01).of(6.0) @c.stack.should eq [ 7 ] end end end # RPCalc end # Math
[~/local/src/ruby/LPP/rspec_examples/rpcalculator(master)]$ rake spec rspec -Ilib -Ispec spec/math/rpcalc_spec.rb Math::RPCalc When an erroneous input is given must raise an exception When a correct input is given must give the correct answer for integer expressions must give the correct answer for float expressions Finished in 0.00457 seconds 3 examples, 0 failures