[TestFixture]
public class StringCalculatorTests
{
private static StringCalculator MakeCalc()
{
return new StringCalculator();
}
[Test]
public void Add_EmptyString_ReturnsZero()
{
//start with this even though StringCalculator doesn't exist yet
StringCalculator sc = MakeCalc();
//method doesn't exist
int result = sc.Add("");
//first kind of syntax
//Assert.AreEqual(0, result);
//second kind of syntax
Assert.That(result, Is.EqualTo(0));
}
[TestCase("1",1)]
[TestCase("2", 2)]
public void Add_SingleNumber_ReturnsThatSingleNumber(string numbers, int expected)
{
StringCalculator sc = MakeCalc();
int result = sc.Add(numbers);
Assert.AreEqual(expected, result);
}
[TestCase("1,2",3)]
[TestCase("1,3",4)]
[TestCase("4,5",9)]
[TestCase("14,44",58)]
[TestCase("1,2,3", 6)]
[TestCase("1,2,3,4,5", 15)]
public void Add_MultipleNumbers_ReturnsTheSum(string numbers, int expected)
{
StringCalculator sc = MakeCalc();
int result = sc.Add(numbers);
Assert.AreEqual(expected, result);
}
[Test]
public void Add_TwoNumbersWithLineFeedDelimeter_ReturnsTheSum()
{
StringCalculator sc = MakeCalc();
int result = sc.Add("1\n2");
Assert.AreEqual(3, result);
}
[TestCase("1\n3", 4)]
[TestCase("1\n2\n3", 6)]
[TestCase("1\n222\n3\n20", 246)]
public void Add_MultipleNumbersWithLineFeedDelimeter_ReturnsTheSum(string numbers, int expected)
{
StringCalculator sc = MakeCalc();
int result = sc.Add(numbers);
Assert.AreEqual(expected, result);
}
[Test]
public void Add_TwoNumbersWithGeneralDelimeter_ReturnsTheSum()
{
StringCalculator sc = MakeCalc();
int result = sc.Add("//;\n1;2");
Assert.AreEqual(3, result);
}
[TestCase("//;\n1;2", 3)]
[TestCase("//;\n1;2;3", 6)]
[TestCase("//;\n1;2;3;20", 26)]
[TestCase("//x\n1x2x3x20", 26)]
public void Add_MultipleNumbersWithGeneralDelimeter_ReturnsTheSum(string numbers, int expected)
{
StringCalculator sc = MakeCalc();
int result = sc.Add(numbers);
Assert.AreEqual(expected, result);
}
[Test]
public void Add_NegativeNumber_ThrowsCorrectExceptionWithNegativeNumber()
{
StringCalculator sc = MakeCalc();
Exception exception = Assert.Throws<Exception>(delegate
{
sc.Add("-1");
});
Assert.AreEqual("Negatives not allowed: -1", exception.Message);
}
[Test]
public void Add_MultipleNegativeNumbers_ThrowsAnExceptionWithAllNegativeNumbers()
{
StringCalculator sc = MakeCalc();
Exception exception = Assert.Throws<Exception>(delegate
{
sc.Add("-1,-2");
});
Assert.AreEqual("Negatives not allowed: -1, -2", exception.Message);
}
[TestCase("-1,-2", "-1, -2")]
[TestCase("-1,-2,-3", "-1, -2, -3")]
[TestCase("-1,2,-3", "-1, -3")]
public void Add_MixedMultipleNegativeAndPositiveNumbers_ThrowsAnExceptionWithAllNegativeNumbers(string numbers, string expected)
{
StringCalculator sc = MakeCalc();
Exception exception = Assert.Throws<Exception>(delegate
{
sc.Add(numbers);
});
Assert.AreEqual("Negatives not allowed: " + expected, exception.Message);
}
}
public class StringCalculator
{
public int Add(string numbers)
{
string delimeter;
if (numbers.Contains("//"))
{
delimeter = numbers.Substring(2, 1);
numbers = numbers.Substring(4, numbers.Length-4);
numbers = numbers.Replace(delimeter, ",");
}
else if (numbers.Contains("\n"))
numbers = numbers.Replace("\n", ",");
if (numbers.Length == 0)
return 0;
if (numbers.Length == 1)
return int.Parse(numbers);
if (numbers.Length == 2)
{
int i = int.Parse(numbers);
if (i < 0)
throw new Exception("Negatives not allowed: " + i.ToString());
return i;
}
string[] listOfNumbers = numbers.Split(',');
string errorMesssage = "Negatives not allowed: ";
bool showErrorMessage = false;
foreach (var number in listOfNumbers)
{
int i = int.Parse(number);
if (i < 0)
{
errorMesssage += i.ToString() + ", ";
showErrorMessage = true;
}
}
//get rid of final comma and space
if (showErrorMessage)
{
errorMesssage = errorMesssage.Substring(0, errorMesssage.Length - 2);
throw new Exception(errorMesssage);
}
int sumOfNumbers = 0;
foreach (var number in listOfNumbers)
sumOfNumbers += int.Parse(number);
return sumOfNumbers;
}
}