diff --git a/tests/edu/caltech/cs2/datastructures/ArrayDequeTests.java b/tests/edu/caltech/cs2/datastructures/ArrayDequeTests.java index 93534150154c78e18648ebae639f180bdfa0d88f..3d50ffa45f2f9adbbf491f1d5722938961cd58e3 100644 --- a/tests/edu/caltech/cs2/datastructures/ArrayDequeTests.java +++ b/tests/edu/caltech/cs2/datastructures/ArrayDequeTests.java @@ -3,30 +3,25 @@ package edu.caltech.cs2.datastructures; import edu.caltech.cs2.helpers.Inspection; import edu.caltech.cs2.helpers.Reflection; import edu.caltech.cs2.helpers.RuntimeInstrumentation; -import edu.caltech.cs2.interfaces.ICollection; -import edu.caltech.cs2.interfaces.IQueue; -import edu.caltech.cs2.interfaces.IDeque; -import edu.caltech.cs2.interfaces.IStack; +import edu.caltech.cs2.interfaces.*; import org.junit.jupiter.api.*; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.ValueSource; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.util.*; -import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Stream; import static edu.caltech.cs2.project03.Project03TestOrdering.*; import static java.util.concurrent.TimeUnit.SECONDS; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.*; @TestMethodOrder(MethodOrderer.OrderAnnotation.class) @Tag("C") -public class ArrayDequeTests implements DequeTests, StackTests, QueueTests { +public class ArrayDequeTests implements IDequeTests, IStackTests, IQueueTests { private static String ARRAY_DEQUE_SOURCE ="src/edu/caltech/cs2/datastructures/ArrayDeque.java"; private Constructor arrayDequeConstructor = Reflection.getConstructor(ArrayDeque.class); @@ -131,6 +126,44 @@ public class ArrayDequeTests implements DequeTests, StackTests, QueueTests { Inspection.assertConstructorHygiene(ARRAY_DEQUE_SOURCE); } + // ARRAYDEQUE TESTS --------------------------------------------------- + + @Order(implSpecificTestLevel) + @DisplayName("The default capacity of the array is 10") + @Test + public void testArrayDequeDefaultInitialCapacity() throws IllegalAccessException { + ArrayDeque<Integer> impl = new ArrayDeque<>(); + + // Reflect and get the backing array + // It's actually an Object[] since that's how it (should!) be initialized internally + // Casting it doesn't change the type of the field. + // It's fine since there should only be one array. + Field arr = Reflection.getFieldByType(ArrayDeque.class, Object[].class); + arr.setAccessible(true); + Integer[] backingArray = (Integer[]) arr.get(impl); + + assertEquals(10, backingArray.length, "Default initial capacity is not 10"); + } + + @Order(implSpecificTestLevel) + @DisplayName("enqueue should always succeed") + @Test + public void testThatArrayDequeEnqueueAlwaysSucceeds() { + ArrayDeque<Integer> impl = new ArrayDeque<>(); + for (int i = 0; i < 100; i ++) { + assertTrue(impl.enqueue(i), "enqueue() should always succeed for ArrayDeque"); + } + } + + @Order(implSpecificTestLevel) + @DisplayName("push should always succeed") + @Test + public void testThatArrayDequePushAlwaysSucceeds() { + ArrayDeque<Integer> impl = new ArrayDeque<>(); + for (int i = 0; i < 100; i ++) { + assertTrue(impl.push(i), "push() should always succeed for ArrayDeque"); + } + } // TOSTRING TESTS --------------------------------------------------- @@ -179,7 +212,7 @@ public class ArrayDequeTests implements DequeTests, StackTests, QueueTests { } @Order(complexityTestLevel) - @DisplayName("addBack() and removeBack() take linear time") + @DisplayName("addBack() and removeBack() take constant time") @Timeout(value = 20, unit = SECONDS) @Test public void testBackDequeOperationComplexity() { @@ -193,8 +226,8 @@ public class ArrayDequeTests implements DequeTests, StackTests, QueueTests { Consumer<IDeque<Integer>> addBack = (IDeque<Integer> q) -> q.addBack(0); Consumer<IDeque<Integer>> removeBack = (IDeque<Integer> q) -> q.removeBack(); - RuntimeInstrumentation.assertAtMost("addBack", RuntimeInstrumentation.ComplexityType.LINEAR, provide, addBack, 8); - RuntimeInstrumentation.assertAtMost("removeBack", RuntimeInstrumentation.ComplexityType.LINEAR, provide, removeBack, 8); + RuntimeInstrumentation.assertAtMost("addBack", RuntimeInstrumentation.ComplexityType.CONSTANT, provide, addBack, 8); + RuntimeInstrumentation.assertAtMost("removeBack", RuntimeInstrumentation.ComplexityType.CONSTANT, provide, removeBack, 8); } @Order(complexityTestLevel) diff --git a/tests/edu/caltech/cs2/datastructures/CircularArrayFixedSizeQueueTests.java b/tests/edu/caltech/cs2/datastructures/CircularArrayFixedSizeQueueTests.java index c1ca90d88c626ead24b918f843850fecec74af22..c9e2b8236b1a80c320b1a767ca0c6599d4d15b4d 100644 --- a/tests/edu/caltech/cs2/datastructures/CircularArrayFixedSizeQueueTests.java +++ b/tests/edu/caltech/cs2/datastructures/CircularArrayFixedSizeQueueTests.java @@ -3,6 +3,7 @@ package edu.caltech.cs2.datastructures; import edu.caltech.cs2.helpers.Inspection; import edu.caltech.cs2.helpers.Reflection; import edu.caltech.cs2.helpers.RuntimeInstrumentation; +import edu.caltech.cs2.interfaces.IFixedSizeQueueTests; import edu.caltech.cs2.interfaces.IFixedSizeQueue; import edu.caltech.cs2.interfaces.IQueue; import org.junit.jupiter.api.*; @@ -21,7 +22,7 @@ import static org.junit.jupiter.api.Assertions.*; @Tag("B") @TestMethodOrder(MethodOrderer.OrderAnnotation.class) -public class CircularArrayFixedSizeQueueTests implements FixedSizeQueueTests { +public class CircularArrayFixedSizeQueueTests implements IFixedSizeQueueTests { private static String FIXED_QUEUE_SOURCE = "src/edu/caltech/cs2/datastructures/CircularArrayFixedSizeQueue.java"; private Constructor circFixedSizeQueueConstructor = Reflection.getConstructor(CircularArrayFixedSizeQueue.class, diff --git a/tests/edu/caltech/cs2/datastructures/LinkedDequeTests.java b/tests/edu/caltech/cs2/datastructures/LinkedDequeTests.java index 40961504a967197edf47cd69a78d77dd7861366a..83fd0af46977ce79f3d9f662cc96638da37cb576 100644 --- a/tests/edu/caltech/cs2/datastructures/LinkedDequeTests.java +++ b/tests/edu/caltech/cs2/datastructures/LinkedDequeTests.java @@ -4,11 +4,7 @@ import edu.caltech.cs2.helpers.Inspection; import edu.caltech.cs2.helpers.NodeChecker; import edu.caltech.cs2.helpers.Reflection; import edu.caltech.cs2.helpers.RuntimeInstrumentation; -import edu.caltech.cs2.interfaces.ICollection; -import edu.caltech.cs2.interfaces.IDeque; -import edu.caltech.cs2.interfaces.IQueue; -import edu.caltech.cs2.interfaces.IStack; -import edu.caltech.cs2.project03.Project03TestOrdering.*; +import edu.caltech.cs2.interfaces.*; import org.junit.jupiter.api.*; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; @@ -27,7 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; @Tag("C") @TestMethodOrder(MethodOrderer.OrderAnnotation.class) -public class LinkedDequeTests implements DequeTests, StackTests, QueueTests { +public class LinkedDequeTests implements IDequeTests, IStackTests, IQueueTests { private static String LINKED_DEQUE_SOURCE = "src/edu/caltech/cs2/datastructures/LinkedDeque.java"; private Constructor linkedDequeConstructor = Reflection.getConstructor(LinkedDeque.class); @@ -114,7 +110,7 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests { } @Order(classSpecificTestLevel) - @DisplayName("Check for linked node class") + @DisplayName("Check that LinkedDeque uses a node class") @Test public void testLinkedNode() { Class[] classes = LinkedDeque.class.getDeclaredClasses(); @@ -283,6 +279,8 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests { 8); } + // "LINKED-NESS" TESTS ------------------------------------------------ + @Order(dequeTestLevel) @DisplayName("Cycle detection for addFront(...), addBack(...), removeFront(...), and removeBack(...)") @ParameterizedTest(name = "Test cycles - {1} random numbers with seed = {0}") @@ -293,7 +291,7 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests { IDeque<Object> impl = new LinkedDeque<>(); // Test that first peek is null assertNull(impl.peekFront(), "empty peek should return null"); - // Test adding values updates size and displays contained correctly + // Randomly add / remove elements to the front / back for (int i = 0; i < size; i++) { int num = r.nextInt(); if (num % 2 == 0) { @@ -312,7 +310,9 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests { impl.removeBack(); } } + // After each operation, check whether cycles have formed NodeChecker.cycleDetection(impl, true); + // Sanity checks, though these aren't super necessary assertEquals(reference.size(), impl.size(), "size()s are not equal"); assertEquals(reference.toString(), impl.toString(), "toStrings()s are not equal"); } @@ -328,7 +328,7 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests { IDeque<Object> impl = new LinkedDeque<>(); // Test that first peek is null assertNull(impl.peekFront(), "empty peek should return null"); - // Test adding values updates size and displays contained correctly + // Randomly add / remove elements to the front / back for (int i = 0; i < size; i++) { int num = r.nextInt(); if (num % 2 == 0) { @@ -347,6 +347,7 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests { impl.removeBack(); } } + // Check that forwards and backwards iteration are sane NodeChecker.checkReverse(impl); assertEquals(reference.size(), impl.size(), "size()s are not equal"); assertEquals(reference.toString(), impl.toString(), "toStrings()s are not equal"); diff --git a/tests/edu/caltech/cs2/datastructures/CollectionTests.java b/tests/edu/caltech/cs2/interfaces/ICollectionTests.java similarity index 97% rename from tests/edu/caltech/cs2/datastructures/CollectionTests.java rename to tests/edu/caltech/cs2/interfaces/ICollectionTests.java index bbc3b056679f4dd4a69699e0676d5bb4eaf206da..dd97298717f56d8b07903450a6fda73915f0439a 100644 --- a/tests/edu/caltech/cs2/datastructures/CollectionTests.java +++ b/tests/edu/caltech/cs2/interfaces/ICollectionTests.java @@ -1,4 +1,4 @@ -package edu.caltech.cs2.datastructures; +package edu.caltech.cs2.interfaces; import edu.caltech.cs2.interfaces.ICollection; import org.junit.jupiter.api.DisplayName; @@ -17,7 +17,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -public interface CollectionTests { +public interface ICollectionTests { ICollection<Object> newCollection(); @Order(collectionTestLevel) @@ -124,7 +124,7 @@ public interface CollectionTests { // Shuffle order of nums and check that all are contained in the collection Collections.shuffle(nums); for (int num : nums) { - assertEquals(true, impl.contains(num), "value should be contained"); + assertTrue(impl.contains(num), "value should be contained"); } // Test that values not in collection are not contained diff --git a/tests/edu/caltech/cs2/datastructures/DequeTests.java b/tests/edu/caltech/cs2/interfaces/IDequeTests.java similarity index 97% rename from tests/edu/caltech/cs2/datastructures/DequeTests.java rename to tests/edu/caltech/cs2/interfaces/IDequeTests.java index c2f1e6903987a8ac92caf3b949dfe1a7befb3806..befe84f370c3d69413ab4eab73086931ec351f9a 100644 --- a/tests/edu/caltech/cs2/datastructures/DequeTests.java +++ b/tests/edu/caltech/cs2/interfaces/IDequeTests.java @@ -1,7 +1,5 @@ -package edu.caltech.cs2.datastructures; +package edu.caltech.cs2.interfaces; -import edu.caltech.cs2.interfaces.ICollection; -import edu.caltech.cs2.interfaces.IDeque; import org.hamcrest.MatcherAssert; import org.hamcrest.collection.IsEmptyIterable; import org.junit.jupiter.api.DisplayName; @@ -20,7 +18,7 @@ import java.util.Random; import static edu.caltech.cs2.project03.Project03TestOrdering.*; import static org.junit.jupiter.api.Assertions.*; -public interface DequeTests extends CollectionTests { +public interface IDequeTests extends ICollectionTests { IDeque<Object> newDeque(); @Order(dequeTestLevel) @@ -42,7 +40,8 @@ public interface DequeTests extends CollectionTests { ref.addLast(value); MatcherAssert.assertThat(impl, IsIterableContainingInOrder.contains(ref.toArray())); } - for (Object value : inputs.trim().split(", ")) { + // Check that iterator is consistent while objects are removed from the back + for (Object ignored : inputs.trim().split(", ")) { MatcherAssert.assertThat(impl, IsIterableContainingInOrder.contains(ref.toArray())); impl.removeBack(); ref.removeLast(); @@ -291,8 +290,7 @@ public interface DequeTests extends CollectionTests { coll.add(num); } impl.addAll(coll); - for (Object num : coll) { - assertTrue(impl.contains(num), "value should be contained in Deque"); - } + + MatcherAssert.assertThat("IDeque has incorrect elements / order", impl, IsIterableContainingInOrder.contains(coll)); } } diff --git a/tests/edu/caltech/cs2/datastructures/FixedSizeQueueTests.java b/tests/edu/caltech/cs2/interfaces/IFixedSizeQueueTests.java similarity index 93% rename from tests/edu/caltech/cs2/datastructures/FixedSizeQueueTests.java rename to tests/edu/caltech/cs2/interfaces/IFixedSizeQueueTests.java index fed881f0ee5b6a85f4ad62261647aad54382c29c..b60b17f64187891063878bec2e07f6e54d0d7fde 100644 --- a/tests/edu/caltech/cs2/datastructures/FixedSizeQueueTests.java +++ b/tests/edu/caltech/cs2/interfaces/IFixedSizeQueueTests.java @@ -1,10 +1,9 @@ -package edu.caltech.cs2.datastructures; +package edu.caltech.cs2.interfaces; +import edu.caltech.cs2.datastructures.CircularArrayFixedSizeQueue; import edu.caltech.cs2.helpers.Reflection; -import edu.caltech.cs2.interfaces.IFixedSizeQueue; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Tag; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; @@ -15,7 +14,7 @@ import java.util.Random; import static edu.caltech.cs2.project03.Project03TestOrdering.*; import static org.junit.jupiter.api.Assertions.assertEquals; -public interface FixedSizeQueueTests extends QueueTests { +public interface IFixedSizeQueueTests extends IQueueTests { IFixedSizeQueue<Object> newFixedSizeQueue(int capacity); @Order(fixedSizeQueueLevel) diff --git a/tests/edu/caltech/cs2/datastructures/QueueTests.java b/tests/edu/caltech/cs2/interfaces/IQueueTests.java similarity index 97% rename from tests/edu/caltech/cs2/datastructures/QueueTests.java rename to tests/edu/caltech/cs2/interfaces/IQueueTests.java index 552b502bb9ffdf9e563787d37fbdb5dcc4a23082..92bc04d779e84726f0ea080e75a024ca1eee31a2 100644 --- a/tests/edu/caltech/cs2/datastructures/QueueTests.java +++ b/tests/edu/caltech/cs2/interfaces/IQueueTests.java @@ -1,4 +1,4 @@ -package edu.caltech.cs2.datastructures; +package edu.caltech.cs2.interfaces; import edu.caltech.cs2.interfaces.IQueue; import edu.caltech.cs2.interfaces.IStack; @@ -14,7 +14,7 @@ import java.util.Random; import static edu.caltech.cs2.project03.Project03TestOrdering.*; import static org.junit.jupiter.api.Assertions.*; -public interface QueueTests { +public interface IQueueTests { IQueue<Object> newQueue(); IQueue<Object> newQueue(int size); diff --git a/tests/edu/caltech/cs2/datastructures/StackTests.java b/tests/edu/caltech/cs2/interfaces/IStackTests.java similarity index 97% rename from tests/edu/caltech/cs2/datastructures/StackTests.java rename to tests/edu/caltech/cs2/interfaces/IStackTests.java index 95d7ce1bfc1895913be21c69fcd9ad23e3bcf127..5878d8020eec72526fa62dc5cf4e8aee47c71d1e 100644 --- a/tests/edu/caltech/cs2/datastructures/StackTests.java +++ b/tests/edu/caltech/cs2/interfaces/IStackTests.java @@ -1,4 +1,4 @@ -package edu.caltech.cs2.datastructures; +package edu.caltech.cs2.interfaces; import edu.caltech.cs2.interfaces.IStack; import org.junit.jupiter.api.DisplayName; @@ -13,7 +13,7 @@ import static edu.caltech.cs2.project03.Project03TestOrdering.*; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; -public interface StackTests { +public interface IStackTests { IStack<Object> newStack(); @Order(stackTestLevel) diff --git a/tests/edu/caltech/cs2/project03/Project03TestOrdering.java b/tests/edu/caltech/cs2/project03/Project03TestOrdering.java index 1cbf6315694262bb37c4ffc2f1af112ba7f81163..86a4c349d98e8afab90c55942b0bdb8b552187f1 100644 --- a/tests/edu/caltech/cs2/project03/Project03TestOrdering.java +++ b/tests/edu/caltech/cs2/project03/Project03TestOrdering.java @@ -5,6 +5,7 @@ public final class Project03TestOrdering { throw new InstantiationError("Class is only for storing constant variables"); } + // Tests related to class structure public static final int classSpecificTestLevel = 0; public static final int collectionTestLevel = 1; @@ -14,8 +15,11 @@ public final class Project03TestOrdering { public static final int fixedSizeQueueLevel = 3; - public static final int toStringTestLevel = 4; - public static final int complexityTestLevel = 5; + // Tests related to the particular implementation + public static final int implSpecificTestLevel = 4; - public static final int guitarStringTestLevel = 6; + public static final int toStringTestLevel = 5; + public static final int complexityTestLevel = 6; + + public static final int guitarStringTestLevel = 7; }