Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.company;
- import org.junit.Before;
- import org.junit.Rule;
- import org.junit.Test;
- import org.junit.rules.ExpectedException;
- import static org.hamcrest.MatcherAssert.assertThat;
- import static org.hamcrest.core.IsEqual.equalTo;
- /**
- */
- public class StringCalculatorTest {
- @Rule
- public ExpectedException exceptionCatcher = ExpectedException.none();
- private StringCalculator stringCalculator;
- @Before
- public void setUp() throws Exception {
- stringCalculator = new StringCalculator();
- }
- @Test
- public void whenEmptyString_thenZero() {
- assertThat(stringCalculator.add(""), equalTo(0));
- }
- @Test
- public void whenOneNumber_thenReturnThatNumber() {
- assertThat(stringCalculator.add(" 1 "), equalTo(1));
- }
- @Test
- public void whenTwoNumbers_thenReturnSum() {
- assertThat(stringCalculator.add("1,\t2"), equalTo(3));
- }
- @Test
- public void whenInvalidDelimiter_thenException() {
- exceptionCatcher.expect(StringCalculator.InvalidInput.class);
- stringCalculator.add("1 1");
- }
- @Test
- public void whenNoNumbers_thenException() {
- exceptionCatcher.expect(StringCalculator.InvalidInput.class);
- stringCalculator.add("foo bar");
- }
- @Test
- public void whenThreeNumber_thenSum() {
- assertThat(stringCalculator.add("1,2,3"), equalTo(6));
- }
- @Test
- public void whenNewLine_thenParsedCorrectly() {
- assertThat(stringCalculator.add("1\n1,2"), equalTo(4));
- }
- @Test
- public void whenNewLineWithComma_thenException() {
- exceptionCatcher.expect(StringCalculator.InvalidInput.class);
- stringCalculator.add("1,\n");
- }
- @Test
- public void whenTwoNumbersWithNewLineWithComma_thenException() {
- exceptionCatcher.expect(StringCalculator.InvalidInput.class);
- stringCalculator.add("1,\n2");
- }
- @Test
- public void whenOtherDelimiter_thenSuportIt() {
- assertThat(stringCalculator.add("//[;]\n2;3"), equalTo(5));
- }
- @Test
- public void whenDelimitersDontMatch_thenException() {
- exceptionCatcher.expect(StringCalculator.InvalidInput.class);
- stringCalculator.add("//[!]\n1,2");
- }
- @Test
- public void whenOtherDelimitedWithNewLine_thenSum() {
- assertThat(stringCalculator.add("//[!]\n100!500"), equalTo(600));
- }
- @Test
- public void whenNegativeNumbers_thenShowThemInException() {
- exceptionCatcher.expect(StringCalculator.InvalidInput.class);
- exceptionCatcher.expectMessage("-1,-5");
- stringCalculator.add("//[qw]\n1qw2qw-1qw100qw-5");
- }
- @Test
- public void whenTwoNumbersGreaterThan1000_thenZero() {
- assertThat(stringCalculator.add("//[-]\n1001-1002"), equalTo(0));
- }
- @Test
- public void whenTenAndThousandOne_thenTen() {
- assertThat(stringCalculator.add("10,1001"), equalTo(10));
- }
- @Test
- public void whenThousandAndThousand_thenTwoThousand() {
- assertThat(stringCalculator.add("1000\n1000"), equalTo(2000));
- }
- @Test
- public void whenTwoDelimiters_thenCorrectSum() {
- assertThat(stringCalculator.add("//[*][%]\n1*2%3"), equalTo(6));
- }
- @Test
- public void whenTwoLongDelimiters_thenCorrectSum() {
- assertThat(stringCalculator.add("//[*~][%-]\n1*~2%-3"), equalTo(6));
- }
- }
- package com.company;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.List;
- import java.util.regex.Pattern;
- import static java.lang.Integer.parseInt;
- /**
- */
- public class StringCalculator {
- private List<String> delimiters;
- private String strNumbers;
- private Pattern delimitersPattern;
- private List<Integer> numbers;
- public StringCalculator() {
- delimiters = Collections.singletonList(",");
- delimitersPattern = Pattern.compile("//(\\[\\S+\\])+\\n.*");
- }
- public int add(String numbers) {
- this.strNumbers = numbers;
- if (numbers.isEmpty())
- return 0;
- checkPreconditions();
- if (hasDelimiter())
- extractDelimiter();
- parse();
- return sum();
- }
- private void checkPreconditions() {
- String[] invalidDelimiters = new String[]{"\n,", ",\n"};
- for (String d : invalidDelimiters)
- if (strNumbers.contains(d))
- throw new InvalidInput();
- }
- private boolean hasDelimiter() {
- return delimitersPattern.matcher(strNumbers).matches();
- }
- private void extractDelimiter() {
- int endIndex = strNumbers.indexOf("\n");
- delimiters = new ArrayList<>();
- int openBraceIdx = 2;
- while (openBraceIdx < endIndex - 1) {
- int closeBraceIdx = strNumbers.indexOf(']', openBraceIdx);
- delimiters.add(strNumbers.substring(openBraceIdx + 1, closeBraceIdx));
- openBraceIdx = closeBraceIdx + 1;
- }
- strNumbers = strNumbers.substring(endIndex + 1);
- }
- private void parse() {
- List<String> splittedNums = new ArrayList<>();
- for (String num : strNumbers.split(makeSplitString()))
- splittedNums.add(num);
- tryParseIntoNumbers(splittedNums);
- }
- private String makeSplitString() {
- String splitString = "(";
- for (String d : delimiters)
- splitString += Pattern.quote(d) + "|";
- splitString += "\\n)";
- return splitString;
- }
- private void tryParseIntoNumbers(List<String> splittedNums) {
- numbers = new ArrayList<>();
- List<Integer> negativeNumbers = new ArrayList<>();
- for (String n : splittedNums) {
- int i = tryParse(n);
- numbers.add(i);
- if (i < 0)
- negativeNumbers.add(i);
- }
- if (!negativeNumbers.isEmpty())
- throwExceptionForNegativeNumbers(negativeNumbers);
- }
- private void throwExceptionForNegativeNumbers(List<Integer> negativeNumbers) {
- String message = "";
- for (Integer n : negativeNumbers)
- message += message.isEmpty() ? n : "," + n;
- throw new InvalidInput(message);
- }
- private Integer tryParse(String number) {
- try {
- return parseInt(number.trim());
- } catch (NumberFormatException e) {
- throw new InvalidInput(e);
- }
- }
- private int sum() {
- int result = 0;
- for (Integer n : numbers) {
- if (n <= 1000)
- result += n;
- }
- return result;
- }
- public static class InvalidInput extends RuntimeException {
- public InvalidInput() {
- }
- public InvalidInput(String message) {
- super(message);
- }
- public InvalidInput(Throwable cause) {
- super(cause);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement