From 92f4b586e0b4c3628c0b8bfb9b09046ba09391e0 Mon Sep 17 00:00:00 2001 From: Kiree Date: Mon, 1 Oct 2018 12:26:25 +0300 Subject: [PATCH 1/5] [ASSIGNMENT FINISHED] :white_check_mark: Implemented the add method to StringCalculator.java :clipboard: Added unit tests for the StringCalculator.java :x: Added more ignored files to the .gitignore --- .gitignore | 22 ++++++++ src/StringCalculator.java | 47 +++++++++++++++-- tests/StringCalculatorTest.java | 93 ++++++++++++++++++++++++++++++++- 3 files changed, 155 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index cd2946a..3aa82af 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,25 @@ $RECYCLE.BIN/ Network Trash Folder Temporary Items .apdisk + +*.class + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +## IDE Specific +.idea +.settings +.project +.classpath + +## Excludes the generated files +bin/ \ No newline at end of file diff --git a/src/StringCalculator.java b/src/StringCalculator.java index 487916b..e88b11f 100644 --- a/src/StringCalculator.java +++ b/src/StringCalculator.java @@ -1,9 +1,46 @@ +import java.util.Arrays; +import java.util.List; public class StringCalculator { - public int add(String numbersStr) { - // Returns the sum of the numbers given in numbersStr - - // not yet implemented - return 0; + + /** + * add(String numbersStr) + * + * Adds the given numbers together. + * + * @param numbersStr - The numbers in a string + * @return The sum of the numbers + */ + public int add(String numbersStr) throws StringCalculatorException { + + final int[] sum = {0}; + String regex = "[0-9, /,]+"; + + // Check that the string is not null or empty + if (numbersStr != null && !numbersStr.isEmpty()) { + + // Replace whitespace with comma + numbersStr = numbersStr.replaceAll("\\s", ","); + + // Abort execution if string contains characters other than numbers [0-9] or comma [/,]. + if (!numbersStr.matches(regex)) { + throw new StringCalculatorException(); + } + + List numbersList = Arrays.asList(numbersStr.split(",")); // Assign the expected numbers to an array + + try { + numbersList.forEach((currentItem) -> { + if(!currentItem.isEmpty()) { + sum[0] = sum[0] + Integer.parseInt(currentItem); + } + }); + return sum[0]; // Return the sum of the items + } catch (NumberFormatException e) { + throw new StringCalculatorException(); // Throw an error on invalid characters. + } + } else { + return sum[0]; // Return 0 for null or empty string + } } } diff --git a/tests/StringCalculatorTest.java b/tests/StringCalculatorTest.java index 4ec9afe..87fa276 100644 --- a/tests/StringCalculatorTest.java +++ b/tests/StringCalculatorTest.java @@ -1,12 +1,101 @@ import static org.junit.Assert.*; +import org.junit.Before; import org.junit.Test; public class StringCalculatorTest { + private StringCalculator stringCalculator; + + @Before + public void initializeStringCalculator() { + stringCalculator = new StringCalculator(); + } + @Test - public void test() { - fail("Not yet implemented"); + public void testAdd_2NumbersString() throws StringCalculatorException { + //Arrange + String twoNumberString = "42,42"; + //Act + int returnedNumber = stringCalculator.add(twoNumberString); + //Assert + assertEquals("Returned number should be equal to the sum of the numbers in the string", 84, returnedNumber); + } + + @Test + public void testAdd_2NumbersStringWithWhiteSpace() throws StringCalculatorException { + //Arrange + String twoNumberString = "42, 42"; + //Act + int returnedNumber = stringCalculator.add(twoNumberString); + //Assert + assertEquals("Returned number should be equal to the sum of the numbers in the string", 84, returnedNumber); + } + + @Test + public void testAdd_1NumberString() throws StringCalculatorException { + //Arrange + String singleNumberString = "42"; + //Act + int returnedNumber = stringCalculator.add(singleNumberString); + //Assert + assertEquals("Returned number should be equal to given number.", Integer.parseInt(singleNumberString), returnedNumber); + } + + @Test + public void testAdd_NullString() throws StringCalculatorException { + //Arrange + String nullString = null; + //Act + int returnedNumber = stringCalculator.add(nullString); + //Assert + assertEquals("Returned number should be 0", 0, returnedNumber); + } + + @Test + public void testAdd_EmptyString() throws StringCalculatorException { + //Arrange + String emptyString = ""; + //Act + int returnedNumber = stringCalculator.add(emptyString); + //Assert + assertEquals("Returned number should be 0", 0, returnedNumber); + } + + @Test + public void testAdd_3NumbersStringWithWhitespace() throws StringCalculatorException { + //Arrange + String threeNumberString = "42,42, 42"; + //Act + int returnedNumber = stringCalculator.add(threeNumberString); + //Assert + assertEquals("Returned number should be equal to the sum of the numbers in the string", 126, returnedNumber); + } + + @Test + public void testAdd_stringWithNewLines() throws StringCalculatorException { + //Arrange + String threeNumberString = "42,42\n42"; + //Act + int returnedNumber = stringCalculator.add(threeNumberString); + //Assert + assertEquals("Returned number should be equal to the sum of the numbers in the string", 126, returnedNumber); + } + + @Test (expected = StringCalculatorException.class) + public void testAdd_NegativeNumber() throws StringCalculatorException { + //Arrange + String negativeNumberString = "-1"; + //Act + int returnedNumber = stringCalculator.add(negativeNumberString); + } + + @Test (expected = StringCalculatorException.class) + public void testAdd_InvalidInput() throws StringCalculatorException { + //Arrange + String invalidNumberString = "Hello there!"; + //Act + int returnedNumber = stringCalculator.add(invalidNumberString); } } From ed69739c1b4021285e6453facf4accf76165259c Mon Sep 17 00:00:00 2001 From: Kiree Date: Mon, 1 Oct 2018 12:35:03 +0300 Subject: [PATCH 2/5] [ASSIGNMENT FINISHED] :bug: Simplified error handling in the add method to StringCalculator.java --- src/StringCalculator.java | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/StringCalculator.java b/src/StringCalculator.java index e88b11f..ec0c69e 100644 --- a/src/StringCalculator.java +++ b/src/StringCalculator.java @@ -28,17 +28,13 @@ public int add(String numbersStr) throws StringCalculatorException { } List numbersList = Arrays.asList(numbersStr.split(",")); // Assign the expected numbers to an array + numbersList.forEach((currentItem) -> { + if(!currentItem.isEmpty()) { + sum[0] = sum[0] + Integer.parseInt(currentItem); + } + }); + return sum[0]; // Return the sum of the items - try { - numbersList.forEach((currentItem) -> { - if(!currentItem.isEmpty()) { - sum[0] = sum[0] + Integer.parseInt(currentItem); - } - }); - return sum[0]; // Return the sum of the items - } catch (NumberFormatException e) { - throw new StringCalculatorException(); // Throw an error on invalid characters. - } } else { return sum[0]; // Return 0 for null or empty string } From 3e3bbfdfc3d36e7fe9ce5189929daf829088ac77 Mon Sep 17 00:00:00 2001 From: Kiree Date: Mon, 8 Oct 2018 09:55:23 +0300 Subject: [PATCH 3/5] [Refactoring] :white_check_mark: Refactored StringCalculator.java to reduce code smells - Made the StringCalculator.java package private. - Consolidated the return value logic --- src/StringCalculator.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/StringCalculator.java b/src/StringCalculator.java index ec0c69e..388e834 100644 --- a/src/StringCalculator.java +++ b/src/StringCalculator.java @@ -1,7 +1,7 @@ import java.util.Arrays; import java.util.List; -public class StringCalculator { +class StringCalculator { /** * add(String numbersStr) @@ -11,7 +11,7 @@ public class StringCalculator { * @param numbersStr - The numbers in a string * @return The sum of the numbers */ - public int add(String numbersStr) throws StringCalculatorException { + int add(String numbersStr) throws StringCalculatorException { final int[] sum = {0}; String regex = "[0-9, /,]+"; @@ -33,10 +33,9 @@ public int add(String numbersStr) throws StringCalculatorException { sum[0] = sum[0] + Integer.parseInt(currentItem); } }); - return sum[0]; // Return the sum of the items - } else { - return sum[0]; // Return 0 for null or empty string } + + return sum[0]; // Return the sum of the items } } From 20e05d04d91b83cdd3a6cbd6c1ac0aeabe5c9719 Mon Sep 17 00:00:00 2001 From: Kiree Date: Mon, 8 Oct 2018 10:04:55 +0300 Subject: [PATCH 4/5] [Refactoring] :white_check_mark: Refactored StringCalculator.java to reduce code smells - Parametrized the check for String null & empty checks. --- src/StringCalculator.java | 15 +++++++++++++-- src/StringCalculatorException.java | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/StringCalculator.java b/src/StringCalculator.java index 388e834..902ff89 100644 --- a/src/StringCalculator.java +++ b/src/StringCalculator.java @@ -17,7 +17,7 @@ int add(String numbersStr) throws StringCalculatorException { String regex = "[0-9, /,]+"; // Check that the string is not null or empty - if (numbersStr != null && !numbersStr.isEmpty()) { + if (isStringNotNullAndNotEmpty(numbersStr)) { // Replace whitespace with comma numbersStr = numbersStr.replaceAll("\\s", ","); @@ -33,9 +33,20 @@ int add(String numbersStr) throws StringCalculatorException { sum[0] = sum[0] + Integer.parseInt(currentItem); } }); - } return sum[0]; // Return the sum of the items } + + /** + * private boolean isStringNotNullAndNotEmpty + * Checks if the given String is null or empty. The null check is performed first to ensure no NPE is thrown. + * + * @param stringToBeChecked - The String that needs to be checked + * @return true/false depending on if the String was null/empty or not + */ + private boolean isStringNotNullAndNotEmpty(String stringToBeChecked) { + return (stringToBeChecked != null && !stringToBeChecked.isEmpty()); + } + } diff --git a/src/StringCalculatorException.java b/src/StringCalculatorException.java index da71147..cf231ec 100644 --- a/src/StringCalculatorException.java +++ b/src/StringCalculatorException.java @@ -1,4 +1,4 @@ -public class StringCalculatorException extends Exception { +class StringCalculatorException extends Exception { } From 7ea604ef20cc09d322af604d6a0e5f00d4e9c85c Mon Sep 17 00:00:00 2001 From: Kiree Date: Mon, 8 Oct 2018 12:17:13 +0300 Subject: [PATCH 5/5] [Refactoring] :white_check_mark: Refactored StringCalculator.java to reduce code smells - Replaced a parameter with a method. --- src/StringCalculator.java | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/StringCalculator.java b/src/StringCalculator.java index 902ff89..ab48ed2 100644 --- a/src/StringCalculator.java +++ b/src/StringCalculator.java @@ -14,20 +14,12 @@ class StringCalculator { int add(String numbersStr) throws StringCalculatorException { final int[] sum = {0}; - String regex = "[0-9, /,]+"; // Check that the string is not null or empty if (isStringNotNullAndNotEmpty(numbersStr)) { + String preparedStr = prepareStringForCalculation(numbersStr); // Prepare the string for calculation - // Replace whitespace with comma - numbersStr = numbersStr.replaceAll("\\s", ","); - - // Abort execution if string contains characters other than numbers [0-9] or comma [/,]. - if (!numbersStr.matches(regex)) { - throw new StringCalculatorException(); - } - - List numbersList = Arrays.asList(numbersStr.split(",")); // Assign the expected numbers to an array + List numbersList = Arrays.asList(preparedStr.split(",")); // Assign the expected numbers to an array numbersList.forEach((currentItem) -> { if(!currentItem.isEmpty()) { sum[0] = sum[0] + Integer.parseInt(currentItem); @@ -49,4 +41,26 @@ private boolean isStringNotNullAndNotEmpty(String stringToBeChecked) { return (stringToBeChecked != null && !stringToBeChecked.isEmpty()); } + /** + * private String prepareStringForCalculation + * Prepares the user input for calculation. + * + * @param originalStr - The original String that needs to be prepared + * @return preparedStr - The prepared String + * @throws StringCalculatorException - Throw if the regex doesn't match + */ + private String prepareStringForCalculation(String originalStr) throws StringCalculatorException{ + String regex = "[0-9, /,]+"; //The regex that the check will be performed against + + // Replace whitespace with comma + String preparedStr = originalStr.replaceAll("\\s", ","); + + // Abort execution if string contains characters other than numbers [0-9] or comma [/,]. + if (!preparedStr.matches(regex)) { + throw new StringCalculatorException(); + } + + return preparedStr; + } + }