A simple kata in Ruby

Yesterday I moved on from Java to Ruby. After running through a few Ruby Koans, I decided to attempt the Coin Change Kata. This quickly led me to want to set up a reasonable development environment. Part one was getting Vim and Tmux to play nicely. Part two was getting a reasonable TDD workflow up and running. This excellent article formed the basis of the steps outlined below.

Step 1

Create a directory coin_change/, initialise as a git repo, add Github’s Ruby .gitignore and then commit the changes.

Step 2

Create a simple Gemfile, which describes the basic dependencies for the application:

source "https://rubygems.org"
gem 'rspec'
group :development do
gem 'guard'
gem 'guard-rspec'
end

To install the dependencies, run: bundle install. The group :development, allows us to describe dependencies that only need to be installed during development. To install just the core dependencies (in this case, just rspec), we would run bundle install — without development.

Step 3:

Initialise an RSpec project by running rspec --init. This creates the following files:

spec/
|- spec_helper.rb
.rspec

The spec_helper.rb contains standard boilerplate, which isn’t needed, so can be replaced with this single line:

$: << File.join(File.dirname(__FILE__), '..', 'lib')

This appends ../lib to the front of any require, so avoids the need to provide paths to files from the project root in our tests (see below for an example).

The default .rspec file makes sure that all test files, when run have the spec_helper.rb file required by default.

Step 4:

Add a Guardfile. The Guard file describes the files to watch for changes and the action to take when a change is detected. It should like this:

guard 'rspec', cmd: 'rspec' do
# watch /lib/files
watch(%r{^lib/(.+).rb$}) do |m|
"spec/#{m[1]}_spec.rb"
end
  # watch /spec/ files
watch(%r{^spec/(.+).rb$}) do |m|
"spec/#{m[1]}.rb"
end
end

Step 5:

Run the test suite with bundle exec guard, which waits for changes.

Then write a first test. This example uses the coin change kata, so a first simple test in RSpec spec/coin_change_spec.rb might look like this:

require 'coin_change' # Nb: no need for full path due to spec_helper
describe CoinChange do
describe '#change' do
it 'when no change due' do
expect(CoinChange.new(0).coins).to eql({})
end
end
end

On save Guard should run RSpec, which reports that there is no coin_change file.

Step 6:

To make the first test pass, create a file lib/coin_change.rb, with the following content:

class CoinChange
attr_reader :name
  def initialize(amount)
@coins = {}
end
end

On save, this first test should now pass!

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.