diff --git a/a2/src/edu/wmich/cs3310/a2/ComputeTime.java b/a2/src/edu/wmich/cs3310/a2/ComputeTime.java new file mode 100644 index 0000000000000000000000000000000000000000..f93b341c31ad5e84b9b983c2077a7b90aa50cd63 --- /dev/null +++ b/a2/src/edu/wmich/cs3310/a2/ComputeTime.java @@ -0,0 +1,119 @@ +package edu.wmich.cs3310.a2; + + +import java.util.Date; + + +/** + * Calculates differences between two times. + */ +public class ComputeTime { + + //region Variables + + private long startMilliseconds; + private long endMilliseconds; + private long differenceMilliseconds; + + //endregion Variables + + + + //region Constructor + + /** + * Base constructor. + */ + public ComputeTime() { + + } + + //endregion Constructor + + + + //region Methods + + //region Private Methods + + /** + * Determines the difference in milliseconds between two times. + * @param time1 Start time. + * @param time2 End time. + * @return Long of Milisecond difference. + * Positive means time1 is earlier than time2. + * Zero means they're equal. + * Negative means time2 is earlier than time1. + */ + public long ComputeDateDifference(Date time1, Date time2) { + startMilliseconds = time1.getTime(); + endMilliseconds = time2.getTime(); + differenceMilliseconds = endMilliseconds - startMilliseconds; + return differenceMilliseconds; + } + + //endregion Private Methods + + + + //region Public Methods + + /** + * Calculates the difference between provided start time and current time. + * @param startDate Start time. + * @return Long of elapsed time. + */ + public long GetTimeLapse(Date startDate) { + long timeResult; + + // Get time lapse of process. + timeResult = ComputeDateDifference(startDate, (new Date())); + return timeResult; + } + + + /** + * Calculates the difference between provided start time and current time. + * Also outputs time and additional information to user. + * @param startDate Start time. + * @param userDisplayString Additional info to show user. + * @return Long of elapsed time. + */ + public long GetTimeLapse(Date startDate, String userDisplayString) { + long timeResult; + System.out.print(userDisplayString); + + // Get time lapse of process. + timeResult = ComputeDateDifference(startDate, (new Date())); + PrintTime(timeResult); + return timeResult; + } + + + /** + * Calculates hours, minutes, seconds, and milliseconds based upon total milliseconds. + * Prints to stdout. + * @param timeInMilliseconds Long that represents milliseconds passed. + */ + public void PrintTime(long timeInMilliseconds) { + long miliseconds; + long seconds; + long minutes; + long hours; + + miliseconds = timeInMilliseconds % 1000; + seconds = timeInMilliseconds / 1000; + minutes = seconds / 60; + seconds = seconds % 60; + hours = minutes / 60; + minutes = minutes % 60; + + // Prints in H:M:S:m format. + System.out.println( + hours + ":" + minutes + ":" + seconds + ":" + miliseconds); + } + + //endregion Public Methods + + //endregion Methods +} diff --git a/a2/src/edu/wmich/cs3310/a2/Controller.java b/a2/src/edu/wmich/cs3310/a2/Controller.java new file mode 100644 index 0000000000000000000000000000000000000000..db06e5d846724548a70f2056a2e48bf0f01a5f7b --- /dev/null +++ b/a2/src/edu/wmich/cs3310/a2/Controller.java @@ -0,0 +1,4 @@ +package edu.wmich.cs3310.a2; + +public class Controller { +} diff --git a/a2/src/edu/wmich/cs3310/a2/DataStructures/CharList.java b/a2/src/edu/wmich/cs3310/a2/DataStructures/CharList.java new file mode 100644 index 0000000000000000000000000000000000000000..31c0c8fa637800125ba9a5b7453c99d693e37bb4 --- /dev/null +++ b/a2/src/edu/wmich/cs3310/a2/DataStructures/CharList.java @@ -0,0 +1,224 @@ +package edu.wmich.cs3310.a2.DataStructures; + + +/** + * Doubly linked list using CharNode for nodes. + */ +public class CharList { + + //region Variables + + protected CharNode firstNode; + protected CharNode lastNode; + + //endregion Variables + + + + //region Controllers + + /** + * Base constructor. + */ + public CharList() { + + } + + //endregion Controllers + + + + //region Properties + + /** + * Getter for first node in list. + * @return First node of list. + */ + public CharNode firstNode() { + return firstNode; + } + + + /** + * Getter for last node in list. + * @return Last node of list. + */ + public CharNode lastNode() { + return lastNode; + } + + + //endregion Properties + + + + //region Methods + + /** + * Retrieves node from indicated index. + * @param index Index of node to retrieve. + * @return Retrieved node or null if failure. + */ + public CharNode Retrieve(int index) { + CharNode tempNode; + int tempIndex = 0; + + // Check that index is valid. + if (index < 0) { + return null; + } else { + tempNode = firstNode; + } + + // Loop until index is found or all nodes are searched. + while (tempIndex < index && tempNode != null) { + tempNode = tempNode.nextNode(); + tempIndex++; + } + + return tempNode; + } + + + /** + * Inserts new new node at given index in linked list. + * @param character Character for node to hold. + * @param index Index of new node. + * @return True on success or false on failure. + */ + public Boolean Insert(char character, int index) { + CharNode newNode = new CharNode(); + CharNode tempNode; + CharNode nextPlaceholder; + CharNode prevPlaceholder; + + // Get node directly before desired index. + tempNode = Retrieve((index - 1)); + + // Check that returned node is valid. + if (tempNode == null && index != 0) { + return false; + } + + newNode.myData(character); + + // Check if list is empty. + if (firstNode == null) { + firstNode = newNode; + lastNode = newNode; + } else { + nextPlaceholder = Retrieve(index); + prevPlaceholder = tempNode; + + // Set nextNode properties. + newNode.nextNode(nextPlaceholder); + if (nextPlaceholder != null) { + nextPlaceholder.prevNode(newNode); + } else { + lastNode = newNode; + } + + // Set prevNode properties. + newNode.prevNode(prevPlaceholder); + if (prevPlaceholder != null) { + prevPlaceholder.nextNode(newNode); + } else { + firstNode = newNode; + } + } + return true; + } + + + /** + * Deletes node with given index. + * @param index Index of node to delete. + * @return Deleted node or null on failure. + */ + public CharNode Delete(int index) { + CharNode foundNode; + CharNode nextPlaceholder; + CharNode prevPlaceholder; + + foundNode = Retrieve(index); + + // Check that returned node is valid. + if (foundNode == null) { + return null; + } + + nextPlaceholder = foundNode.nextNode(); + prevPlaceholder = foundNode.prevNode(); + + // Handling for next property. + if (prevPlaceholder != null) { + prevPlaceholder.nextNode(nextPlaceholder); + } else { + firstNode = nextPlaceholder; + } + + // Handling for prev property. + if (nextPlaceholder != null) { + nextPlaceholder.prevNode(prevPlaceholder); + } else { + lastNode = prevPlaceholder; + } + + foundNode.nextNode(null); + foundNode.prevNode(null); + return foundNode; + } + + + /** + * Deletes node with given character. + * @param character Character to delete. + * @return Deleted node or null on failure. + */ + public CharNode Delete(char character) { + CharNode tempNode = firstNode; + CharNode foundNode = null; + CharNode nextPlaceholder; + CharNode prevPlaceholder; + + // Continue until character is found or all nodes are searched. + while (tempNode != null) { + + if (tempNode.myData() == character) { + foundNode = tempNode; + tempNode = null; + } else { + tempNode = tempNode.nextNode(); + } + } + + // Check for match. + if (foundNode == null) { + return null; + } else { + nextPlaceholder = foundNode.nextNode(); + prevPlaceholder = foundNode.prevNode(); + + // Handling for next property. + if (prevPlaceholder != null) { + prevPlaceholder.nextNode(nextPlaceholder); + } else { + firstNode = nextPlaceholder; + } + + // Handling for prev property. + if (nextPlaceholder != null) { + nextPlaceholder.prevNode(prevPlaceholder); + } else { + lastNode = prevPlaceholder; + } + + foundNode.nextNode(null); + foundNode.prevNode(null); + return foundNode; + } + } + + //endregion Methods + +} diff --git a/a2/src/edu/wmich/cs3310/a2/DataStructures/CharNode.java b/a2/src/edu/wmich/cs3310/a2/DataStructures/CharNode.java new file mode 100644 index 0000000000000000000000000000000000000000..7ef6193b651f0823d5146c161234463886134411 --- /dev/null +++ b/a2/src/edu/wmich/cs3310/a2/DataStructures/CharNode.java @@ -0,0 +1,77 @@ +package edu.wmich.cs3310.a2.DataStructures; + + +/** + * Node class for linked list. + */ +public class CharNode { + + //region Variables + + private char data; + private CharNode nextNode; + private CharNode prevNode; + + //endregion Variables + + + + //region Properties + + /** + * Getter for node char. + * @return The char that node holds. + */ + public char myData() { + return data; + } + + + + /** + * Setter for node char. + * @param data The char for node to hold. + */ + public void myData(char data) { + this.data = data; + } + + + /** + * Getter for next node. + * @return The next node. + */ + public CharNode nextNode() { + return nextNode; + } + + + /** + * Setter for next node. + * @param nextNode The next node to hold. + */ + public void nextNode(CharNode nextNode) { + this.nextNode = nextNode; + } + + + /** + * Getter for previous node. + * @return The previous node. + */ + public CharNode prevNode() { + return prevNode; + } + + + /** + * Setter for previous node. + * @param prevNode The previous node. + */ + public void prevNode(CharNode prevNode) { + this.prevNode = prevNode; + } + + //endregion Properties + +} diff --git a/a2/src/edu/wmich/cs3310/a2/DataStructures/CharQueue.java b/a2/src/edu/wmich/cs3310/a2/DataStructures/CharQueue.java new file mode 100644 index 0000000000000000000000000000000000000000..f04063038af08114afed97073d1c9c87da939f1b --- /dev/null +++ b/a2/src/edu/wmich/cs3310/a2/DataStructures/CharQueue.java @@ -0,0 +1,128 @@ +package edu.wmich.cs3310.a2.DataStructures; + + +/** + * Queue implementation of linked list. + */ +public class CharQueue extends CharList { + + //region Variables + + + + //endregion Variables + + + + //region Controllers + + public CharQueue() { + + } + + //endregion Controllers + + + + //region Properties + + /** + * Getter for queue head node. + * @return Node currently in head position. + */ + public CharNode headNode() { + return firstNode; + } + + + /** + * Getter for queue tail node. + * @return Node currently in tail position. + */ + public CharNode tailNode() { + return lastNode; + } + + //endregion Properties + + + + //region Methods + + /** + * Adds new node to tail of list. + * @param character Character for node to hold. + */ + public void Enqueue(char character) { + CharNode newNode = new CharNode(); + newNode.myData(character); + + // Check if list is empty. + if (firstNode == null) { + firstNode = newNode; + lastNode = newNode; + } else { + newNode.prevNode(lastNode); + lastNode.nextNode(newNode); + lastNode = newNode; + } + } + + + /** + * Adds new node to tail of list, by acting like list is + * only a singly-linked linked list. + * @param character Character for node to hold. + */ + public void Enqueue_Singly(char character) { + CharNode tempNode; + CharNode newNode = new CharNode(); + newNode.myData(character); + + // Check if list is empty. + if (firstNode == null) { + firstNode = newNode; + lastNode = newNode; + } else { + tempNode = firstNode; + + // Find last node in list. + while (tempNode.nextNode() != null) { + tempNode = tempNode.nextNode(); + } + + tempNode.nextNode(newNode); + newNode.prevNode(tempNode); + lastNode = newNode; + } + } + + + /** + * Removes node from list head. + * @return Removed node or null if list is empty. + */ + public CharNode Dequeue() { + CharNode tempNode = new CharNode(); + + // Check if list is empty. + if (firstNode == null) { + return null; + } else { + tempNode = firstNode; + firstNode = firstNode.nextNode(); + tempNode.nextNode(null); + + // Check if list was only one element. + if (firstNode == null) { + lastNode = null; + } else { + firstNode.prevNode(null); + } + } + return tempNode; + } + + //endregion Methods + +} diff --git a/a2/src/edu/wmich/cs3310/a2/DataStructures/CharStack.java b/a2/src/edu/wmich/cs3310/a2/DataStructures/CharStack.java new file mode 100644 index 0000000000000000000000000000000000000000..acbf05b09b2975c41ca373001444ead71351cf53 --- /dev/null +++ b/a2/src/edu/wmich/cs3310/a2/DataStructures/CharStack.java @@ -0,0 +1,91 @@ +package edu.wmich.cs3310.a2.DataStructures; + + +/** + * Stack implementation of linked list. + */ +public class CharStack extends CharList { + + //region Variables + + + + //endregion Variables + + + + //region Controllers + + public CharStack() { + + } + + //endregion Controllers + + + + //region Properties + + + /** + * Getter for stack head node. + * @return Node currently in head position. + */ + public CharNode headNode() { + return firstNode; + } + + //endregion Properties + + + + //region Methods + + /** + * Adds new node to list head. + * @param character Character for node to hold. + */ + public void Push(char character) { + CharNode newNode = new CharNode(); + newNode.myData(character); + + // Check if list is empty. + if (firstNode == null) { + firstNode = newNode; + lastNode = newNode; + } else { + newNode.nextNode(firstNode); + firstNode.prevNode(newNode); + firstNode = newNode; + } + } + + + /** + * Removes top node from list head. + * @return Removed node or null if list is empty. + */ + public CharNode Pop() { + CharNode tempNode; + + // Check if list is empty. + if (firstNode == null) { + return null; + } else { + tempNode = firstNode; + firstNode = firstNode.nextNode(); + tempNode.nextNode(null); + + // Check if list was only one element. + if (firstNode == null) { + lastNode = null; + } else { + firstNode.prevNode(null); + } + } + return tempNode; + } + + //endregion Methods + +} diff --git a/a2/src/edu/wmich/cs3310/a2/Main.java b/a2/src/edu/wmich/cs3310/a2/Main.java new file mode 100644 index 0000000000000000000000000000000000000000..eb9a7caba23b07de3cbafe63ae94c7b1bfe712eb --- /dev/null +++ b/a2/src/edu/wmich/cs3310/a2/Main.java @@ -0,0 +1,12 @@ +package edu.wmich.cs3310.a2; + + +/** + * Program main. + */ +public class Main { + public static void main(String[] args) { + // Create class to run program from non-static source. + Controller controller = new Controller(); + } +} diff --git a/a2/tests/ComputeTimeTests.java b/a2/tests/ComputeTimeTests.java new file mode 100644 index 0000000000000000000000000000000000000000..391a4f93691bb3c5923e0072cb8fd4b6214dfd6c --- /dev/null +++ b/a2/tests/ComputeTimeTests.java @@ -0,0 +1,136 @@ + +import java.util.Calendar; +import java.util.Date; +import org.junit.Before; +import org.junit.Assert; +import org.junit.Test; + +import edu.wmich.cs3310.a2.ComputeTime; + + +/** + * Tests for ComputeTime class. + */ +public class ComputeTimeTests { + + //region Variables + + long result; + Date date1; + Date date2; + ComputeTime computeTime; + Calendar calendar; + + //endregion Variables + + + + //region Tests + + @Before + public void SetUp() { + computeTime = new ComputeTime(); + date1 = new Date(); + calendar = Calendar.getInstance(); + } + + + @Test + public void TestEqualDate() { + date2 = date1; + result = computeTime.ComputeDateDifference(date1, date2); + Assert.assertEquals(0, result); + } + + + @Test + public void TestMillisecondDifference() { + // Date1 earlier than date2. + calendar.setTime(date1); + calendar.add(Calendar.MILLISECOND, 1); + date2 = calendar.getTime(); + result = computeTime.ComputeDateDifference(date1, date2); + Assert.assertEquals((1), result); + + // Date1 later than date2. + calendar.setTime(date1); + calendar.add(Calendar.MILLISECOND, -1); + date2 = calendar.getTime(); + result = computeTime.ComputeDateDifference(date1, date2); + Assert.assertEquals(-1, result); + } + + + @Test + public void TestSecondDifference() { + // Date1 earlier than date2. + calendar.setTime(date1); + calendar.add(Calendar.SECOND, 1); + date2 = calendar.getTime(); + result = computeTime.ComputeDateDifference(date1, date2); + Assert.assertEquals(1000, result); + + // Date1 later than date2. + calendar.setTime(date1); + calendar.add(Calendar.SECOND, -1); + date2 = calendar.getTime(); + result = computeTime.ComputeDateDifference(date1, date2); + Assert.assertEquals(-1000, result); + } + + + @Test + public void TestMinuteDifference() { + // Date1 earlier than date2. + calendar.setTime(date1); + calendar.add(Calendar.MINUTE, 1); + date2 = calendar.getTime(); + result = computeTime.ComputeDateDifference(date1, date2); + Assert.assertEquals((60 * 1000), result); + + // Date1 later than date2. + calendar.setTime(date1); + calendar.add(Calendar.MINUTE, -1); + date2 = calendar.getTime(); + result = computeTime.ComputeDateDifference(date1, date2); + Assert.assertEquals(-(60 * 1000), result); + } + + + @Test + public void TestHourDifference() { + // Date1 earlier than date2. + calendar.setTime(date1); + calendar.add(Calendar.HOUR, 1); + date2 = calendar.getTime(); + result = computeTime.ComputeDateDifference(date1, date2); + Assert.assertEquals((60 * 60 * 1000), result); + + // Date1 later than date2. + calendar.setTime(date1); + calendar.add(Calendar.HOUR, -1); + date2 = calendar.getTime(); + result = computeTime.ComputeDateDifference(date1, date2); + Assert.assertEquals(-(60 * 60 * 1000), result); + } + + + @Test + public void TestDayDifference() { + // Date1 earlier than date2. + calendar.setTime(date1); + calendar.add(Calendar.DAY_OF_MONTH, 1); + date2 = calendar.getTime(); + result = computeTime.ComputeDateDifference(date1, date2); + Assert.assertEquals((24 * 60 * 60 * 1000), result); + + // Date1 later than date2. + calendar.setTime(date1); + calendar.add(Calendar.DAY_OF_MONTH, -1); + date2 = calendar.getTime(); + result = computeTime.ComputeDateDifference(date1, date2); + Assert.assertEquals(-(24 * 60 * 60 * 1000), result); + } + + //endregion Tests +} diff --git a/a2/tests/DataStructures/CharListTests.java b/a2/tests/DataStructures/CharListTests.java new file mode 100644 index 0000000000000000000000000000000000000000..b1f5ab72b5108f6b6b2309452ea59ec4e8b15566 --- /dev/null +++ b/a2/tests/DataStructures/CharListTests.java @@ -0,0 +1,249 @@ +package DataStructures; + +import org.junit.Before; +import org.junit.Assert; +import org.junit.Test; + +import edu.wmich.cs3310.a2.DataStructures.CharList; +import edu.wmich.cs3310.a2.DataStructures.CharNode; + + +/** + * Tests for CharList class. + */ +public class CharListTests { + + //region Variables + + CharNode aNode; + CharList aList; + + //endregion Variables + + + + //region Tests + + @Before + public void setUp() { + aNode = new CharNode(); + aList = new CharList(); + } + + + @Test + public void Test_Insert_Success_OnlyFirst() { + Assert.assertNull(aList.firstNode()); + Assert.assertNull(aList.lastNode()); + + // Test inserting with 1 node. + Assert.assertTrue(aList.Insert('a', 0)); + Assert.assertEquals('a', aList.firstNode().myData()); + Assert.assertEquals(aList.firstNode(), aList.lastNode()); + + // Test inserting with 2 nodes. + Assert.assertTrue(aList.Insert('b', 0)); + Assert.assertEquals('b', aList.firstNode().myData()); + Assert.assertEquals('a', aList.lastNode().myData()); + Assert.assertEquals(aList.firstNode(), aList.lastNode().prevNode()); + Assert.assertEquals(aList.lastNode(), aList.firstNode().nextNode()); + + // Test inserting with 3 nodes. + Assert.assertTrue(aList.Insert('c', 0)); + Assert.assertEquals('c', aList.firstNode().myData()); + Assert.assertEquals('b', aList.firstNode().nextNode().myData()); + Assert.assertEquals(aList.firstNode(), aList.lastNode().prevNode().prevNode()); + Assert.assertEquals(aList.firstNode().nextNode(), aList.lastNode().prevNode()); + Assert.assertEquals(aList.firstNode().nextNode().nextNode(), aList.lastNode()); + } + + + @Test + public void Test_Insert_Success_OnlyLast() { + Assert.assertNull(aList.firstNode()); + Assert.assertNull(aList.lastNode()); + + // Test inserting with 1 node. + Assert.assertTrue(aList.Insert('a', 0)); + Assert.assertEquals('a', aList.firstNode().myData()); + Assert.assertEquals(aList.firstNode(), aList.lastNode()); + + // Test inserting with 2 nodes. + Assert.assertTrue(aList.Insert('b', 1)); + Assert.assertEquals('a', aList.firstNode().myData()); + Assert.assertEquals('b', aList.lastNode().myData()); + Assert.assertEquals(aList.firstNode(), aList.lastNode().prevNode()); + Assert.assertEquals(aList.lastNode(), aList.firstNode().nextNode()); + + // Test inserting with 3 nodes. + Assert.assertTrue(aList.Insert('c', 2)); + Assert.assertEquals('c', aList.lastNode().myData()); + Assert.assertEquals('b', aList.lastNode().prevNode().myData()); + Assert.assertEquals(aList.firstNode(), aList.lastNode().prevNode().prevNode()); + Assert.assertEquals(aList.firstNode().nextNode(), aList.lastNode().prevNode()); + Assert.assertEquals(aList.firstNode().nextNode().nextNode(), aList.lastNode()); + } + + + @Test + public void Test_Insert_Fail_BadIndex() { + Assert.assertNull(aList.firstNode()); + Assert.assertNull(aList.lastNode()); + Assert.assertFalse(aList.Insert('a', -1)); + Assert.assertFalse(aList.Insert('a', 1)); + + Assert.assertTrue(aList.Insert('a', 0)); + Assert.assertFalse(aList.Insert('b', -1)); + Assert.assertFalse(aList.Insert('b', 2)); + + Assert.assertTrue(aList.Insert('b', 1)); + Assert.assertFalse(aList.Insert('c', -1)); + Assert.assertFalse(aList.Insert('c', 3)); + } + + + @Test + public void Test_Delete_Index_Success_OnlyFirst() { + Assert.assertTrue(aList.Insert('a', 0)); + Assert.assertTrue(aList.Insert('b', 1)); + Assert.assertTrue(aList.Insert('c', 2)); + + // Test deleting with 3 nodes. + aNode = aList.Delete(0); + Assert.assertNotNull(aNode); + Assert.assertEquals('a', aNode.myData()); + Assert.assertNull(aNode.nextNode()); + Assert.assertNull(aNode.prevNode()); + Assert.assertEquals('b', aList.firstNode().myData()); + Assert.assertEquals('c', aList.lastNode().myData()); + Assert.assertEquals(aList.firstNode(), aList.lastNode().prevNode()); + Assert.assertEquals(aList.lastNode(), aList.firstNode().nextNode()); + + // Test deleting with 2 nodes. + aNode = aList.Delete(0); + Assert.assertNotNull(aNode); + Assert.assertEquals('b', aNode.myData()); + Assert.assertNull(aNode.nextNode()); + Assert.assertNull(aNode.prevNode()); + Assert.assertEquals('c', aList.firstNode().myData()); + Assert.assertEquals(aList.firstNode(), aList.lastNode()); + + // Test deleting with 1 nodes. + aNode = aList.Delete(0); + Assert.assertNotNull(aNode); + Assert.assertEquals('c', aNode.myData()); + Assert.assertNull(aNode.nextNode()); + Assert.assertNull(aNode.prevNode()); + Assert.assertNull(aList.firstNode()); + Assert.assertNull(aList.lastNode()); + } + + + @Test + public void Test_Delete_Index_Success_OnlyLast() { + Assert.assertTrue(aList.Insert('a', 0)); + Assert.assertTrue(aList.Insert('b', 1)); + Assert.assertTrue(aList.Insert('c', 2)); + + // Test deleting with 3 nodes. + aNode = aList.Delete(2); + Assert.assertNotNull(aNode); + Assert.assertEquals('c', aNode.myData()); + Assert.assertNull(aNode.nextNode()); + Assert.assertNull(aNode.prevNode()); + Assert.assertEquals('a', aList.firstNode().myData()); + Assert.assertEquals('b', aList.lastNode().myData()); + Assert.assertEquals(aList.firstNode(), aList.lastNode().prevNode()); + Assert.assertEquals(aList.lastNode(), aList.firstNode().nextNode()); + + // Test deleting with 2 nodes. + aNode = aList.Delete(1); + Assert.assertNotNull(aNode); + Assert.assertEquals('b', aNode.myData()); + Assert.assertNull(aNode.nextNode()); + Assert.assertNull(aNode.prevNode()); + Assert.assertEquals('a', aList.firstNode().myData()); + Assert.assertEquals(aList.firstNode(), aList.lastNode()); + + // Test deleting with 1 nodes. + aNode = aList.Delete(0); + Assert.assertNotNull(aNode); + Assert.assertEquals('a', aNode.myData()); + Assert.assertNull(aNode.nextNode()); + Assert.assertNull(aNode.prevNode()); + Assert.assertNull(aList.firstNode()); + Assert.assertNull(aList.lastNode()); + } + + + @Test + public void Test_Delete_Index_Fail_BadIndex() { + // Test deleting with 0 nodes. + Assert.assertNull(aList.Delete(0)); + Assert.assertTrue(aList.Insert('a', 0)); + + // Test deleting with 1 nodes. + Assert.assertNull(aList.Delete(-1)); + Assert.assertNull(aList.Delete(1)); + Assert.assertTrue(aList.Insert('b', 1)); + + // Test deleting with 2 nodes. + Assert.assertNull(aList.Delete(-1)); + Assert.assertNull(aList.Delete(2)); + } + + + @Test + public void Test_Delete_Char_Success() { + Assert.assertTrue(aList.Insert('a', 0)); + Assert.assertTrue(aList.Insert('b', 1)); + Assert.assertTrue(aList.Insert('c', 2)); + + // Test deleting with 3 nodes. + aNode = aList.Delete('c'); + Assert.assertNotNull(aNode); + Assert.assertEquals('c', aNode.myData()); + Assert.assertNull(aNode.nextNode()); + Assert.assertNull(aNode.prevNode()); + Assert.assertEquals('a', aList.firstNode().myData()); + Assert.assertEquals('b', aList.lastNode().myData()); + Assert.assertEquals(aList.firstNode(), aList.lastNode().prevNode()); + Assert.assertEquals(aList.lastNode(), aList.firstNode().nextNode()); + + // Test deleting with 2 nodes. + aNode = aList.Delete('b'); + Assert.assertNotNull(aNode); + Assert.assertEquals('b', aNode.myData()); + Assert.assertNull(aNode.nextNode()); + Assert.assertNull(aNode.prevNode()); + Assert.assertEquals('a', aList.firstNode().myData()); + Assert.assertEquals(aList.firstNode(), aList.lastNode()); + + + // Test deleting with 1 nodes. + aNode = aList.Delete('a'); + Assert.assertNotNull(aNode); + Assert.assertEquals('a', aNode.myData()); + Assert.assertNull(aNode.nextNode()); + Assert.assertNull(aNode.prevNode()); + Assert.assertNull(aList.firstNode()); + Assert.assertNull(aList.lastNode()); + } + + + @Test + public void Test_Delete_Char_Fail() { + // Test deleting with 0 nodes. + Assert.assertNull(aList.Delete('a')); + Assert.assertTrue(aList.Insert('a', 0)); + + // Test deleting with 1 nodes. + Assert.assertNull(aList.Delete('b')); + Assert.assertTrue(aList.Insert('b', 1)); + + // Test deleting with 2 nodes. + Assert.assertNull(aList.Delete('c')); + } + + //endregion Tests +} diff --git a/a2/tests/DataStructures/CharNodeTests.java b/a2/tests/DataStructures/CharNodeTests.java new file mode 100644 index 0000000000000000000000000000000000000000..becdd1e2aafd539e2e6d24d1e7231c61f4dd7893 --- /dev/null +++ b/a2/tests/DataStructures/CharNodeTests.java @@ -0,0 +1,62 @@ +package DataStructures; + +import org.junit.Before; +import org.junit.Assert; +import org.junit.Test; + +import edu.wmich.cs3310.a2.DataStructures.CharNode; + + +/** + * Tests for CharNode class. + */ +public class CharNodeTests { + + //region Variables + + CharNode aNode; + + //endregion Variables + + + + //region Tests + + @Before + public void setUp() { + aNode = new CharNode(); + } + + + @Test + public void TestNodeData() { + aNode.myData('a'); + Assert.assertEquals('a', aNode.myData()); + aNode.myData('b'); + Assert.assertEquals('b', aNode.myData()); + } + + + @Test + public void TestNextNode() { + Assert.assertNull(aNode.nextNode()); + CharNode nextNode = new CharNode(); + nextNode.myData('c'); + aNode.nextNode(nextNode); + Assert.assertEquals(nextNode, aNode.nextNode()); + Assert.assertEquals('c', aNode.nextNode().myData()); + } + + + @Test + public void TestPrevNode() { + Assert.assertNull(aNode.prevNode()); + CharNode prevNode = new CharNode(); + prevNode.myData('d'); + aNode.prevNode(prevNode); + Assert.assertEquals(prevNode, aNode.prevNode()); + Assert.assertEquals('d', aNode.prevNode().myData()); + } + + //endregion Tests +} diff --git a/a2/tests/DataStructures/CharQueueTests.java b/a2/tests/DataStructures/CharQueueTests.java new file mode 100644 index 0000000000000000000000000000000000000000..c75aac17ad49c4425128c778d2f91c6f37c7dc76 --- /dev/null +++ b/a2/tests/DataStructures/CharQueueTests.java @@ -0,0 +1,147 @@ +package DataStructures; + +import org.junit.Before; +import org.junit.Assert; +import org.junit.Test; + +import edu.wmich.cs3310.a2.DataStructures.CharQueue; +import edu.wmich.cs3310.a2.DataStructures.CharNode; + + +/** + * Tests for CharQueue class. + */ +public class CharQueueTests { + + //region Variables + + CharNode aNode; + CharQueue aQueue; + + //endregion Variables + + //region Tests + + @Before + public void setUp() { + aNode = new CharNode(); + aQueue = new CharQueue(); + } + + + @Test + public void Test_Enqueue() { + Assert.assertNull(aQueue.headNode()); + Assert.assertNull(aQueue.tailNode()); + + // Test enqueueing with one node. + aQueue.Enqueue('a'); + Assert.assertEquals('a', aQueue.headNode().myData()); + Assert.assertNull(aQueue.headNode().prevNode()); + Assert.assertNull(aQueue.tailNode().nextNode()); + Assert.assertEquals(aQueue.headNode(), aQueue.tailNode()); + + // Test enqueueing with two nodes. + aQueue.Enqueue('b'); + Assert.assertEquals('a', aQueue.headNode().myData()); + Assert.assertEquals('b', aQueue.tailNode().myData()); + Assert.assertNull(aQueue.headNode().prevNode()); + Assert.assertNull(aQueue.tailNode().nextNode()); + Assert.assertEquals(aQueue.headNode(), aQueue.tailNode().prevNode()); + Assert.assertEquals(aQueue.tailNode(), aQueue.headNode().nextNode()); + + // Test enqueueing with three nodes. + aQueue.Enqueue('c'); + Assert.assertEquals('a', aQueue.headNode().myData()); + Assert.assertEquals('b', aQueue.headNode().nextNode().myData()); + Assert.assertEquals('c', aQueue.tailNode().myData()); + Assert.assertNull(aQueue.headNode().prevNode()); + Assert.assertNull(aQueue.tailNode().nextNode()); + Assert.assertEquals(aQueue.headNode(), aQueue.tailNode().prevNode().prevNode()); + Assert.assertEquals(aQueue.headNode().nextNode(), aQueue.tailNode().prevNode()); + Assert.assertEquals(aQueue.headNode().nextNode().nextNode(), aQueue.tailNode()); + } + + + @Test + public void Test_Enqueue_Singly() { + Assert.assertNull(aQueue.headNode()); + Assert.assertNull(aQueue.tailNode()); + + // Test enqueueing with one node. + aQueue.Enqueue_Singly('a'); + Assert.assertEquals('a', aQueue.headNode().myData()); + Assert.assertNull(aQueue.headNode().prevNode()); + Assert.assertNull(aQueue.tailNode().nextNode()); + Assert.assertEquals(aQueue.headNode(), aQueue.tailNode()); + + // Test enqueueing with two nodes. + aQueue.Enqueue_Singly('b'); + Assert.assertEquals('a', aQueue.headNode().myData()); + Assert.assertEquals('b', aQueue.tailNode().myData()); + Assert.assertNull(aQueue.headNode().prevNode()); + Assert.assertNull(aQueue.tailNode().nextNode()); + Assert.assertEquals(aQueue.headNode(), aQueue.tailNode().prevNode()); + Assert.assertEquals(aQueue.tailNode(), aQueue.headNode().nextNode()); + + // Test enqueueing with three nodes. + aQueue.Enqueue_Singly('c'); + Assert.assertEquals('a', aQueue.headNode().myData()); + Assert.assertEquals('b', aQueue.headNode().nextNode().myData()); + Assert.assertEquals('c', aQueue.tailNode().myData()); + Assert.assertNull(aQueue.headNode().prevNode()); + Assert.assertNull(aQueue.tailNode().nextNode()); + Assert.assertEquals(aQueue.headNode(), aQueue.tailNode().prevNode().prevNode()); + Assert.assertEquals(aQueue.headNode().nextNode(), aQueue.tailNode().prevNode()); + Assert.assertEquals(aQueue.headNode().nextNode().nextNode(), aQueue.tailNode()); + } + + + @Test + public void Test_Dequeue() { + aQueue.Enqueue('a'); + aQueue.Enqueue('b'); + aQueue.Enqueue('c'); + + // Test dequeueing with three nodes. + aNode = aQueue.Dequeue(); + Assert.assertNotNull(aNode); + Assert.assertEquals('a', aNode.myData()); + Assert.assertNull(aNode.prevNode()); + Assert.assertNull(aNode.nextNode()); + Assert.assertEquals('b', aQueue.headNode().myData()); + Assert.assertEquals('c', aQueue.tailNode().myData()); + Assert.assertNull(aQueue.headNode().prevNode()); + Assert.assertNull(aQueue.tailNode().nextNode()); + Assert.assertEquals(aQueue.headNode(), aQueue.tailNode().prevNode()); + Assert.assertEquals(aQueue.tailNode(), aQueue.headNode().nextNode()); + + // Test dequeueing with two nodes. + aNode = aQueue.Dequeue(); + Assert.assertNotNull(aNode); + Assert.assertEquals('b', aNode.myData()); + Assert.assertNull(aNode.prevNode()); + Assert.assertNull(aNode.nextNode()); + Assert.assertEquals('c', aQueue.headNode().myData()); + Assert.assertNull(aQueue.headNode().prevNode()); + Assert.assertNull(aQueue.headNode().nextNode()); + Assert.assertEquals(aQueue.headNode(), aQueue.tailNode()); + + // Test dequeueing with one node. + aNode = aQueue.Dequeue(); + Assert.assertNotNull(aNode); + Assert.assertEquals('c', aNode.myData()); + Assert.assertNull(aNode.prevNode()); + Assert.assertNull(aNode.nextNode()); + Assert.assertNull(aQueue.headNode()); + Assert.assertNull(aQueue.tailNode()); + + // Test dequeueing with zero nodes. + aNode = aQueue.Dequeue(); + Assert.assertNull(aNode); + } + + + + //endregion Tests +} diff --git a/a2/tests/DataStructures/CharStackTests.java b/a2/tests/DataStructures/CharStackTests.java new file mode 100644 index 0000000000000000000000000000000000000000..bb5db1bfbfd28d4ff0350924fb5554f3246b0782 --- /dev/null +++ b/a2/tests/DataStructures/CharStackTests.java @@ -0,0 +1,101 @@ +package DataStructures; + +import org.junit.Before; +import org.junit.Assert; +import org.junit.Test; + +import edu.wmich.cs3310.a2.DataStructures.CharStack; +import edu.wmich.cs3310.a2.DataStructures.CharNode; + + +/** + * Tests for CharStack class. + */ +public class CharStackTests { + + //region Variables + + CharNode aNode; + CharStack aStack; + + //endregion Variables + + //region Tests + + @Before + public void setUp() { + aNode = new CharNode(); + aStack = new CharStack(); + } + + + @Test + public void Test_Push() { + Assert.assertNull(aStack.headNode()); + + // Test pushing with 1 node. + aStack.Push('a'); + Assert.assertEquals('a', aStack.headNode().myData()); + Assert.assertNull(aStack.headNode().prevNode()); + Assert.assertNull(aStack.headNode().nextNode()); + + // Test pushing with 2 nodes. + aStack.Push('b'); + Assert.assertEquals('b', aStack.headNode().myData()); + Assert.assertEquals('a', aStack.headNode().nextNode().myData()); + Assert.assertNull(aStack.headNode().prevNode()); + Assert.assertNull(aStack.headNode().nextNode().nextNode()); + + + // Test pushing with 3 nodes. + aStack.Push('c'); + Assert.assertEquals('c', aStack.headNode().myData()); + Assert.assertEquals('b', aStack.headNode().nextNode().myData()); + Assert.assertEquals('a', aStack.headNode().nextNode().nextNode().myData()); + Assert.assertNull(aStack.headNode().prevNode()); + Assert.assertNull(aStack.headNode().nextNode().nextNode().nextNode()); + } + + + @Test + public void Test_Pop() { + aStack.Push('a'); + aStack.Push('b'); + aStack.Push('c'); + + // Test popping with 3 nodes. + aNode = aStack.Pop(); + Assert.assertNotNull(aNode); + Assert.assertEquals('c', aNode.myData()); + Assert.assertNull(aNode.prevNode()); + Assert.assertNull(aNode.nextNode()); + Assert.assertEquals('b', aStack.headNode().myData()); + Assert.assertEquals('a', aStack.headNode().nextNode().myData()); + Assert.assertNull(aStack.headNode().prevNode()); + Assert.assertNull(aStack.headNode().nextNode().nextNode()); + + // Test popping with 2 nodes. + aNode = aStack.Pop(); + Assert.assertNotNull(aNode); + Assert.assertEquals('b', aNode.myData()); + Assert.assertNull(aNode.prevNode()); + Assert.assertNull(aNode.nextNode()); + Assert.assertEquals('a', aStack.headNode().myData()); + Assert.assertNull(aStack.headNode().prevNode()); + Assert.assertNull(aStack.headNode().nextNode()); + + // Test popping with 1 node. + aNode = aStack.Pop(); + Assert.assertNotNull(aNode); + Assert.assertEquals('a', aNode.myData()); + Assert.assertNull(aNode.prevNode()); + Assert.assertNull(aNode.nextNode()); + Assert.assertNull(aStack.headNode()); + + // Test popping with 0 nodes. + aNode = aStack.Pop(); + Assert.assertNull(aNode); + } + + //endregion Tests +}