Created
July 5, 2016 01:07
-
-
Save iamkevinlowe/72b2f39e53915003ba94e275afac7551 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# http://osherove.com/tdd-kata-1/ | |
class StringCalculator | |
def add(string) | |
# Default delimiters to split string | |
delims = %w(, \n) | |
# If string begins with "//[delimiter]\n" include delimiter to array of delimiters | |
if string.match(/^\/\/.+/) | |
match, string = string.split('\n', 2) | |
delims.concat(match.to_s[3..-2].split('][')) | |
end | |
# Gets accepted numbers from string | |
numbers = string.split(Regexp.union(delims)).map(&:to_i).reject { |n| n > 1000 } | |
# Gets any negative numbers | |
negatives = numbers.select { |n| n < 0 } | |
# Raises an ArgumentError if negative numbers are found | |
raise ArgumentError.new "negatives not allowed: #{negatives.join(', ')}" unless negatives.none? | |
# Returns sum of numbers | |
numbers.inject(0) { |sum, num| sum += num } | |
end | |
end | |
# class Test | |
# attr_reader :pass_count, :fail_count | |
# def initialize(calc) | |
# @pass_count = @fail_count = 0 | |
# @calc = calc | |
# end | |
# def this(desc, method, string, expected) | |
# puts "Test: #{desc}" | |
# begin | |
# actual = @calc.send(method, string) | |
# rescue ArgumentError => e | |
# actual = e.message | |
# end | |
# if actual == expected | |
# puts "\tPassed!\n\n" | |
# @pass_count += 1 | |
# else | |
# puts "\tFailed! Expected #{actual} to equal #{expected}\n\n" | |
# @fail_count += 1 | |
# end | |
# end | |
# end | |
# test = Test.new(StringCalculator.new) | |
# test.this("expect empty string to equal 0", 'add', '', 0) | |
# test.this("expect '1' to equal 1", 'add', '1', 1) | |
# test.this("expect '1,2' to equal 3", 'add', '1,2', 3) | |
# test.this("expect '1,2,3' to equal 6", 'add', '1,2,3', 6) | |
# rand_array = (1..rand(10) + 1).map { |n| n * rand(10) } | |
# test.this("expect an unknown amount of numbers to pass", 'add', rand_array.join(','), rand_array.inject(&:+)) | |
# test.this("expect '1\\n2,3' to equal 6", 'add', '1\n2,3', 6) | |
# test.this("expect '//[;]\\n1;2' to equal 3", 'add', '//[;]\n1;2', 3) | |
# test.this("expect negative numbers to throw an exception", 'add', '-1', 'negatives not allowed: -1') | |
# test.this("expect numbers bigger than 1000 to be ignored", 'add', '2,1001', 2) | |
# test.this("expect '//[***]\\n1***2***3' to equal 6", 'add', '//[***]\n1***2***3', 6) | |
# test.this("expect '//[*][%]\\n1*2%3' to equal 6", 'add', '//[*][%]\n1*2%3', 6) | |
# test.this("expect multiple delimiters with lengths longer than one character to pass", 'add', '//[@@@][*][^^]\n1@@@2*3^^4', 10) | |
# puts "#{test.pass_count} tests passed. #{test.fail_count} tests failed." | |
require 'minitest/autorun' | |
describe StringCalculator do | |
let(:calc) { StringCalculator.new } | |
describe "when given an empty string" do | |
it "returns zero" do | |
calc.add('').must_equal 0 | |
calc.add(' ').must_equal 0 | |
calc.add(' ').must_equal 0 | |
end | |
end | |
describe "when given a single number string" do | |
it "returns the number" do | |
calc.add('1').must_equal 1 | |
calc.add('2').must_equal 2 | |
calc.add('345').must_equal 345 | |
end | |
end | |
describe "when given a two number string" do | |
it "returns the sum of the two numbers" do | |
calc.add('1,2').must_equal 3 | |
calc.add('2,3').must_equal 5 | |
calc.add('45,67').must_equal 112 | |
end | |
end | |
describe "when given a three number string" do | |
it "returns the sum of the three numbers" do | |
calc.add('1,2,3').must_equal 6 | |
calc.add('4,5,6').must_equal 15 | |
calc.add('78,90,12').must_equal 180 | |
end | |
end | |
describe "when given an unknown amount of numbers string" do | |
it "returns the sum of the numbers" do | |
3.times do | |
rand_array = 1.upto(rand(10) + 1).map { |n| n * rand(10) } | |
calc.add(rand_array.join(',')).must_equal rand_array.inject(&:+) | |
end | |
end | |
end | |
describe "when given a string of with '\\n'" do | |
it "returns the sum of the numbers delimited by '\\n' and ','" do | |
calc.add('1\n2,3').must_equal 6 | |
calc.add('4\n5\n6').must_equal 15 | |
calc.add('7,8\n9').must_equal 24 | |
end | |
end | |
describe "when given a string that starts with '//[;]\\n'" do | |
it "returns the sum of the numbers delimited by ';', '\\n' and ','" do | |
calc.add('//[;]\n1;2').must_equal 3 | |
calc.add('//[;]\n3,4;5\n6').must_equal 18 | |
calc.add('//[;]\n7;8;9;0').must_equal 24 | |
end | |
end | |
describe "when given a string with negative numbers" do | |
it "raises an ArgumentError error" do | |
3.times do | |
negatives = 1.upto(rand(10) + 1).map { |n| -(n * rand(10) + 1) } | |
err = assert_raises(ArgumentError) { calc.add(negatives.join(',')) } | |
err.message.must_equal "negatives not allowed: #{negatives.join(', ')}" | |
end | |
end | |
end | |
describe "when given a string with a number greater than 1000" do | |
it "ignores numbers greater than 1000 and returns the sum" do | |
calc.add('1,1001').must_equal 1 | |
calc.add('2,1000').must_equal 1002 | |
calc.add('1001,2002,3003').must_equal 0 | |
end | |
end | |
describe "when given a string with a multi character custom delimiter" do | |
it "delimits the string with the multi character delimiter and returns the sum" do | |
calc.add('//[***]\n1***2').must_equal 3 | |
calc.add('//[***]\n3,4***5').must_equal 12 | |
calc.add('//[abc]\n6abc7\n8abc9').must_equal 30 | |
end | |
end | |
describe "when given a string with multiple custom delimiters" do | |
it "delimits the string with custom delimiters and returns the sum" do | |
calc.add('//[*][%]\n1*2%3').must_equal 6 | |
calc.add('//[*][%]\n4*5*6%7%8').must_equal 30 | |
calc.add('//[!][@][#][$][%][^][&][*]\n1!2@3#4$5%6^7&8*9').must_equal 45 | |
end | |
end | |
describe "when given a string with multiple custom delimiters of multiple characters each" do | |
it "delimits the string with custom delimiters and returns the sum" do | |
calc.add('//[@@@][*][^^]\n1@@@2*3^^4').must_equal 10 | |
calc.add('//[!!!][;;][!@#]\n5!!!6;;7!@#8').must_equal 26 | |
calc.add('//[***][**][*]\n1***2**3*4').must_equal 10 | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment