ArticleS. DavidChelimsky.

### Bowling with rSpec

Now THIS is fun. Here's the bowling game test driven in Ruby with the new rspec (v0.5).
Spec using v0.5
NOTE - updated on 4/15/2006 - see "Spec using v0.4" for the original post

`require 'spec'context "A bowling score calculator" do  setup do    @game = Game.new  end  specify "should score 0 for an all gutter game" do    (1..20).each { @game.roll(0) }    @game.score.should.be 0  end  specify "should score 20 for an all ones game" do    (1..20).each { @game.roll(1) }    @game.score.should.be 20  end  specify "should score 150 for an all fives game" do    (1..21).each { @game.roll(5) }    @game.score.should.be 150  end  specify "should score 300 for a perfect game" do    (1..12).each { @game.roll(10) }    @game.score.should.be 300  endend`
Spec using v0.4
Solution
!commentForm
Fri, 3 Mar 2006 16:27:14, Dave Astels, A recursive solution
When David showed me this, I immediately thought "A recursive solution would probably be cleaner and more understandable". So here it is.
`require 'spec'class GameSpec < Spec::Context  def setup    @game = Game.new  end  def gutter_game_score_should_be_zero    (1..20).each { @game.roll(0) }    @game.score.should.be 0  end  def all_ones_game_score_should_be_20    (1..20).each { @game.roll(1) }    @game.score.should.be 20  end  def all_fives_game_score_should_be_150    (1..21).each { @game.roll(5) }    @game.score.should.be 150  end  def perfect_game_score_should_be_300   (1..12).each { @game.roll(10) }    @game.score.should.be 300  endendclass Game  def initialize    @rolls = []  end  def roll(pins)    @rolls.push pins  end  def score    compute_score(1, @rolls)  end  def compute_score(frame, rolls)    return 0 if frame > 10    return do_strike(frame, rolls) if strike?(rolls)    return do_spare(frame, rolls) if spare?(rolls)    return do_regular_frame(frame, rolls)  end  def strike?(rolls)    rolls[0] == 10  end  def spare?(rolls)    rolls[0] + rolls[1] == 10  end  def do_strike(frame, rolls)    10 + rolls[1] + rolls[2] + compute_score(frame + 1, rolls[1..-1])  end  def do_spare(frame, rolls)    10 + rolls[2] + compute_score(frame + 1, rolls[2..-1])  end  def do_regular_frame(frame, rolls)    rolls[0] + rolls[1] + compute_score(frame + 1, rolls[2..-1])  endend`
Sat, 4 Mar 2006 18:02:18, Craig Demyanovich, Thanks and using require
First, thanks to the two of you for your work on this latest version of RSpec. Second, thanks for this example. I tried the bowling game in Ruby with Test::Unit some time ago. I'll compare what I did then with the examples here and see where it leads me.

Notice that David uses

require 'rubygems'
require_gem 'rspec'

while Dave uses

require 'spec'

In my previous experimentation with RSpec and another library available as a gem, I had to use require as David did, even though the example code showed the form that Dave uses. This is true with RSpec v. 0.4.0 for me. I installed it as a gem; I'm using Mac OS X 10.4.5 and Ruby 1.8.4 from DarwinPorts[?]. Any ideas why I can't just do

require 'spec'

require 'rubygems'
require_gem 'rspec'
Sun, 5 Mar 2006 15:30:52, Dave Astels, require 'rubygems'
you can avoid having to explicitly require rubygems by putting this in your env var setup:

RUBYOPT=rubygems

It doesn't seem to be ideal, though... but it does work.

IMHO gems is a package & deployment approach... libraries shouldn't depend on it.

Dave
Wed, 22 Mar 2006 18:25:59, Micah Martin, Man, that's small!
The amount of code I mean. Ruby rocks!
Sat, 15 Apr 2006 10:10:54, Aslak Hellesoy, Update the example - the syntax has changed!
We've got a new syntax for specs now. Take a peek at the examples over at http://rspec.rubyforge.org/

Aslak