Commit 8b332aad authored by Adam H. Abbas's avatar Adam H. Abbas
Browse files

Merge branch 'small-revisions' into 'master'

Small revisions

Closes #4

See merge request !2
1 merge request!2Small revisions
Pipeline #43524 failed with stage
in 0 seconds
Showing with 79 additions and 43 deletions
+79 -43
...@@ -3,30 +3,25 @@ package edu.caltech.cs2.datastructures; ...@@ -3,30 +3,25 @@ package edu.caltech.cs2.datastructures;
import edu.caltech.cs2.helpers.Inspection; import edu.caltech.cs2.helpers.Inspection;
import edu.caltech.cs2.helpers.Reflection; import edu.caltech.cs2.helpers.Reflection;
import edu.caltech.cs2.helpers.RuntimeInstrumentation; import edu.caltech.cs2.helpers.RuntimeInstrumentation;
import edu.caltech.cs2.interfaces.ICollection; import edu.caltech.cs2.interfaces.*;
import edu.caltech.cs2.interfaces.IQueue;
import edu.caltech.cs2.interfaces.IDeque;
import edu.caltech.cs2.interfaces.IStack;
import org.junit.jupiter.api.*; import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.ValueSource; import org.junit.jupiter.params.provider.ValueSource;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Stream; import java.util.stream.Stream;
import static edu.caltech.cs2.project03.Project03TestOrdering.*; import static edu.caltech.cs2.project03.Project03TestOrdering.*;
import static java.util.concurrent.TimeUnit.SECONDS; 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) @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@Tag("C") @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 static String ARRAY_DEQUE_SOURCE ="src/edu/caltech/cs2/datastructures/ArrayDeque.java";
private Constructor arrayDequeConstructor = Reflection.getConstructor(ArrayDeque.class); private Constructor arrayDequeConstructor = Reflection.getConstructor(ArrayDeque.class);
...@@ -131,6 +126,44 @@ public class ArrayDequeTests implements DequeTests, StackTests, QueueTests { ...@@ -131,6 +126,44 @@ public class ArrayDequeTests implements DequeTests, StackTests, QueueTests {
Inspection.assertConstructorHygiene(ARRAY_DEQUE_SOURCE); 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 --------------------------------------------------- // TOSTRING TESTS ---------------------------------------------------
...@@ -179,7 +212,7 @@ public class ArrayDequeTests implements DequeTests, StackTests, QueueTests { ...@@ -179,7 +212,7 @@ public class ArrayDequeTests implements DequeTests, StackTests, QueueTests {
} }
@Order(complexityTestLevel) @Order(complexityTestLevel)
@DisplayName("addBack() and removeBack() take linear time") @DisplayName("addBack() and removeBack() take constant time")
@Timeout(value = 20, unit = SECONDS) @Timeout(value = 20, unit = SECONDS)
@Test @Test
public void testBackDequeOperationComplexity() { public void testBackDequeOperationComplexity() {
...@@ -193,8 +226,8 @@ public class ArrayDequeTests implements DequeTests, StackTests, QueueTests { ...@@ -193,8 +226,8 @@ public class ArrayDequeTests implements DequeTests, StackTests, QueueTests {
Consumer<IDeque<Integer>> addBack = (IDeque<Integer> q) -> q.addBack(0); Consumer<IDeque<Integer>> addBack = (IDeque<Integer> q) -> q.addBack(0);
Consumer<IDeque<Integer>> removeBack = (IDeque<Integer> q) -> q.removeBack(); Consumer<IDeque<Integer>> removeBack = (IDeque<Integer> q) -> q.removeBack();
RuntimeInstrumentation.assertAtMost("addBack", RuntimeInstrumentation.ComplexityType.LINEAR, provide, addBack, 8); RuntimeInstrumentation.assertAtMost("addBack", RuntimeInstrumentation.ComplexityType.CONSTANT, provide, addBack, 8);
RuntimeInstrumentation.assertAtMost("removeBack", RuntimeInstrumentation.ComplexityType.LINEAR, provide, removeBack, 8); RuntimeInstrumentation.assertAtMost("removeBack", RuntimeInstrumentation.ComplexityType.CONSTANT, provide, removeBack, 8);
} }
@Order(complexityTestLevel) @Order(complexityTestLevel)
......
...@@ -3,6 +3,7 @@ package edu.caltech.cs2.datastructures; ...@@ -3,6 +3,7 @@ package edu.caltech.cs2.datastructures;
import edu.caltech.cs2.helpers.Inspection; import edu.caltech.cs2.helpers.Inspection;
import edu.caltech.cs2.helpers.Reflection; import edu.caltech.cs2.helpers.Reflection;
import edu.caltech.cs2.helpers.RuntimeInstrumentation; import edu.caltech.cs2.helpers.RuntimeInstrumentation;
import edu.caltech.cs2.interfaces.IFixedSizeQueueTests;
import edu.caltech.cs2.interfaces.IFixedSizeQueue; import edu.caltech.cs2.interfaces.IFixedSizeQueue;
import edu.caltech.cs2.interfaces.IQueue; import edu.caltech.cs2.interfaces.IQueue;
import org.junit.jupiter.api.*; import org.junit.jupiter.api.*;
...@@ -21,7 +22,7 @@ import static org.junit.jupiter.api.Assertions.*; ...@@ -21,7 +22,7 @@ import static org.junit.jupiter.api.Assertions.*;
@Tag("B") @Tag("B")
@TestMethodOrder(MethodOrderer.OrderAnnotation.class) @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 static String FIXED_QUEUE_SOURCE = "src/edu/caltech/cs2/datastructures/CircularArrayFixedSizeQueue.java";
private Constructor circFixedSizeQueueConstructor = Reflection.getConstructor(CircularArrayFixedSizeQueue.class, private Constructor circFixedSizeQueueConstructor = Reflection.getConstructor(CircularArrayFixedSizeQueue.class,
......
...@@ -4,11 +4,7 @@ import edu.caltech.cs2.helpers.Inspection; ...@@ -4,11 +4,7 @@ import edu.caltech.cs2.helpers.Inspection;
import edu.caltech.cs2.helpers.NodeChecker; import edu.caltech.cs2.helpers.NodeChecker;
import edu.caltech.cs2.helpers.Reflection; import edu.caltech.cs2.helpers.Reflection;
import edu.caltech.cs2.helpers.RuntimeInstrumentation; import edu.caltech.cs2.helpers.RuntimeInstrumentation;
import edu.caltech.cs2.interfaces.ICollection; import edu.caltech.cs2.interfaces.*;
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 org.junit.jupiter.api.*; import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.CsvSource;
...@@ -27,7 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; ...@@ -27,7 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertNull;
@Tag("C") @Tag("C")
@TestMethodOrder(MethodOrderer.OrderAnnotation.class) @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 static String LINKED_DEQUE_SOURCE = "src/edu/caltech/cs2/datastructures/LinkedDeque.java";
private Constructor linkedDequeConstructor = Reflection.getConstructor(LinkedDeque.class); private Constructor linkedDequeConstructor = Reflection.getConstructor(LinkedDeque.class);
...@@ -114,7 +110,7 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests { ...@@ -114,7 +110,7 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests {
} }
@Order(classSpecificTestLevel) @Order(classSpecificTestLevel)
@DisplayName("Check for linked node class") @DisplayName("Check that LinkedDeque uses a node class")
@Test @Test
public void testLinkedNode() { public void testLinkedNode() {
Class[] classes = LinkedDeque.class.getDeclaredClasses(); Class[] classes = LinkedDeque.class.getDeclaredClasses();
...@@ -283,6 +279,8 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests { ...@@ -283,6 +279,8 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests {
8); 8);
} }
// "LINKED-NESS" TESTS ------------------------------------------------
@Order(dequeTestLevel) @Order(dequeTestLevel)
@DisplayName("Cycle detection for addFront(...), addBack(...), removeFront(...), and removeBack(...)") @DisplayName("Cycle detection for addFront(...), addBack(...), removeFront(...), and removeBack(...)")
@ParameterizedTest(name = "Test cycles - {1} random numbers with seed = {0}") @ParameterizedTest(name = "Test cycles - {1} random numbers with seed = {0}")
...@@ -293,7 +291,7 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests { ...@@ -293,7 +291,7 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests {
IDeque<Object> impl = new LinkedDeque<>(); IDeque<Object> impl = new LinkedDeque<>();
// Test that first peek is null // Test that first peek is null
assertNull(impl.peekFront(), "empty peek should return 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++) { for (int i = 0; i < size; i++) {
int num = r.nextInt(); int num = r.nextInt();
if (num % 2 == 0) { if (num % 2 == 0) {
...@@ -312,7 +310,9 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests { ...@@ -312,7 +310,9 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests {
impl.removeBack(); impl.removeBack();
} }
} }
// After each operation, check whether cycles have formed
NodeChecker.cycleDetection(impl, true); NodeChecker.cycleDetection(impl, true);
// Sanity checks, though these aren't super necessary
assertEquals(reference.size(), impl.size(), "size()s are not equal"); assertEquals(reference.size(), impl.size(), "size()s are not equal");
assertEquals(reference.toString(), impl.toString(), "toStrings()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 { ...@@ -328,7 +328,7 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests {
IDeque<Object> impl = new LinkedDeque<>(); IDeque<Object> impl = new LinkedDeque<>();
// Test that first peek is null // Test that first peek is null
assertNull(impl.peekFront(), "empty peek should return 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++) { for (int i = 0; i < size; i++) {
int num = r.nextInt(); int num = r.nextInt();
if (num % 2 == 0) { if (num % 2 == 0) {
...@@ -347,6 +347,7 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests { ...@@ -347,6 +347,7 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests {
impl.removeBack(); impl.removeBack();
} }
} }
// Check that forwards and backwards iteration are sane
NodeChecker.checkReverse(impl); NodeChecker.checkReverse(impl);
assertEquals(reference.size(), impl.size(), "size()s are not equal"); assertEquals(reference.size(), impl.size(), "size()s are not equal");
assertEquals(reference.toString(), impl.toString(), "toStrings()s are not equal"); assertEquals(reference.toString(), impl.toString(), "toStrings()s are not equal");
......
package edu.caltech.cs2.datastructures; package edu.caltech.cs2.interfaces;
import edu.caltech.cs2.interfaces.ICollection; import edu.caltech.cs2.interfaces.ICollection;
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayName;
...@@ -17,7 +17,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; ...@@ -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.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
public interface CollectionTests { public interface ICollectionTests {
ICollection<Object> newCollection(); ICollection<Object> newCollection();
@Order(collectionTestLevel) @Order(collectionTestLevel)
...@@ -124,7 +124,7 @@ public interface CollectionTests { ...@@ -124,7 +124,7 @@ public interface CollectionTests {
// Shuffle order of nums and check that all are contained in the collection // Shuffle order of nums and check that all are contained in the collection
Collections.shuffle(nums); Collections.shuffle(nums);
for (int num : 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 // Test that values not in collection are not contained
......
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.MatcherAssert;
import org.hamcrest.collection.IsEmptyIterable; import org.hamcrest.collection.IsEmptyIterable;
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayName;
...@@ -20,7 +18,7 @@ import java.util.Random; ...@@ -20,7 +18,7 @@ import java.util.Random;
import static edu.caltech.cs2.project03.Project03TestOrdering.*; import static edu.caltech.cs2.project03.Project03TestOrdering.*;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
public interface DequeTests extends CollectionTests { public interface IDequeTests extends ICollectionTests {
IDeque<Object> newDeque(); IDeque<Object> newDeque();
@Order(dequeTestLevel) @Order(dequeTestLevel)
...@@ -42,7 +40,8 @@ public interface DequeTests extends CollectionTests { ...@@ -42,7 +40,8 @@ public interface DequeTests extends CollectionTests {
ref.addLast(value); ref.addLast(value);
MatcherAssert.assertThat(impl, IsIterableContainingInOrder.contains(ref.toArray())); 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())); MatcherAssert.assertThat(impl, IsIterableContainingInOrder.contains(ref.toArray()));
impl.removeBack(); impl.removeBack();
ref.removeLast(); ref.removeLast();
...@@ -291,8 +290,7 @@ public interface DequeTests extends CollectionTests { ...@@ -291,8 +290,7 @@ public interface DequeTests extends CollectionTests {
coll.add(num); coll.add(num);
} }
impl.addAll(coll); 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));
}
} }
} }
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.helpers.Reflection;
import edu.caltech.cs2.interfaces.IFixedSizeQueue;
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.CsvSource;
...@@ -15,7 +14,7 @@ import java.util.Random; ...@@ -15,7 +14,7 @@ import java.util.Random;
import static edu.caltech.cs2.project03.Project03TestOrdering.*; import static edu.caltech.cs2.project03.Project03TestOrdering.*;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
public interface FixedSizeQueueTests extends QueueTests { public interface IFixedSizeQueueTests extends IQueueTests {
IFixedSizeQueue<Object> newFixedSizeQueue(int capacity); IFixedSizeQueue<Object> newFixedSizeQueue(int capacity);
@Order(fixedSizeQueueLevel) @Order(fixedSizeQueueLevel)
......
package edu.caltech.cs2.datastructures; package edu.caltech.cs2.interfaces;
import edu.caltech.cs2.interfaces.IQueue; import edu.caltech.cs2.interfaces.IQueue;
import edu.caltech.cs2.interfaces.IStack; import edu.caltech.cs2.interfaces.IStack;
...@@ -14,7 +14,7 @@ import java.util.Random; ...@@ -14,7 +14,7 @@ import java.util.Random;
import static edu.caltech.cs2.project03.Project03TestOrdering.*; import static edu.caltech.cs2.project03.Project03TestOrdering.*;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
public interface QueueTests { public interface IQueueTests {
IQueue<Object> newQueue(); IQueue<Object> newQueue();
IQueue<Object> newQueue(int size); IQueue<Object> newQueue(int size);
......
package edu.caltech.cs2.datastructures; package edu.caltech.cs2.interfaces;
import edu.caltech.cs2.interfaces.IStack; import edu.caltech.cs2.interfaces.IStack;
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayName;
...@@ -13,7 +13,7 @@ import static edu.caltech.cs2.project03.Project03TestOrdering.*; ...@@ -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.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
public interface StackTests { public interface IStackTests {
IStack<Object> newStack(); IStack<Object> newStack();
@Order(stackTestLevel) @Order(stackTestLevel)
......
...@@ -5,6 +5,7 @@ public final class Project03TestOrdering { ...@@ -5,6 +5,7 @@ public final class Project03TestOrdering {
throw new InstantiationError("Class is only for storing constant variables"); 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 classSpecificTestLevel = 0;
public static final int collectionTestLevel = 1; public static final int collectionTestLevel = 1;
...@@ -14,8 +15,11 @@ public final class Project03TestOrdering { ...@@ -14,8 +15,11 @@ public final class Project03TestOrdering {
public static final int fixedSizeQueueLevel = 3; public static final int fixedSizeQueueLevel = 3;
public static final int toStringTestLevel = 4; // Tests related to the particular implementation
public static final int complexityTestLevel = 5; 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;
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment