Permalink
Browse files

Kata enero: StringCalculator (Java)

  • Loading branch information...
Sergio authored and 12meses12katas committed May 22, 2011
1 parent e7523c5 commit ad58c6da72a955585721599020a100b543d0def2
View
@@ -0,0 +1,12 @@
+#java specific
+*.class
+
+#eclipse
+.metadata/
+
+## generic files to ignore
+*~
+*.lock
+*.DS_Store
+*.swp
+*.out
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="test"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>StringCalculator</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
@@ -0,0 +1,12 @@
+#Sun May 22 20:00:59 CEST 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
@@ -0,0 +1,106 @@
+package com.stringcalculator.src;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class StringCalculator
+{
+ private static final int MAX_VALUE = 1000;
+ private static final String NEGATIVE_PREFIX = "-";
+ private static final String NEGATIVE_ERROR_MESSAGE = "negatives not allowed";
+ private static final String OR = "|";
+ private static final String NEW_LINE = "\\n";
+ private static final String ASSIGN_DELIMITER = "//";
+ private static final String DEFAULT_DELIMITER = ",".concat(OR + NEW_LINE).concat(OR + ASSIGN_DELIMITER).concat(OR + "\\[").concat(OR + "\\]");
+
+ public static int add(String input) throws Exception
+ {
+ int sum = 0;
+
+ if (inputHasOperands(input))
+ {
+ List<String> operands = getNonEmptyOperands(input.split(getDefaultDelimiter(input)));
+
+ throwExceptionIfExistNegativeOperands(operands);
+ operands = getOperandsLessThanThousand(operands);
+ for (String operand : operands)
+ sum += Integer.parseInt(operand);
+ }
+
+ return sum;
+ }
+
+ private static List<String> getOperandsLessThanThousand(List<String> operands)
+ {
+ List<String> operandsLessThanThousand = new ArrayList<String>();
+
+ for (String operand:operands)
+ if (Integer.parseInt(operand) <= MAX_VALUE)
+ operandsLessThanThousand.add(operand);
+
+ return operandsLessThanThousand;
+ }
+
+ private static void throwExceptionIfExistNegativeOperands(List<String> operands) throws Exception
+ {
+ List<String> negativeOperands = getNegativeOperands(operands);
+
+ if (negativeOperands.size() > 0)
+ {
+ String errorMessage = NEGATIVE_ERROR_MESSAGE;
+
+ for (String negativeOperand : negativeOperands)
+ errorMessage = errorMessage.concat(" " + negativeOperand);
+
+ throw new Exception(errorMessage);
+ }
+ }
+
+ private static List<String> getNegativeOperands(List<String> operands)
+ {
+ List<String> negativeOperands = new ArrayList<String>();
+
+ for (String operand : operands)
+ if (operand.startsWith(NEGATIVE_PREFIX))
+ negativeOperands.add(operand);
+
+ return negativeOperands;
+ }
+
+ private static List<String> getNonEmptyOperands(String[] operands)
+ {
+ List<String> nonEmptyOperands = new ArrayList<String>();
+
+ for (String input : operands)
+ if (inputHasOperands(input))
+ nonEmptyOperands.add(input);
+
+ return nonEmptyOperands;
+ }
+
+ private static String getDefaultDelimiter(String input)
+ {
+ String defaultDelimiter = DEFAULT_DELIMITER;
+
+ if (input.startsWith(ASSIGN_DELIMITER))
+ {
+ String[] delimiters = input.split(NEW_LINE)[0].substring(ASSIGN_DELIMITER.length()).split("\\[|\\]");
+ for (String delimiter : delimiters)
+ if (delimiter.length() > 0)
+ defaultDelimiter = defaultDelimiter.concat(OR + delimiter);
+ }
+
+ return escapeMetaRegex(defaultDelimiter);
+ }
+
+ private static String escapeMetaRegex(String regex)
+ {
+ return regex.replace("*", "\\*").replace("+", "\\+").replace("(", "\\(").replace(")", "\\)");
+ }
+
+ private static boolean inputHasOperands(String input)
+ {
+ return input.length() != 0;
+ }
+
+}
@@ -0,0 +1,79 @@
+package com.stringcalculator.test;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import com.stringcalculator.src.StringCalculator;
+
+public class StringCalculatorTest
+{
+ @Rule
+ public ExpectedException exception = ExpectedException.none();
+
+ @Test
+ public void addMaxTwoOperandsTest() throws Exception
+ {
+ assertEquals(0, StringCalculator.add(""));
+ assertEquals(1, StringCalculator.add("1"));
+ assertEquals(3, StringCalculator.add("1,2"));
+ }
+
+ @Test
+ public void addUnknownOperandsTest() throws Exception
+ {
+ assertEquals(7, StringCalculator.add("1,5,1"));
+ assertEquals(14, StringCalculator.add("1,5,1,3,4"));
+ }
+
+ @Test
+ public void returnsAndCommansOperatorsTest() throws Exception
+ {
+ assertEquals(6, StringCalculator.add("1\n2,3"));
+ assertEquals(9, StringCalculator.add("1,5\n1,2"));
+ }
+
+ @Test
+ public void changeDelimiterTest() throws Exception
+ {
+ assertEquals(3, StringCalculator.add("//;\n1;2"));
+ assertEquals(10, StringCalculator.add("//:\n1:2,3\n2:2"));
+ }
+
+ @Test
+ public void negativeNumbersExceptionTest() throws Exception
+ {
+ exception.expectMessage("negatives not allowed -2");
+ StringCalculator.add("//;\n1;-2");
+ exception.expectMessage("negatives not allowed -2 -4 -1");
+ StringCalculator.add("//;\n1;-2;-4;-1");
+ }
+
+ @Test
+ public void operandsLessThanThousandTest() throws Exception
+ {
+ assertEquals(2, StringCalculator.add("2,1001"));
+ assertEquals(0, StringCalculator.add("1540,1425"));
+ assertEquals(0, StringCalculator.add("1540"));
+ }
+
+ @Test
+ public void anyLengthDelimiterTest() throws Exception
+ {
+ assertEquals(6, StringCalculator.add("//[***]\n1***2***3"));
+ }
+
+ @Test
+ public void multipleDelimitersTest() throws Exception
+ {
+ assertEquals(6, StringCalculator.add("//[*][%]\n1*2%3"));
+ }
+
+ @Test
+ public void anyLengthMultipleDelimitersTest() throws Exception
+ {
+ assertEquals(6, StringCalculator.add("//[***][%]\n1***2%3"));
+ }
+}

0 comments on commit ad58c6d

Please sign in to comment.