Skip to content

Instantly share code, notes, and snippets.

@alberto
Created January 4, 2011 19:26
Show Gist options
  • Select an option

  • Save alberto/765257 to your computer and use it in GitHub Desktop.

Select an option

Save alberto/765257 to your computer and use it in GitHub Desktop.
String Calculator Kata
require "test_notifier/runner/rspec"
TestNotifier.default_notifier = :notify_send
RSpec::Matchers.define :add_to do |expected|
match do |string|
string.add == expected
end
end
module AddableString
def add
numbers.inject(0) { |sum, number| sum + number }
end
private
def numbers
split(any_delimiter).map(&:to_i)
end
def any_delimiter
Regexp.union delimiters
end
def delimiters
return default_delimiters + singlechar_delimiter + bracketed_delimiters
end
def default_delimiters
[",", "\n"]
end
def singlechar_delimiter
has_custom_delimiters?? [self[2]] : []
end
def bracketed_delimiters
scan(/\[(.+?)\]/).map{ |m| m[0] }
end
def has_custom_delimiters?
start_with?("//")
end
end
class String
include AddableString
end
describe "String Calculator" do
it "should return 0 for ''" do
"".should add_to 0
end
context "can add one number" do
it "should return 1 for 1" do
"1".should add_to 1
end
it "should return 2 for 2" do
"2".should add_to 2
end
it "should return 42 for 42" do
"42".should add_to 42
end
end
context "can add two numbers" do
it "should return 2 for 1,1" do
"1,1".should add_to 2
end
it "should return 3 for 1,2" do
"1,2".should add_to 3
end
it "should return 12 for 1,11" do
"1,11".should add_to 12
end
end
context "can add any amount of numbers" do
it "should return 6 for 1,2,3" do
"1,2,3".should add_to 6
end
it "should return 200 for one-hundred twos" do
Array.new(2,100).join(',').should add_to 200
end
end
context "delimiters" do
it "supports \n as delimiter" do
"1\n2".should add_to 3
end
it "supports ; as delimiter" do
"//;\n1;2".should add_to 3
end
it "supports % as delimiter" do
"//%\n1%2".should add_to 3
end
context "delimiters of any length" do
it "supports ;: as delimiter" do
"//[;:]\n1;:2".should add_to 3
end
it "supports ::: as delimiter" do
"//[:::]\n1:::2".should add_to 3
end
end
context "multiple delimiters" do
it "supports %, & as delimiters" do
"//[%][&]\n1%2&3".should add_to 6
end
end
end
end
@alberto
Copy link
Copy Markdown
Author

alberto commented Jan 5, 2011

sí, ayer lo pensé mientras hacía la kata, pero decidí dejarlo para hoy :)

@xaviuzz
Copy link
Copy Markdown

xaviuzz commented Jan 6, 2011

El inject ya es bastante feo y poco semantico en su forma
def add
summands.inject { |sum, summand| sum + summand }
end
asi que cuando no necesites un valor inicial distinto del valor del primer elemento intenta no ofuscar hombre!! :)
mira que me parece feo el inject .. no hay alternativas mas semanticas??

@xaviuzz
Copy link
Copy Markdown

xaviuzz commented Jan 6, 2011

ahh y quiza podrias reforzar la prueba en el contexto an unknown amount of numbers

@alberto
Copy link
Copy Markdown
Author

alberto commented Jan 6, 2011

Sobre el inject, parece que no funciona sin el (0), ¿puede que porque summand es un string intente inicializar sum="" ? La verdad es que hasta hace 2 días que me lo comentó plagelao no lo conocía. No conozco nada mejor, tampoco me gusta mucho la semántica esa.

Sobre reforzar ese contexto, ¿qué echas en falta?

@alberto
Copy link
Copy Markdown
Author

alberto commented Jan 7, 2011

@xaviuzz el add que proponías devuelve nil en vez de 0 cuando summands == []

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment