Last active
November 25, 2019 16:22
-
-
Save IceSelkie/2c958c5e9b999ca417f1b530eee211c3 to your computer and use it in GitHub Desktop.
CSE 11 Gerald Programming Assignment 9 JUnit Tester
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package pa9; | |
import org.junit.Test; | |
import java.util.Iterator; | |
import java.util.LinkedList; | |
import java.util.List; | |
import java.util.Arrays; | |
import java.lang.reflect.*; | |
import static org.junit.Assert.*; | |
/** | |
* PA9Tester created by Stanley S. for PA9 with CustomAL for Gerald's CSE11 class. | |
* | |
* @author Stanley S. | |
* @version 1.0 | |
* @since Nov 23, 2019 | |
*/ | |
public class PA9TesterStanley | |
{ | |
@Test | |
public void testAdd() | |
{ | |
CustomAL list1 = new CustomAL(); | |
assertEquals(0, list1.size()); | |
assertEquals(10, capacity(list1)); | |
list1.add("1"); | |
assertEquals(1, list1.size()); | |
list1.add("2"); | |
assertEquals(2, list1.size()); | |
list1.add(0, "0"); | |
assertEquals(3, list1.size()); | |
assertArrayEquals(new Object[]{"0", "1", "2"}, list1.getData()); | |
list1.add(3, "3"); | |
assertSame("3", list1.get(3)); | |
// assert list1.add(18,"4") throws IndexOutOfBoundsException with message "Index out-of-bounds exception: index = 18; size = 4" | |
assertException(new IndexOutOfBoundsException("Index out-of-bounds exception: index = 18; size = 4"), "Expected IndexOutOfBounds error when adding element off the end of the list.", list1, "add", new Class[]{int.class, Object.class}, 18, "4"); | |
// assert list1.add(-1,"4") throws IndexOutOfBoundsException with message "Index out-of-bounds exception: index = -1; size = 4" | |
assertException(new IndexOutOfBoundsException("Index out-of-bounds exception: index = -1; size = 4"), "Expected IndexOutOfBounds error when adding element with a negative index.", list1, "add", new Class[]{int.class, Object.class}, -1, "4"); | |
} | |
@Test | |
public void testDynamicSize() | |
{ | |
CustomAL<Double> list = new CustomAL<Double>(3); | |
assertEquals(0, list.size()); | |
assertEquals(3, capacity(list)); | |
assertTrue(list.isEmpty()); | |
for (int i = 0; i < 3; i++) | |
list.add(7.2*i); | |
assertEquals(3, list.size()); | |
assertEquals(3, capacity(list)); | |
list.add(7.2); | |
assertEquals(4, list.size()); | |
assertEquals(6, capacity(list)); | |
for (int i = 0; i < 2; i++) | |
list.add(2.7*i); | |
assertEquals(6, list.size()); | |
assertEquals(6, capacity(list)); | |
list.add(7.2); | |
assertEquals(7, list.size()); | |
assertEquals(12, capacity(list)); | |
for (int i = 0; i < 100; i++) | |
list.add(2391.69211D*i); | |
assertEquals(107, list.size()); | |
assertEquals(192, capacity(list)); | |
for (int i = 0; i < 107; i++) { | |
list.remove(0); | |
assertEquals(106-i, list.size()); | |
assertEquals("Removing elements from the CustomAL should not cause its capacity "+ | |
"to shrink!", 192, capacity(list)); | |
} | |
} | |
@Test | |
public void testRemove() | |
{ | |
CustomAL<String> list = new CustomAL<>(); | |
assertEquals(0, list.size()); | |
assertEquals(10, capacity(list)); | |
for (int i = 1; i <= 20; i++) | |
list.add("Item #"+i); | |
assertEquals(20, list.size()); | |
assertEquals(20, capacity(list)); | |
for (int i = 0; i < 10; i++) | |
assertEquals("Item #"+(2*i+1), list.remove(i)); | |
assertEquals(10, list.size()); | |
assertEquals(20, capacity(list)); | |
assertEquals("Item #20", list.remove(9)); | |
assertNull(reflectMeAData(list)[9]); | |
assertEquals(9, list.size()); | |
assertEquals(20, capacity(list)); | |
assertTrue(list.remove("Item #2")); | |
assertFalse(list.remove("Item #2")); | |
assertFalse(list.remove(null)); | |
assertFalse(list.remove(new String())); | |
assertTrue(list.remove("Item #18")); | |
assertEquals(7, list.size()); | |
assertEquals(20, capacity(list)); | |
// assert list.remove(-1) throws IndexOutOfBoundsException with message "Index out-of-bounds exception: index = -1; size = 7" | |
assertException(new IndexOutOfBoundsException("Index out-of-bounds exception: index = -1; size = 7"), "Expected IndexOutOfBounds error when removing -1st element from list.", list, "remove", new Class[]{int.class}, -1); | |
// assert list.remove(7) throws IndexOutOfBoundsException with message "Index out-of-bounds exception: index = 7; size = 7" | |
assertException(new IndexOutOfBoundsException("Index out-of-bounds exception: index = 7; size = 7"), "Expected IndexOutOfBounds error when removing element one off the edge of the array.", list, "remove", new Class[]{int.class}, 7); | |
assertEquals(7, list.size()); | |
assertEquals(20, capacity(list)); | |
assertArrayEquals(new Object[]{"Item #4", "Item #6", "Item #8", "Item #10", "Item #12", | |
"Item #14", "Item #16"}, list.getData()); | |
assertArrayEquals(new Object[]{"Item #4", "Item #6", "Item #8", "Item #10", "Item #12", | |
"Item #14", "Item #16", null, null, null, null, null, null, null, null, null, | |
null, null, null, null}, reflectMeAData(list)); | |
for (int i = 0; i < 7; i++) | |
list.remove(0); | |
assertEquals(0, list.size()); | |
assertEquals(20, capacity(list)); | |
assertTrue(list.isEmpty()); | |
// assert list.remove(0) throws IndexOutOfBoundsException with message "Index out-of-bounds exception: index = 0; size = 0" | |
assertException(new IndexOutOfBoundsException("Index out-of-bounds exception: index = 0; size = 0"), "Expected IndexOutOfBounds error when removing 0th element from empty list.", list, "remove", new Class[]{int.class}, 0); | |
CustomAL<Obj> customal = new CustomAL<>(); | |
Obj o11 = new Obj(1, 1), | |
o12 = new Obj(1, 2), | |
o13 = new Obj(1, 3), | |
o21 = new Obj(2, 1), | |
o22 = new Obj(2, 2); | |
customal.add(o11); | |
customal.add(o12); | |
customal.add(o13); | |
customal.add(o21); | |
customal.add(o22); | |
customal.add(null); | |
customal.add(o12); | |
customal.add(null); | |
assertEquals(8, customal.size()); | |
assertEquals(10, capacity(customal)); | |
assertTrue(customal.remove(o13)); | |
assertSame(o12, customal.get(0)); | |
assertTrue(customal.remove(o13)); | |
assertSame(o13, customal.get(0)); | |
assertTrue(customal.remove(o21)); | |
assertSame(o22, customal.get(1)); | |
assertEquals(5, customal.size()); | |
assertEquals(10, capacity(customal)); | |
assertEquals(2, customal.indexOf(null)); | |
assertTrue(customal.remove(null)); | |
assertEquals(3, customal.indexOf(null)); | |
assertTrue(customal.remove(null)); | |
assertEquals(-1, customal.indexOf(null)); | |
assertFalse(customal.remove(null)); | |
assertEquals(3, customal.size()); | |
assertEquals(10, capacity(customal)); | |
assertTrue(customal.remove(o13)); | |
assertSame(o12, customal.get(1)); | |
assertTrue(customal.remove(o13)); | |
assertFalse(customal.contains(o12)); | |
assertFalse(customal.remove(o13)); | |
} | |
@Test | |
public void testConstructors() | |
{ | |
CustomAL list = new CustomAL(null); | |
assertEquals(0, list.size()); | |
assertArrayEquals(new Object[10], reflectMeAData(list)); | |
list = new CustomAL(); | |
assertEquals(0, list.size()); | |
assertArrayEquals(new Object[10], reflectMeAData(list)); | |
list = new CustomAL(1); | |
assertEquals(0, list.size()); | |
assertArrayEquals(new Object[1], reflectMeAData(list)); | |
list = new CustomAL(150000); | |
assertEquals(0, list.size()); | |
assertArrayEquals(new Object[150000], reflectMeAData(list)); | |
LinkedList ll = new LinkedList(); | |
ll.add("Something"); | |
list = new CustomAL(ll); | |
assertEquals(1, list.size()); | |
assertEquals(2, capacity(list)); | |
ll.add("Other"); | |
list = new CustomAL(ll); | |
assertEquals(2, list.size()); | |
assertEquals(4, capacity(list)); | |
for (int i = 0; i < 17; i++) | |
ll.add("more!"); | |
list = new CustomAL(ll); | |
assertEquals(19, list.size()); | |
assertEquals(38, capacity(list)); | |
} | |
@Test | |
public void testGetData() | |
{ | |
CustomAL<String> list = new CustomAL<>(2); | |
assertArrayEquals(new Object[0], list.getData()); | |
list.add("Data"); | |
assertArrayEquals(new Object[]{"Data"}, list.getData()); | |
list.add("More Data"); | |
assertArrayEquals(new Object[]{"Data", "More Data"}, list.getData()); | |
} | |
@Test | |
public void testGetSetIndexOfAndContains() | |
{ | |
CustomAL<String> list = new CustomAL<>(37); | |
for (int i = 0; i < 26; i++) | |
list.add(((Character)((char)('a'+i))).toString()); | |
assertEquals("a", list.get(0)); | |
assertEquals("z", list.get(25)); | |
assertEquals("s", list.get(18)); | |
list.set(0, "Start!"); | |
list.set(25, "End!"); | |
assertTrue(list.contains("g")); | |
assertFalse(list.contains("a")); | |
assertFalse(list.contains("z")); | |
assertTrue(list.contains("Start!")); | |
assertTrue(list.contains("End!")); | |
assertFalse(list.contains(null)); | |
assertEquals(6, list.indexOf("g")); | |
assertEquals(0, list.indexOf("Start!")); | |
assertEquals(25, list.indexOf("End!")); | |
assertEquals(-1, list.indexOf("Its not in there.")); | |
assertEquals(-1, list.indexOf(null)); | |
list.set(13, "b"); | |
assertEquals(1, list.indexOf("b")); | |
// assert list.set(-1,"") throws IndexOutOfBoundsException with message "Index out-of-bounds exception: index = -1; size = 26" | |
assertException(new IndexOutOfBoundsException("Index out-of-bounds exception: index = -1; size = 26"), list, "set", new Class[]{int.class, Object.class}, -1, ""); | |
// assert list.set(26,"") throws IndexOutOfBoundsException with message "Index out-of-bounds exception: index = 26; size = 26" | |
assertException(new IndexOutOfBoundsException("Index out-of-bounds exception: index = 26; size = 26"), list, "set", new Class[]{int.class, Object.class}, 26, ""); | |
// assert list.get(-1) throws IndexOutOfBoundsException with message "Index out-of-bounds exception: index = -1; size = 26" | |
assertException(new IndexOutOfBoundsException("Index out-of-bounds exception: index = -1; size = 26"), list, "get", new Class[]{int.class}, -1); | |
// assert list.get(26) throws IndexOutOfBoundsException with message "Index out-of-bounds exception: index = 26; size = 26" | |
assertException(new IndexOutOfBoundsException("Index out-of-bounds exception: index = 26; size = 26"), list, "get", new Class[]{int.class}, 26); | |
} | |
@Test | |
public void testEquals() | |
{ | |
CustomAL<String> l1 = new CustomAL<>(2); | |
CustomAL<String> l2 = new CustomAL<>(3); | |
CustomAL<Object> l3 = new CustomAL<>(5); | |
l1.add("A"); | |
l2.add("A"); | |
assertTrue(l1.equals(l2)); | |
assertTrue(l2.equals(l1)); | |
l2.add("B"); | |
assertFalse(l1.equals(l2)); | |
assertFalse(l2.equals(l1)); | |
l2.clear(); | |
l2.add("B"); | |
assertFalse(l1.equals(l2)); | |
assertFalse(l2.equals(l1)); | |
l3.add("A"); | |
assertTrue(l1.equals(l3)); | |
assertTrue(l3.equals(l1)); | |
l3.add('b'); | |
l1.add("b"); | |
assertFalse(l1.equals(l3)); | |
assertFalse(l3.equals(l1)); | |
l3.set(1, "b"); | |
assertTrue(l1.equals(l3)); | |
assertTrue(l3.equals(l1)); | |
} | |
@Test | |
public void testClear() | |
{ | |
CustomAL<Character> list = new CustomAL<>(37); | |
for (int i = 0; i < 26; i++) | |
list.add((char)('a'+i)); | |
assertEquals(26, list.size()); | |
assertEquals(37, capacity(list)); | |
Object[] originalData = reflectMeAData(list); | |
list.clear(); | |
assertEquals(0, list.size()); | |
assertEquals(37, capacity(list)); | |
assertSame("The internal array should not be changed on a .clear(), it should only be cleared.", originalData, reflectMeAData(list)); | |
assertArrayEquals(new Object[37], originalData); | |
} | |
@Test | |
public void testSublist() | |
{ | |
CustomAL<String> listOriginal = new CustomAL<>(); | |
listOriginal.add("0"); | |
listOriginal.add("1"); | |
listOriginal.add("2"); | |
listOriginal.add("3"); | |
listOriginal.add("4"); | |
listOriginal.add("5"); | |
listOriginal.add("6"); | |
listOriginal.add("7"); | |
assertArrayEquals(listOriginal.getData(), ((CustomAL)(listOriginal.subList(0, listOriginal.size()))).getData()); | |
assertArrayEquals(new Object[]{"3", "4", "5"}, ((CustomAL)(listOriginal.subList(3, 6))).getData()); | |
assertArrayEquals(new Object[]{"0"}, ((CustomAL)(listOriginal.subList(0, 1))).getData()); | |
assertArrayEquals(new Object[]{}, ((CustomAL)(listOriginal.subList(0, 0))).getData()); | |
assertArrayEquals(new Object[]{}, ((CustomAL)(listOriginal.subList(7, 7))).getData()); | |
assertArrayEquals(new Object[]{}, ((CustomAL)(listOriginal.subList(5, 3))).getData()); | |
assertArrayEquals(new Object[]{"7"}, ((CustomAL)(listOriginal.subList(7, 8))).getData()); | |
// assert listOriginal.subList(-1,2) throws IndexOutOfBoundsException with message "Index out-of-bounds exception: startIndex = -1; endIndex = 2; size = 8" | |
assertException(new IndexOutOfBoundsException("Index out-of-bounds exception: startIndex = -1; endIndex = 2; size = 8"), listOriginal, "subList", new Class[]{int.class, int.class}, -1, 2); | |
// assert listOriginal.subList(6,10) throws IndexOutOfBoundsException with message "Index out-of-bounds exception: startIndex = 6; endIndex = 10; size = 8" | |
assertException(new IndexOutOfBoundsException("Index out-of-bounds exception: startIndex = 6; endIndex = 10; size = 8"), listOriginal, "subList", new Class[]{int.class, int.class}, 6, 10); | |
CustomAL list2 = new CustomAL(17); | |
for (int i = 0; i < 32; i++) | |
list2.add(i+""); | |
assertEquals(32, list2.size()); | |
assertEquals(34, capacity(list2)); | |
CustomAL list3 = (CustomAL)list2.subList(1, 23); | |
assertEquals(22, list3.size()); | |
} | |
@Test | |
public void testConstructorAddEdgeCase() | |
{ | |
CustomAL list = new CustomAL(0); | |
Thread t = new Thread(() -> { | |
try { | |
list.add("test"); | |
} catch (IndexOutOfBoundsException e) { | |
fail("Index out of bounds error on adding item to a list of capacity 0."); | |
} | |
}); | |
t.start(); | |
try { Thread.sleep(100); } catch (InterruptedException ignored) {} | |
if (t.isAlive()) { | |
t.interrupt(); | |
fail("Add item to list of size 0 creates infinite loop."); | |
} | |
assertEquals(1, list.size()); | |
CustomAL list2 = new CustomAL(new LinkedList()); | |
assertEquals(0, list2.size()); | |
assertEquals(10, capacity(list2)); | |
list2 = new CustomAL(null); | |
assertEquals(0, list2.size()); | |
assertEquals(10, capacity(list2)); | |
} | |
/* **************** Helper Methods **************** */ | |
private int capacity(CustomAL list) | |
{ | |
try { return reflectMeAData(list).length; } catch (NullPointerException npe) { return -1; } | |
} | |
private double load(CustomAL list) | |
{ | |
return (double)list.size()/capacity(list); | |
} | |
class Obj | |
{ | |
int main; | |
int hidden; | |
Obj(int data, int hidden) | |
{ | |
this.main = data; | |
this.hidden = hidden; | |
} | |
public boolean equals(Object obj) | |
{ | |
if (obj instanceof Obj) return main == ((Obj)obj).main; | |
return false; | |
} | |
} | |
/* **************** There be reflection stuff below this line. **************** */ | |
/* **************** Not recommended to look at for the feint of heart. **************** */ | |
private Object[] reflectMeAData(CustomAL list) | |
{ | |
if (list == null) | |
return null; | |
try { | |
Field fieldData = CustomAL.class.getDeclaredField("data"); | |
fieldData.setAccessible(true); | |
return (Object[])fieldData.get(list); | |
} catch (Exception e) { | |
return null; | |
} | |
} | |
private <T extends Exception> void assertException(T e, Object o, String method, Class[] types, Object... args) | |
{ | |
assertException(e, "Excepted Exception of "+e.getClass()+" but none was thrown.", o, method, types, args); | |
} | |
private <T extends Exception> void assertException(T e, String message, Object o, String method, Class[] types, Object... args) | |
{ | |
try { | |
Method m = o.getClass().getDeclaredMethod(method, types); | |
try { | |
m.invoke(o, args); | |
fail(message); | |
} catch (InvocationTargetException wrappedException) { | |
Exception ex = (Exception)wrappedException.getTargetException(); | |
assertEquals(e.getMessage(), ex.getMessage()); | |
assertEquals(e.getClass().toString(), ex.getClass().toString()); | |
} | |
} catch (NoSuchMethodException | IllegalAccessException err) { | |
throw new RuntimeException("Reflect error. Cannot test method."); | |
} | |
} | |
@Test | |
public void testInstanceVariables() | |
{ | |
// Assert all created fields private | |
int count = 0; | |
List<Field> fields = Arrays.asList(CustomAL.class.getDeclaredFields()); | |
Iterator<Field> fieldIterator = fields.iterator(); | |
while (fieldIterator.hasNext()) { | |
Field field = fieldIterator.next(); | |
// Ignore compiler/hidden instance variables such as "this". | |
if (field.isSynthetic()) | |
fieldIterator.remove(); | |
else { | |
count++; | |
if ((field.getModifiers() & Modifier.PRIVATE) == 0 && (field.getModifiers() & (Modifier.STATIC | Modifier.FINAL)) == 0) | |
fail("All instance variables of CustomAL should be private. Found "+field.getName()+" that was not private."); | |
if (field.getType().toString().matches(".*?java\\.util\\..*List.*")) | |
fail("Not supposed to use any Java Language List implementations."); | |
} | |
} | |
if (count != 2) { | |
StringBuilder sb = new StringBuilder("CustomAL should have two instance variables, found ").append(count).append(" instead! (Instance variables found:"); | |
for (int i = 0; i < fields.size(); i++) | |
sb.append(fields.get(i).getName()).append(i != fields.size()-1 ? ", " : ""); | |
sb.append(")"); | |
fail(sb.toString()); | |
} | |
} | |
@Test | |
public void testDoNotModifyClass() | |
{ | |
assertEquals("ListADT interface should not be modified!", -1766347384, Arrays.deepHashCode(new Object[]{ListADT.class, ListADT.class.getDeclaredFields(), ListADT.class.getDeclaredAnnotations(), ListADT.class.getDeclaredConstructors(), ListADT.class.getDeclaredMethods()})); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment