Skip to content

Instantly share code, notes, and snippets.

@futureperfect
Created June 16, 2015 23:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save futureperfect/9f358ac315b4a72bd26a to your computer and use it in GitHub Desktop.
Save futureperfect/9f358ac315b4a72bd26a to your computer and use it in GitHub Desktop.
String Calculator Kata

String Calculator

This is my first implementation of this String Calculator Code Kata.

It was written as TDD with Guard driving Minitest.

module StringCalculator
def add
raise_if_negatives_present
return digits_less_than_or_equal_to_1000.reduce 0, :+
end
private
def digits
@digits ||= gsub(/[\n]/, delimiter).split(delimiter).map { |item| item.to_i }
end
def digits_less_than_or_equal_to_1000
digits.select { |x| x <= 1000 }
end
def negatives
@negatives ||= digits.select { |x| x < 0 }
end
def raise_if_negatives_present
raise "Cannot have negative numbers: #{negatives}" if negatives.any?
end
def delimiter
@delimiter ||= self[0,2] == '//' ? self[2,1] : ','
end
end
# coding: utf-8
require "minitest/autorun"
require "./string_calculator"
class String
include StringCalculator
end
class TestStringCalculator < Minitest::Test
def test_empty_string_returns_zero
assert_equal 0, "".add
end
def test_single_character_numeric_string_returns_number
assert_equal 4, "4".add
end
def test_two_character_numerics_string_returns_number
assert_equal 14, "14".add
end
def test_three_character_numeric_string_returns_number
assert_equal 123, "123".add
end
def test_adds_two_comma_delimited_single_numbers
assert_equal 3, "1,2".add
end
def test_adds_larger_single_digit_comma_delimited_numbers
assert_equal 12, "7,5".add
end
def test_adds_collection_of_comma_delimited_numbers
assert_equal 7, "1,2,4".add
end
def test_handles_newlines_as_delimiters
assert_equal 3, "1\n2".add
end
def test_handles_mixed_delimiters
assert_equal 9, "1,6\n2".add
end
def test_handles_alternate_delimiters
assert_equal 6, "//;\n1;2;3".add
end
def test_raises_error_with_negative_number
assert_raises { "-1".add }
end
def test_raises_error_with_negative_numbers_and_includes_negatives_in_message
error = assert_raises(RuntimeError) {"-1,-7".add }
regex = /Cannot have negative numbers\: \[-1, -7\]/
assert_match regex, error.message
end
def test_includes_all_negative_numbers_in_raised_error_message
error = assert_raises(RuntimeError) {"-1,-7,9,-27".add }
regex = /Cannot have negative numbers\: \[-1, -7, -27\]/
assert_match regex, error.message
end
def test_ignores_single_numbers_greater_than_1000
assert_equal 0, "1001".add
end
def test_ignores_numbers_greater_than_1000_in_expressions
assert_equal 5, "1001,5".add
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment