-
-
Save alberto/765257 to your computer and use it in GitHub Desktop.
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 |
sí, ayer lo pensé mientras hacía la kata, pero decidí dejarlo para hoy :)
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??
ahh y quiza podrias reforzar la prueba en el contexto an unknown amount of numbers
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?
@xaviuzz el add que proponías devuelve nil en vez de 0 cuando summands == []
Yo estoy abriendo la clase String directamente :P
Eso hace que cambie bastante el código. Mañana intento subir un gist :)