diff --git a/bin/StringCalculator.class b/bin/StringCalculator.class index a937b0c..79a8158 100644 Binary files a/bin/StringCalculator.class and b/bin/StringCalculator.class differ diff --git a/bin/StringCalculatorTest.class b/bin/StringCalculatorTest.class index d44b83f..e21a1f7 100644 Binary files a/bin/StringCalculatorTest.class and b/bin/StringCalculatorTest.class differ diff --git a/src/StringCalculator.java b/src/StringCalculator.java index 487916b..06b05f9 100644 --- a/src/StringCalculator.java +++ b/src/StringCalculator.java @@ -1,9 +1,72 @@ +// 1. The method can take 0, 1 or 2 numbers, and will return their sum (for an empty string it will +// return 0) for example “” or “1” or “1,2” +// 2. Add method to handle an unknown amount of numbers +// 3. Add method to handle new lines between numbers (instead of commas). +// 1. the following input is ok: “1\n2,3” (will equal 6) +// 2. the following input is NOT ok: “1,\n” +// 4. Calling Add with a negative numbers or invalid input (not numbers) will throw an +// StringCalculatorException + +import java.util.ArrayList; +import java.util.regex.*; + public class StringCalculator { - public int add(String numbersStr) { - // Returns the sum of the numbers given in numbersStr - - // not yet implemented - return 0; - } + public int add(String numbersStr) throws StringCalculatorException { + if (!isInputValid(numbersStr)) { + throw new StringCalculatorException(); + } + int[] numbers = getNumbers(numbersStr); + int sum = addNumbers(numbers); + return sum; + } + + public boolean isInputValid(String input) { + // The empty string is valid. + if (input.equals("")) { + return true; + } + Matcher matcher = Pattern.compile("([0-9]+)").matcher(input); + int count = 0; + while (matcher.find()) { + count++; + } + // If this is not 0, 1 or 2, it is invalid. + if (count < 0 || count > 2) { + return false; + } + + // If the string doesn't start or end with a number, it is invalid. + boolean numberAtStart = Pattern.compile("^([0-9]+)").matcher(input).find(); + boolean numberAtEnd = Pattern.compile("([0-9]+)$").matcher(input).find(); + + return numberAtStart && numberAtEnd; + } + + public int[] getNumbers(String input) { + ArrayList list = new ArrayList(); + Matcher matcher = Pattern.compile("([0-9]+)").matcher(input); + while (matcher.find()) { + for (int i = 0; i < matcher.groupCount(); i++) { + String match = matcher.group(i); + list.add(Integer.parseInt(match)); + } + } + int[] returnList = new int[list.size()]; + for (int i = 0; i < returnList.length; i++) { + returnList[i] = list.get(i); + } + return returnList; + } + + public int addNumbers(int[] numbers) { + if (numbers.length == 0) { + return 0; + } + int sum = 0; + for (int i : numbers) { + sum += i; + } + return sum; + } } diff --git a/tests/StringCalculatorTest.java b/tests/StringCalculatorTest.java index 4ec9afe..8f2f241 100644 --- a/tests/StringCalculatorTest.java +++ b/tests/StringCalculatorTest.java @@ -1,12 +1,134 @@ import static org.junit.Assert.*; - import org.junit.Test; public class StringCalculatorTest { + @Test + public void isInputValid_ReturnsTrueForEmptyInput() { + StringCalculator calc = new StringCalculator(); + boolean result = calc.isInputValid(""); + assertTrue("Empty string returned false.", result); + } + + @Test + public void isInputValid_ReturnsTrueForOneNumber() { + StringCalculator calc = new StringCalculator(); + boolean result = calc.isInputValid("1"); + assertTrue("One number string returned false.", result); + } + + @Test + public void isInputValid_ReturnsTrueForTwoNumbers() { + StringCalculator calc = new StringCalculator(); + boolean result = calc.isInputValid("3,13"); + assertTrue("Two number string returned false.", result); + } + + @Test + public void isInputValid_ReturnsFalseForThreeNumbers() { + StringCalculator calc = new StringCalculator(); + boolean result = calc.isInputValid("8, 1, 3"); + assertFalse("Three number string returned true.", result); + } + + @Test + public void isInputValid_ReturnsFalseIfNoNumberAtStart() { + StringCalculator calc = new StringCalculator(); + boolean result = calc.isInputValid(", 1, 3"); + assertFalse("No number at start string returned true.", result); + } + + @Test + public void isInputValid_ReturnsFalseIfNoNumberAtEnd() { + StringCalculator calc = new StringCalculator(); + boolean result = calc.isInputValid("3,4,"); + assertFalse("No number at end string returned true.", result); + } + + @Test + public void getNumbers_ReturnsEmptyArrayForNoNumbers() throws StringCalculatorException { + StringCalculator calc = new StringCalculator(); + int[] numbers = calc.getNumbers(""); + int[] expected = new int[] {}; + assertArrayEquals(expected, numbers); + } + + @Test + public void getNumbers_ReturnsTheNumbersForOneNumber() throws StringCalculatorException { + StringCalculator calc = new StringCalculator(); + int[] numbers = calc.getNumbers("3"); + int[] expected = new int[] { 3 }; + assertArrayEquals(expected, numbers); + } + + @Test + public void getNumbers_ReturnsTheNumbersForTwoNumbers() throws StringCalculatorException { + StringCalculator calc = new StringCalculator(); + int[] numbers = calc.getNumbers("8, 10"); + int[] expected = new int[] { 8, 10 }; + assertArrayEquals(expected, numbers); + } + + @Test + public void addNumbers_AddsNumbersForEmptyArray() { + StringCalculator calc = new StringCalculator(); + int[] numbers = new int[] {}; + int sum = calc.addNumbers(numbers); + assertEquals(0, sum); + } + + @Test + public void addNumbers_AddsNumbersForOneNumber() { + StringCalculator calc = new StringCalculator(); + int[] numbers = new int[] { 3 }; + int sum = calc.addNumbers(numbers); + assertEquals(3, sum); + } - @Test - public void test() { - fail("Not yet implemented"); - } + @Test + public void addNumbers_AddsNumbersForTwoNumbers() { + StringCalculator calc = new StringCalculator(); + int[] numbers = new int[] { 8, 1 }; + int sum = calc.addNumbers(numbers); + assertEquals(9, sum); + } + @Test + public void add_IsCorrectForNoNumbers() throws StringCalculatorException { + StringCalculator calc = new StringCalculator(); + int result = calc.add(""); + assertEquals(0, result); + } + @Test + public void add_IsCorrectForOneNumber() throws StringCalculatorException { + StringCalculator calc = new StringCalculator(); + int result = calc.add("4"); + assertEquals(4, result); + } + @Test + public void add_IsCorrectForTwoNumbers() throws StringCalculatorException { + StringCalculator calc = new StringCalculator(); + int result = calc.add("5,6"); + assertEquals(11, result); + } + @Test + public void add_IsCorrectForTwoNumbersLineSeparator() throws StringCalculatorException { + StringCalculator calc = new StringCalculator(); + int result = calc.add("4\n8"); + assertEquals(12, result); + } + @Test(expected = StringCalculatorException.class) + public void add_ThrowsForTooManyNumbers() throws StringCalculatorException { + StringCalculator calc = new StringCalculator(); + int result = calc.add("4,5,6"); + } + @Test(expected = StringCalculatorException.class) + public void add_ThrowsForNoNumberAtStart() throws StringCalculatorException { + StringCalculator calc = new StringCalculator(); + int result = calc.add(",6,8"); + } + @Test(expected = StringCalculatorException.class) + public void add_ThrowsForNoNumberAtEnd() throws StringCalculatorException { + StringCalculator calc = new StringCalculator(); + int result = calc.add("4,5,"); + } }