Skip to content

Instantly share code, notes, and snippets.

@mowat27
Created August 25, 2013 21:14
Show Gist options
  • Select an option

  • Save mowat27/6336350 to your computer and use it in GitHub Desktop.

Select an option

Save mowat27/6336350 to your computer and use it in GitHub Desktop.
Implemented the word count kata using red-refactor-green and dependency injection. I think I went wrong with the count class - it's a value object wrapping a Hash. Next time, I'll try wrapping the actual word count.
require 'rspec-given'
describe "word counter" do
Given(:word_counter) { WordCounterFactory.new.create }
Then { word_counter.count("one") == {"one" => 1} }
Then { word_counter.count("one fish") == {"one" => 1, "fish" => 1} }
Then { word_counter.count("one fish fish") == {"one" => 1, "fish" => 2} }
Then { word_counter.count("one fish,fish") == {"one" => 1, "fish" => 2} }
Then { word_counter.count("one fish Fish") == {"one" => 1, "fish" => 2} }
Then { word_counter.count("one fish Fish") == {"one" => 1, "fish" => 2} }
Then { word_counter.count("one fish &$%Fish") == {"one" => 1, "fish" => 2} }
end
class WordCounterFactory
def create
parser = Parser.new(Count.new, ->(text) { text.split(/\W+/).map(&:downcase) } )
WordCounter.new(parser)
end
end
class WordCounter
def initialize(parser)
@parser = parser
end
def count(text)
@parser.parse(text).to_hash
end
end
class Parser
def initialize(count, split_fn)
@count = count
@split_fn = split_fn
end
def parse(text)
@split_fn.call(text).inject(@count) do |count, word|
count.increment(word)
end
end
end
class Count
def initialize(count = {})
@count = count.to_hash
@count.default = 0
end
def increment(word)
@count[word] += 1
Count.new(self)
end
def to_hash
@count.clone
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment