diff --git a/src/main/java/StringManipulation.java b/src/main/java/StringManipulation.java index 4deb6f1..315aae2 100644 --- a/src/main/java/StringManipulation.java +++ b/src/main/java/StringManipulation.java @@ -1,33 +1,134 @@ public class StringManipulation implements StringManipulationInterface { + private String string; + @Override public String getString() { - return null; + return string; } @Override public void setString(String string) { + this.string = string; } @Override public int count() { - return 0; + if (string == null) + return 0; + if (string.length() == 0) + return 0; + + int count = 0; + for (int i = 0; i < string.length() - 2; i++) { + if (i == 0 && !isSpaceChar(string.charAt(i))) + count++; + else if (isSpaceChar(string.charAt(i)) && !isSpaceChar(string.charAt(i + 1))) + count++; + } + + return count; } @Override public String removeNthCharacter(int n, boolean maintainSpacing) { - return null; + if (n <= 0) + throw new IllegalArgumentException(); + if (n > string.length()) + throw new IndexOutOfBoundsException(); + + StringBuilder newStr = new StringBuilder(); + for (int i = 1; i < string.length() + 1; i++) { + if (i % n == 0) { + if (maintainSpacing) + newStr.append(' '); + } else + newStr.append(string.charAt(i - 1)); + } + + return newStr.toString(); } @Override public String[] getSubStrings(int startWord, int endWord) { - return null; + if (count() < endWord) + throw new IndexOutOfBoundsException(); + if (startWord <= 0 || endWord <= 0 || startWord > endWord) + throw new IllegalArgumentException(); + + String[] words = new String[(endWord - startWord) + 1]; + int wordIndex = 0; + + StringBuilder sb = new StringBuilder(); + int wordCount = 0; + for (int i = 0; i < string.length() - 1; i++) { + // Case where first character is a word + if (i == 0 && !isSpaceChar(string.charAt(i))) { + wordCount++; + if (wordCount == startWord) + sb.append(string.charAt(i)); + + // Case where beginning of new word is found + } else if (isSpaceChar(string.charAt(i)) && !isSpaceChar(string.charAt(i + 1))) { + wordCount++; + i++; + if (wordCount >= startWord && wordCount <= endWord) + sb.append(string.charAt(i)); + + // Case where end of word is found + } else if (!isSpaceChar(string.charAt(i)) && isSpaceChar(string.charAt(i + 1))) { + if (wordCount >= startWord && wordCount <= endWord) { + sb.append(string.charAt(i)); + words[wordIndex++] = sb.toString(); + sb = new StringBuilder(); + } + + } else if (!isSpaceChar(string.charAt(i)) && wordCount >= startWord && wordCount <= endWord) { + sb.append(string.charAt(i)); + } + } + if (endWord == count()) { + sb.append(string.charAt(string.length() - 1)); + words[wordIndex] = sb.toString(); + } + + return words; } @Override - public String restoreString(int[] indices) { - return null; + public String restoreString(int[] indices){ + if (indices.length != string.length()) + throw new IllegalArgumentException(); + + boolean[] indexUsed = new boolean[indices.length]; + char[] chars = new char[indices.length]; + for (int i = 0; i < indices.length; i++) { + if (indices[i] < 0 || indices[i] > string.length()) + throw new IndexOutOfBoundsException(); + if (indexUsed[indices[i]]) + throw new IllegalArgumentException("Indices must be unique"); + + chars[indices[i]] = string.charAt(i); + indexUsed[indices[i]] = true; + } + + StringBuilder sb = new StringBuilder(); + for (char c : chars) + sb.append(c); + + return sb.toString(); } + private boolean isSpaceChar(char ch) { + // Add any characters considered as a word delimiter + char[] spaceChars = {' ', '_', '-', '\t', '\n'}; + + for (char c : spaceChars) { + if (c == ch) + return true; + } + + return false; + } } diff --git a/src/test/java/StringManipulationTest.java b/src/test/java/StringManipulationTest.java index 6692c2c..8a52d02 100644 --- a/src/test/java/StringManipulationTest.java +++ b/src/test/java/StringManipulationTest.java @@ -1,149 +1,370 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import java.util.Arrays; import static org.junit.jupiter.api.Assertions.*; public class StringManipulationTest { - private StringManipulationInterface manipulatedstring; + private StringManipulationInterface manipulatedString; + @BeforeEach public void setUp() { - manipulatedstring = new StringManipulation(); + manipulatedString = new StringManipulation(); } @AfterEach public void tearDown() { - manipulatedstring = null; + manipulatedString = null; + } + + + @Test + @DisplayName("Test GetString with a new object") + public void testGetString1() { + // arrange + manipulatedString = new StringManipulation(); + + // act + String result = manipulatedString.getString(); + + // assert + assertNull(result); + } + + @Test + @DisplayName("Test GetString with a basic string") + public void testGetString2() { + // arrange + String expected = "string"; + manipulatedString.setString(expected); + + // act + String actual = manipulatedString.getString(); + + // assert + assertEquals(expected, actual); } + @Test + @DisplayName("Test Count with a new object") public void testCount1() { - manipulatedstring.setString("This is my string"); - int length = manipulatedstring.count(); - assertEquals(4, length); + // arrange + manipulatedString = new StringManipulation(); + + // act + int actual = manipulatedString.count(); + + // assert + assertEquals(0, actual); } @Test + @DisplayName("Test Count with an empty string") public void testCount2() { - fail("Not yet implemented"); + // arrange + manipulatedString.setString(""); + + // act + int actual = manipulatedString.count(); + + // assert + assertEquals(0, actual); } @Test + @DisplayName("Test Count with a multi-word string") public void testCount3() { - fail("Not yet implemented"); + // arrange + manipulatedString.setString("This is my string"); + int expected = 4; + + // act + int actual = manipulatedString.count(); + + // assert + assertEquals(expected, actual); } @Test + @DisplayName("Test Count with trailing spaces on the string") public void testCount4() { - fail("Not yet implemented"); + // arrange + manipulatedString.setString("Here are spaces "); + int expected = 3; + + // act + int actual = manipulatedString.count(); + + // assert + assertEquals(expected, actual); + } + + @Test + @DisplayName("Test Count with alternate spacing characters") + public void testCount5() { + // arrange + manipulatedString.setString("I_am_spaced_with_underscores"); + int expected = 5; + + // act + int actual = manipulatedString.count(); + + // assert + assertEquals(expected, actual); } + @Test + @DisplayName("Test RemoveNthCharacter with a random string with no replacement") public void testRemoveNthCharacter1() { - manipulatedstring.setString("I'd b3tt3r put s0me d161ts in this 5tr1n6, right?"); - assertEquals("I' bttr uts0e 16tsinths trn6 rgh?", manipulatedstring.removeNthCharacter(3, false)); + // arrange + manipulatedString.setString("I'd b3tt3r put s0me d161ts in this 5tr1n6, right?"); + String expected = "I' bttr uts0e 16tsinths trn6 rgh?"; + + // act + String actual = manipulatedString.removeNthCharacter(3, false); + + // assert + assertEquals(expected, actual); } @Test + @DisplayName("Test RemoveNthCharacter with a random string with replacement") public void testRemoveNthCharacter2() { - manipulatedstring.setString("I'd b3tt3r put s0me d161ts in this 5tr1n6, right?"); - assertEquals("I' b tt r ut s0 e 16 ts in th s tr n6 r gh ?", manipulatedstring.removeNthCharacter(3, true)); + // arrange + manipulatedString.setString("I'd b3tt3r put s0me d161ts in this 5tr1n6, right?"); + String expected = "I' b tt r ut s0 e 16 ts in th s tr n6 r gh ?"; + + // act + String actual = manipulatedString.removeNthCharacter(3, true); + + // assert + assertEquals(expected, actual); } @Test + @DisplayName("Test RemoveNthCharacter with an index less than one") public void testRemoveNthCharacter3() { - fail("Not yet implemented"); + // arrange + manipulatedString.setString("A string"); + + // act/assert + assertThrows(IllegalArgumentException.class, () -> manipulatedString.removeNthCharacter(0, true)); } @Test + @DisplayName("Test RemoveNthCharacter with an index greater than string length") public void testRemoveNthCharacter4() { - fail("Not yet implemented"); + // arrange + manipulatedString.setString("A string"); + + // act/assert + assertThrows(IndexOutOfBoundsException.class, () -> manipulatedString.removeNthCharacter(50, true)); } @Test + @DisplayName("Test RemoveNthCharacter with an empty string with no replacement") public void testRemoveNthCharacter5() { - fail("Not yet implemented"); + // arrange + manipulatedString.setString("A"); + String expected = ""; + + // act + String actual = manipulatedString.removeNthCharacter(1, false); + + // assert + assertEquals(expected, actual); } @Test + @DisplayName("Test RemoveNthCharacter with an empty string with replacement") public void testRemoveNthCharacter6() { - fail("Not yet implemented"); + // arrange + manipulatedString.setString("A"); + String expected = " "; + + // act + String actual = manipulatedString.removeNthCharacter(1, true); + + // assert + assertEquals(expected, actual); } @Test + @DisplayName("Test RemoveNthCharacter with removing all characters") public void testRemoveNthCharacter7() { - fail("Not yet implemented"); + // arrange + manipulatedString.setString("This is a string"); + String expected = ""; + + // act + String actual = manipulatedString.removeNthCharacter(1, false); + + // assert + assertEquals(expected, actual); + } + + @Test + @DisplayName("Test RemoveNthCharacter with replacing all characters") + public void testRemoveNthCharacter8() { + // arrange + manipulatedString.setString("This is a string"); + String expected = " "; + + // act + String actual = manipulatedString.removeNthCharacter(1, true); + + // assert + assertEquals(expected, actual); + } + + + @Test + @DisplayName("Test getSubStrings with a multi-word string") + public void testGetSubStrings1() { + // arrange + manipulatedString.setString("This is my string"); + + // act + String [] sStings = manipulatedString.getSubStrings(3, 4); + + // assert + assertEquals("my", sStings[0]); + assertEquals("string", sStings[1]); } @Test - public void testGeSubStrings1() { - manipulatedstring.setString("This is my string"); - String [] sStings = manipulatedstring.getSubStrings(3, 4); + @DisplayName("Test getSubStrings for exception throw where string has no words") + public void testGetSubStrings2() { + // arrange + manipulatedString.setString(""); - assertEquals(sStings[0], "my"); - assertEquals(sStings[1], "string"); + // act/assert + assertThrows(IndexOutOfBoundsException.class, () -> manipulatedString.getSubStrings(0, 1)); } @Test - public void testGeSubStrings2() { - fail("Not yet implemented"); + @DisplayName("Test getSubStrings for exception throw when there are less words than endWord param") + public void testGetSubStrings3() { + // arrange + manipulatedString.setString("This is four words"); + + // act/assert + assertThrows(IndexOutOfBoundsException.class, () -> manipulatedString.getSubStrings(1, 5)); } + @Test - public void testGeSubStrings3() { - fail("Not yet implemented"); + @DisplayName("Test getSubStrings for exception thrown when startWord is invalid") + public void testGetSubStrings4() { + // arrange + manipulatedString.setString("I am a string"); + + // act/assert + assertThrows(IllegalArgumentException.class, () -> manipulatedString.getSubStrings(0, 2)); } + @Test - public void testGeSubStrings4() { - fail("Not yet implemented"); + @DisplayName("Test getSubStrings for exception thrown when endWord is invalid") + public void testGetSubStrings5() { + // arrange + manipulatedString.setString("I am a string"); + + // act/assert + assertThrows(IllegalArgumentException.class, () -> manipulatedString.getSubStrings(1, 0)); } + @Test - public void testGeSubStrings5() { - fail("Not yet implemented"); + @DisplayName("Test getSubStrings getting from a single word string") + public void testGetSubStrings6() { + // arrange + manipulatedString.setString("String"); + String[] expected = {"String"}; + + // act + String[] result = manipulatedString.getSubStrings(1, 1); + + // assert + assertIterableEquals(Arrays.asList(expected), Arrays.asList(result)); } + @Test - public void testGeSubStrings6() { - fail("Not yet implemented"); + @DisplayName("Test getSubStrings getting from a string with extra spaces") + public void testGetSubStrings7() { + // arrange + manipulatedString.setString(" So many spaces "); + String[] expected = {"So", "many"}; + + // act + String[] result = manipulatedString.getSubStrings(1, 2); + + // assert + assertIterableEquals(Arrays.asList(expected), Arrays.asList(result)); } + @Test - public void testRestoreString1() - { - manipulatedstring.setString("art"); + @DisplayName("Test restoreString with small sample string") + public void testRestoreString1() { + // arrange + manipulatedString.setString("art"); int [] array; array=new int[]{1,0,2}; - String restoreString = manipulatedstring.restoreString(array); + + // act + String restoreString = manipulatedString.restoreString(array); + + // assert assertEquals(restoreString, "rat"); } @Test - public void testRestoreString2() - { - fail("Not yet implemented"); + @DisplayName("Test restoreString for thrown exception when indices index of incorrect length given as param") + public void testRestoreString2() { + // arrange + manipulatedString.setString("text"); + int[] array = new int[] {0, 1}; + // act/assert + assertThrows(IllegalArgumentException.class, () -> manipulatedString.restoreString(array)); } @Test - public void testRestoreString3() - { - fail("Not yet implemented"); + @DisplayName("Test restoreString for thrown exception when there is a index less than 0 in indices param") + public void testRestoreString3() { + // arrange + manipulatedString.setString("text"); + int[] array = new int[] {-1, 1, 3, 2}; + // act/assert + assertThrows(IndexOutOfBoundsException.class, () -> manipulatedString.restoreString(array)); } @Test - public void testRestoreString4() - { - fail("Not yet implemented"); + @DisplayName("Test restoreString for thrown exception when there is a index greater than string length in indices param") + public void testRestoreString4() { + // arrange + manipulatedString.setString("text"); + int[] array = new int[] {4, 3, 2, 6}; + // act/assert + assertThrows(IndexOutOfBoundsException.class, () -> manipulatedString.restoreString(array)); } @Test - public void testRestoreString5() - { - fail("Not yet implemented"); + @DisplayName("Test restoreString for thrown exception when there is are duplicates in indices param") + public void testRestoreString5() { + // arrange + manipulatedString.setString("text"); + int[] array = new int[] {1, 2, 1, 3}; + // act/assert + assertThrows(IllegalArgumentException.class, () -> manipulatedString.restoreString(array)); } }