String Calculator Kata
Here's a sample solution for the String Calculator Kata that I'm using with cyber-dojo, in C# using NUnit as the test framework.
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class NegativesNotAllowedException : Exception
{
}
/// <summary>
/// Calculators the sum of up to two numbers in a formatted string
/// </summary>
public class StringCalculator
{
/// <summary>
/// Examples:
/// Empty string returns 0.
/// "1" returns 1
/// "1,2" returns 3
/// "1\n2,3" returns 6
/// Negative numbers throw a NegativesNotAllowed exception
/// </summary>
/// <param name="numbers"></param>
/// <returns></returns>
public int Add(string numbers)
{
int sum = 0;
if (!string.IsNullOrWhiteSpace(numbers))
{
var splits = numbers.Split(new char[] { ',', '\n' });
foreach (string number in splits)
{
int newNumber = 0;
try
{
newNumber = Convert.ToInt32(number);
}
catch (FormatException)
{
newNumber = 0;
}
if (newNumber < 0)
{
throw new NegativesNotAllowedException();
}
sum += newNumber;
}
}
return sum;
}
}
Tests
using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
[TestFixture]
public class StringCalculatorSpecimenTests
{
[Test]
public void StringCalculator_Add_Empty_String_Returns_Zero()
{
var sc = new StringCalculator();
Assert.AreEqual(0, sc.Add(string.Empty));
}
[Test]
public void StringCalculator_Add_Non_Numeric_Returns_Zero()
{
var sc = new StringCalculator();
Assert.AreEqual(0, sc.Add("a,b,c"));
}
[Test]
public void StringCalculator_Add_OneNumber_One_ReturnsOne()
{
var sc = new StringCalculator();
Assert.AreEqual(1, sc.Add("1"));
}
[Test]
public void StringCalculator_Add_OneNumber_Five_ReturnsFive()
{
var sc = new StringCalculator();
Assert.AreEqual(5, sc.Add("5"));
}
[Test]
public void StringCalculator_Add_TwoNumbers_OneTwo_ReturnsThree()
{
var sc = new StringCalculator();
Assert.AreEqual(3, sc.Add("1,2"));
}
[Test]
public void StringCalculator_Add_ThreeNumbers_OneTwoThree_ReturnsSix()
{
var sc = new StringCalculator();
Assert.AreEqual(6, sc.Add("1,2,3"));
}
[Test]
public void StringCalculator_Add_Three_Numbers_NewLine_OneTwoThree_Returns_Six()
{
var sc = new StringCalculator();
Assert.AreEqual(6, sc.Add("1\n2,3"));
}
[Test]
public void StringCalculator_Add_Three_Numbers_Whitespace_OneTwoThree_Returns_Six()
{
var sc = new StringCalculator();
Assert.AreEqual(6, sc.Add(" 1, 2,3 "));
}
[Test]
[ExpectedException(typeof(NegativesNotAllowedException))]
public void StringCalculator_Add_One_Negative_Number_Throws_Exception()
{
var sc = new StringCalculator();
sc.Add("-1");
Assert.Fail("Expecting Exception");
}
[Test]
[ExpectedException(typeof(NegativesNotAllowedException))]
public void StringCalculator_Add_Two_Numbers_Negative_First_Throws_Exception()
{
var sc = new StringCalculator();
sc.Add("-1, 9");
Assert.Fail("Expecting Exception");
}
[Test]
[ExpectedException(typeof(NegativesNotAllowedException))]
public void StringCalculator_Add_Two_Numbers_Negative_Second_Throws_Exception()
{
var sc = new StringCalculator();
sc.Add("2,-7");
Assert.Fail("Expecting Exception");
}
}