Skip to content

Instantly share code, notes, and snippets.

@shicholas
Last active December 18, 2015 15:49
Show Gist options
  • Save shicholas/5806632 to your computer and use it in GitHub Desktop.
Save shicholas/5806632 to your computer and use it in GitHub Desktop.
LVRUG Kata 6/19/13 with many thanks to @marksim
module StringCalculator
String.class_eval do
def calc
raise NoNegativeNumbers.new(numbers.select{|n| n < 0}) if numbers.any?{|n| n < 0}
numbers.inject(0, &:+)
end
private
def numbers
if self.start_with?("//")
parts = self.split("\n")
parts.last.split(delimiter).map(&:to_i).reject{|n| n > 999}
else
self.split(delimiter).map(&:to_i).reject{|n| n > 999}
end
end
def delimiter
if self.start_with?("//")
parts = self.split("\n")
regex = parts.first.sub("//", "").sub("[]","|").sub("[", "").sub("]", "")
/[#{regex}]/
else
/[\n|,]/
end
end
end
end
class NoNegativeNumbers < Exception
def initialize(numbers)
@negative_numbers = numbers
end
def message
"No Negative Numbers: #{@negative_numbers.join(", ")}"
end
end
require 'spec_helper'
using StringCalculator
describe StringCalculator do
it 'should return zero for an empty string' do
"".calc.should eq 0
end
it 'should return 1 for "1"' do
"1".calc.should eq 1
end
it 'should return 3 for "1,2"' do
"1,2".calc.should eq 3
end
it 'should return 6 for "1,2,3"' do
"1,2,3".calc.should eq 6
end
it 'should return 6 for "1\n2,3"' do
"1\n2,3".calc.should eq 6
end
it 'should let one define their delimiter' do
"//;\n1;2;3".calc.should eq 6
"//s\n1s2s3".calc.should eq 6
end
it 'should let one define a delimiter within brackets' do
"//[n]\n1n2n3".calc.should eq 6
end
it 'should let one define multiple delimiters within brackets' do
"//[n][s]\n1n2s3".calc.should eq 6
"//[n][s][y]\n1n2s3y4".calc.should eq 10
end
it 'should raise NoNegativeNumbers for "-1,2,-3"' do
expect{"-1,2,-3".calc}.to raise_error NoNegativeNumbers, /-1, -3/
end
it 'should show correct error message for "-1,2,-4"' do
begin
"-1,2,-4".calc
rescue NoNegativeNumbers => e
e.message.should eq "No Negative Numbers: -1, -4"
end
end
it 'should reject numbers more than 999' do
"1,1000,2".calc.should eq 3
end
end
Sources
The Kata http://osherove.com/tdd-kata-1/
The String Class http://ruby-doc.org/core-2.0/String.html
The Array Class http://ruby-doc.org/core-2.0/Array.html
Symbol to Proc http://blog.thoughtfolder.com/2008-02-25-a-detailed-explanation-of-ruby-s-symbol-to-proc.html
The Exception Class http://www.ruby-doc.org/core-2.0/Exception.html
Rescuing Exceptions http://rubylearning.com/satishtalim/ruby_exceptions.html
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment