Skip to content

Instantly share code, notes, and snippets.

@alwarren
Last active April 24, 2019 13:52
Show Gist options
  • Save alwarren/9cd84e3c402fbfcfabfaba154c4185b8 to your computer and use it in GitHub Desktop.
Save alwarren/9cd84e3c402fbfcfabfaba154c4185b8 to your computer and use it in GitHub Desktop.
Deque Specification Unit Tests
/**
* Description: A generic data type Deque.
*
* API Requirements:
*
* public class Deque<Item> implements Iterable<Item> {
* public Deque() // construct an empty deque
* public boolean isEmpty() // is the deque empty?
* public int size() // return the number of items on the deque
* public void addFirst(Item item) // add the item to the front
* public void addLast(Item item) // add the item to the end
* public Item removeFirst() // remove and return the item from the front
* public Item removeLast() // remove and return the item from the end
* public Iterator<Item> iterator() // return an iterator over items in order from front to end
* public static void main(String[] args) // unit testing (optional)
* }
*
* Corner cases. Throw the specified exception for the following corner cases:
*
* Throw a java.lang.IllegalArgumentException if the client calls either addFirst() or addLast() with a null argument.
* Throw a java.util.NoSuchElementException if the client calls either removeFirst() or removeLast when the deque is empty.
* Throw a java.util.NoSuchElementException if the client calls the next() method in the iterator when there are no more items to return.
* Throw a java.lang.UnsupportedOperationException if the client calls the remove() method in the iterator.
*
* Performance Requirements:
*
* Support each deque operation (including construction) in constant worst-case time.
* A deque containing n items must use at most 48n + 192 bytes of memory.
* A deque containing n items must use space proportional to the number of items currently in the deque.
* Iterator implementation must support each operation (including construction) in constant worst-case time.
*
* Deliverables. Deque.java.
*
* The class may not call library functions except those in StdIn, StdOut, StdRandom, java.lang,
* java.util.Iterator, and java.util.NoSuchElementException. In particular, do not use either
* java.util.LinkedList or java.util.ArrayList.
*
* Note on Deliverables. The classes StdIn, StdOut, and StdRandom will be provided.
*/
/**
* Description: Tests used to verify corner cases in Deque.
*
* Corner cases. Throw the specified exception for the following corner cases:
*
* Throw a java.lang.IllegalArgumentException if the client calls either addFirst() or addLast() with a null argument.
* Throw a java.util.NoSuchElementException if the client calls either removeFirst() or removeLast when the deque is empty.
* Throw a java.util.NoSuchElementException if the client calls the next() method in the iterator when there are no more items to return.
* Throw a java.lang.UnsupportedOperationException if the client calls the remove() method in the iterator.
*/
public class TestDequeCornerCases {
@Test(expected = IllegalArgumentException.class)
public void throw_IllegalArgumentException_on_addFirst_with_null_argument() {
new Deque<>().addFirst(null);
}
@Test(expected = IllegalArgumentException.class)
public void throw_IllegalArgumentException_on_addLast_with_null_argument() {
new Deque<>().addLast(null);
}
@Test(expected = NoSuchElementException.class)
public void throw_NoSuchElementException_on_removeFirst_when_deque_is_empty() {
new Deque<>().removeFirst();
}
@Test(expected = NoSuchElementException.class)
public void throw_NoSuchElementException_on_removelast_when_deque_is_empty() {
new Deque<>().removeLast();
}
@Test(expected = NoSuchElementException.class)
public void throw_NoSuchElementException_on_iterator_next_when_no_more_items_to_return() {
new Deque<>().iterator().next();
}
@Test(expected = UnsupportedOperationException.class)
public void throw_UnsupportedOperationException_on_calling_iterator_remove() {
new Deque<>().iterator().remove();
}
}
/**
* Description: Tests used to create an empty API for a generic data type Deque
* using test driven design (TDD).
*
* API Requirements:
*
* public class Deque<Item> implements Iterable<Item> {
* public Deque() // construct an empty deque
* public boolean isEmpty() // is the deque empty?
* public int size() // return the number of items on the deque
* public void addFirst(Item item) // add the item to the front
* public void addLast(Item item) // add the item to the end
* public Item removeFirst() // remove and return the item from the front
* public Item removeLast() // remove and return the item from the end
* public Iterator<Item> iterator() // return an iterator over items in order from front to end
* public static void main(String[] args) // unit testing (optional)
* }
*
* API Restrictions:
*
* Do not create any methods other than those defined in the API Requirements.
*
*/
public class TestDequeueApi {
@Test
// construct an empty deque
public void construct_an_empty_deque() {
Deque<Object> queue = new Deque<>();
}
@Test
// is the deque empty?
public void is_the_deque_empty() {
assertTrue(new Deque<>().isEmpty());
}
@Test
// return the number of items on the deque
public void return_the_number_of_items_on_the_deque() {
assertEquals(0, new Deque<>().size());
}
@Test
// add the item to the front
public void add_the_item_to_the_front() {
new Deque<>().addFirst(new Object());
}
@Test
// add the item to the end
public void add_the_item_to_the_end() {
new Deque<>().addLast(new Object());
}
// remove and return the item from the front
@Test
public void remove_and_return_the_item_from_the_front() {
try {
new Deque<>().removeFirst();
} catch (NoSuchElementException e) {
// no op - only for API test
}
}
// remove and return the item from the end
@Test
public void remove_and_return_the_item_from_the_end() {
try {
new Deque<>().removeLast();
} catch (NoSuchElementException e) {
// no op - only for API test
}
}
@Test
// return an iterator over items in order from front to end
public void return_an_iterator_over_items_in_order_from_front_to_end() {
new Deque<>().iterator();
}
@Test
// unit testing (optional)
public void unit_testing_optional() {
// Deque.main(null);
}
@Test
public void api_does_not_violate_restriction_on_required_methods() {
List<String> expected = expectedMethodNames();
List<String> actual = actualMethodNames();
assertEquals(expected, actual);
}
private static List<String> actualMethodNames() {
List<String> names = new ArrayList<>();
try {
Class<?> c = Class.forName("Deque", true, Deque.class.getClassLoader());
Method[] methods = c.getDeclaredMethods();
for (Method method : methods) {
names.add(method.getName());
}
names.remove("main");
Collections.sort(names);
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
return names;
}
private static List<String> expectedMethodNames() {
List<String> names = Arrays.asList(
"isEmpty",
"size",
"addFirst",
"addLast",
"removeFirst",
"removeLast",
"iterator"
);
Collections.sort(names);
return names;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment