Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • sarafa/p2
  • mertht/p2
  • cse332-19au/p2
  • sandchow/p2
  • hanzhang/p2
  • cse332-19sp/p2
  • cse332-20sp/p2
  • cse332-20su-tasks/p2
  • cse332-20su/p2
  • cse332-21su/p2
  • cse332-21wi/p2
  • cse332-21sp/p2
  • cse332-20au/p2
13 results
Show changes
Commits on Source (5)
Showing
with 440 additions and 817 deletions
File added
File added
package cse332.datastructures.containers; package cse332.datastructures.containers;
import java.util.Objects;
/** /**
* Simple class to hold a piece of data and its value. * Simple class to hold a piece of data and its value.
* *
...@@ -40,4 +42,18 @@ public class Item<K, V> { ...@@ -40,4 +42,18 @@ public class Item<K, V> {
public String toString() { public String toString() {
return this.key + "=" + this.value + ""; return this.key + "=" + this.value + "";
} }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Item<?, ?> item = (Item<?, ?>) o;
return Objects.equals(key, item.key) &&
Objects.equals(value, item.value);
}
@Override
public int hashCode() {
return Objects.hash(key, value);
}
} }
...@@ -13,7 +13,7 @@ import datastructures.worklists.ArrayStack; ...@@ -13,7 +13,7 @@ import datastructures.worklists.ArrayStack;
* BinarySearchTree implements the ComparableDictionary interface using a binary * BinarySearchTree implements the ComparableDictionary interface using a binary
* search tree. Notice that the key type must be Comparable. * search tree. Notice that the key type must be Comparable.
*/ */
public class BinarySearchTree<K extends Comparable<K>, V> public class BinarySearchTree<K extends Comparable<? super K>, V>
extends ComparableDictionary<K, V> { extends ComparableDictionary<K, V> {
// The root of the BST. Root is null if and only if the tree is empty. // The root of the BST. Root is null if and only if the tree is empty.
protected BSTNode root; protected BSTNode root;
......
...@@ -10,6 +10,6 @@ package cse332.interfaces.misc; ...@@ -10,6 +10,6 @@ package cse332.interfaces.misc;
* *
* @author Adam Blank * @author Adam Blank
*/ */
public abstract class ComparableDictionary<K extends Comparable<K>, V> public abstract class ComparableDictionary<K extends Comparable<? super K>, V>
extends DeletelessDictionary<K, V> { extends DeletelessDictionary<K, V> {
} }
...@@ -28,6 +28,6 @@ import cse332.datastructures.trees.BinarySearchTree; ...@@ -28,6 +28,6 @@ import cse332.datastructures.trees.BinarySearchTree;
* 6. Do NOT override the toString method. It is used for grading. * 6. Do NOT override the toString method. It is used for grading.
*/ */
public class AVLTree<K extends Comparable<K>, V> extends BinarySearchTree<K, V> { public class AVLTree<K extends Comparable<? super K>, V> extends BinarySearchTree<K, V> {
// TODO: Implement me! // TODO: Implement me!
} }
package tests.gitlab.ckpt1; package tests.gitlab.ckpt1;
import datastructures.worklists.CircularArrayFIFOQueue; import datastructures.worklists.CircularArrayFIFOQueue;
import tests.TestsUtility; import org.junit.Test;
public class CircularArrayComparatorTests extends TestsUtility { import static org.junit.Assert.*;
public static void main(String[] args) {
new CircularArrayComparatorTests().run();
}
@Override
protected void run() {
SHOW_TESTS = true;
PRINT_TESTERR = true;
DEBUG = true;
test("test_empty_empty"); public class CircularArrayComparatorTests {
test("test_ab_ab");
test("test_ab_abc"); private CircularArrayFIFOQueue<String> init() {
test("test_abc_ab");
test("test_ac_abc");
test("test_a_aa");
test("test_equality_consistent_with_compare");
test("test_compare_transitive");
test("test_equals_doesnt_modify");
finish();
}
protected static CircularArrayFIFOQueue<String> init() {
return new CircularArrayFIFOQueue<String>(10); return new CircularArrayFIFOQueue<String>(10);
} }
private static int result(int a, int b) { private boolean result(int a, int b) {
return Integer.signum(a) == Integer.signum(b) ? 1 : 0; return Integer.signum(a) == Integer.signum(b);
} }
public static int test_empty_empty() { @Test(timeout = 3000)
public void test_empty_empty() {
CircularArrayFIFOQueue<String> l1 = init(); CircularArrayFIFOQueue<String> l1 = init();
CircularArrayFIFOQueue<String> l2 = init(); CircularArrayFIFOQueue<String> l2 = init();
return result(l1.compareTo(l2), "".compareTo("")); assertTrue(result(l1.compareTo(l2), "".compareTo("")));
} }
public static int test_ab_ab() { @Test(timeout = 3000)
public void test_ab_ab() {
CircularArrayFIFOQueue<String> l1 = init(); CircularArrayFIFOQueue<String> l1 = init();
CircularArrayFIFOQueue<String> l2 = init(); CircularArrayFIFOQueue<String> l2 = init();
l1.add("a"); l1.add("a");
l1.add("b"); l1.add("b");
l2.add("a"); l2.add("a");
l2.add("b"); l2.add("b");
return result(l1.compareTo(l2), "ab".compareTo("ab")); assertTrue(result(l1.compareTo(l2), "ab".compareTo("ab")));
} }
public static int test_ab_abc() {
@Test(timeout = 3000)
public void test_ab_abc() {
CircularArrayFIFOQueue<String> l1 = init(); CircularArrayFIFOQueue<String> l1 = init();
CircularArrayFIFOQueue<String> l2 = init(); CircularArrayFIFOQueue<String> l2 = init();
l1.add("a"); l1.add("a");
...@@ -58,10 +42,11 @@ public class CircularArrayComparatorTests extends TestsUtility { ...@@ -58,10 +42,11 @@ public class CircularArrayComparatorTests extends TestsUtility {
l2.add("a"); l2.add("a");
l2.add("b"); l2.add("b");
l2.add("c"); l2.add("c");
return result(l1.compareTo(l2), "ab".compareTo("abc")); assertTrue(result(l1.compareTo(l2), "ab".compareTo("abc")));
} }
public static int test_abc_ab() { @Test(timeout = 3000)
public void test_abc_ab() {
CircularArrayFIFOQueue<String> l1 = init(); CircularArrayFIFOQueue<String> l1 = init();
CircularArrayFIFOQueue<String> l2 = init(); CircularArrayFIFOQueue<String> l2 = init();
l1.add("a"); l1.add("a");
...@@ -69,9 +54,11 @@ public class CircularArrayComparatorTests extends TestsUtility { ...@@ -69,9 +54,11 @@ public class CircularArrayComparatorTests extends TestsUtility {
l1.add("c"); l1.add("c");
l2.add("a"); l2.add("a");
l2.add("b"); l2.add("b");
return result(l1.compareTo(l2), "abc".compareTo("ab")); assertTrue(result(l1.compareTo(l2), "abc".compareTo("ab")));
} }
public static int test_ac_abc() {
@Test(timeout = 3000)
public void test_ac_abc() {
CircularArrayFIFOQueue<String> l1 = init(); CircularArrayFIFOQueue<String> l1 = init();
CircularArrayFIFOQueue<String> l2 = init(); CircularArrayFIFOQueue<String> l2 = init();
l1.add("a"); l1.add("a");
...@@ -79,44 +66,50 @@ public class CircularArrayComparatorTests extends TestsUtility { ...@@ -79,44 +66,50 @@ public class CircularArrayComparatorTests extends TestsUtility {
l2.add("a"); l2.add("a");
l2.add("b"); l2.add("b");
l2.add("c"); l2.add("c");
return result(l1.compareTo(l2), "ac".compareTo("abc")); assertTrue(result(l1.compareTo(l2), "ac".compareTo("abc")));
} }
public static int test_a_aa() {
@Test(timeout = 3000)
public void test_a_aa() {
CircularArrayFIFOQueue<String> l1 = init(); CircularArrayFIFOQueue<String> l1 = init();
CircularArrayFIFOQueue<String> l2 = init(); CircularArrayFIFOQueue<String> l2 = init();
l1.add("a"); l1.add("a");
l2.add("a"); l2.add("a");
l2.add("a"); l2.add("a");
return result(l1.compareTo(l2), "a".compareTo("aa")); assertTrue(result(l1.compareTo(l2), "a".compareTo("aa")));
} }
public static int test_compare_transitive() { @Test(timeout = 3000)
public void test_compare_transitive() {
CircularArrayFIFOQueue<String> l1 = init(); CircularArrayFIFOQueue<String> l1 = init();
CircularArrayFIFOQueue<String> l2 = init(); CircularArrayFIFOQueue<String> l2 = init();
CircularArrayFIFOQueue<String> l3 = init(); CircularArrayFIFOQueue<String> l3 = init();
l1.add("abc"); l1.add("abc");
l2.add("def"); l2.add("def");
l3.add("efg"); l3.add("efg");
return l1.compareTo(l2) < 0 && l2.compareTo(l3) < 0 && l1.compareTo(l3) < 0 ? 1 : 0; assertTrue(l1.compareTo(l2) < 0 && l2.compareTo(l3) < 0 && l1.compareTo(l3) < 0) ;
} }
public static int test_equality_consistent_with_compare() { @Test(timeout = 3000)
public void test_equality_consistent_with_compare() {
CircularArrayFIFOQueue<String> l1 = init(); CircularArrayFIFOQueue<String> l1 = init();
CircularArrayFIFOQueue<String> l2 = init(); CircularArrayFIFOQueue<String> l2 = init();
l1.add("a"); l1.add("a");
l1.add("b"); l1.add("b");
l2.add("a"); l2.add("a");
l2.add("b"); l2.add("b");
return l1.equals(l2) && l1.compareTo(l2) == 0 ? 1 : 0; assertEquals(l1, l2);
assertEquals(l1.compareTo(l2), 0);
} }
public static int test_equals_doesnt_modify() { @Test(timeout = 3000)
public void test_equals_doesnt_modify() {
CircularArrayFIFOQueue<String> l1 = init(); CircularArrayFIFOQueue<String> l1 = init();
CircularArrayFIFOQueue<String> l2 = init(); CircularArrayFIFOQueue<String> l2 = init();
l1.add("a"); l1.add("a");
l2.add("a"); l2.add("a");
l1.equals(l2); l1.equals(l2);
return l1.size() == 1 ? 1 : 0; assertEquals(l1.size(), 1);
} }
} }
package tests.gitlab.ckpt1; package tests.gitlab.ckpt1;
import tests.GradingUtility; import org.junit.runner.RunWith;
import org.junit.runners.Suite;
public class Ckpt1Tests extends GradingUtility { @RunWith(Suite.class)
public static void main(String[] args) {
new Ckpt1Tests();
}
protected Class<?>[] getTests() { @Suite.SuiteClasses({
return new Class<?>[] { NGramToNextChoicesMapTests.class,
NGramToNextChoicesMapTests.class, MoveToFrontListTests.class,
MoveToFrontListTests.class, CircularArrayComparatorTests.class
CircularArrayComparatorTests.class })
};
} public class Ckpt1Tests {
}
}
\ No newline at end of file
...@@ -4,77 +4,63 @@ import java.util.Arrays; ...@@ -4,77 +4,63 @@ import java.util.Arrays;
import cse332.datastructures.containers.Item; import cse332.datastructures.containers.Item;
import datastructures.dictionaries.MoveToFrontList; import datastructures.dictionaries.MoveToFrontList;
import tests.TestsUtility; import org.junit.Test;
import static org.junit.Assert.*;
public class MoveToFrontListTests extends TestsUtility { public class MoveToFrontListTests {
public static void main(String[] args) {
new MoveToFrontListTests().run();
}
@Override @SuppressWarnings("unchecked")
protected void run() { @Test(timeout = 3000)
SHOW_TESTS = true; public void checkStructure() {
PRINT_TESTERR = true; MoveToFrontList<Integer, Integer> list = new MoveToFrontList<Integer, Integer>();
DEBUG = true;
test("testHugeMTFList"); int[] arr = {6, 5, 10, 14, 10, 31, 10, 13, 10, 10, 12, 10, 14, 10, 10, 11, 10, 14, 9, 8, 3, 2, 1, 0, 7, 4};
test("checkStructure"); for(int i = 0; i < arr.length; i++) {
Integer oldValue = list.find(arr[i]);
finish(); if (oldValue == null) {
} list.insert(arr[i], 1);
} else {
@SuppressWarnings("unchecked") list.insert(arr[i], 1 + oldValue);
public static int checkStructure() { }
MoveToFrontList<Integer, Integer> list = new MoveToFrontList<Integer, Integer>(); }
// Convert iterator to string
int[] arr = {6, 5, 10, 14, 10, 31, 10, 13, 10, 10, 12, 10, 14, 10, 10, 11, 10, 14, 9, 8, 3, 2, 1, 0, 7, 4}; Item<Integer, Integer>[] dcs = (Item<Integer, Integer>[])new Item[list.size()];
for(int i = 0; i < arr.length; i++) { int i = 0;
Integer oldValue = list.find(arr[i]); for (Item<Integer, Integer> item : list) {
if (oldValue == null) { dcs[i++] = item;
list.insert(arr[i], 1);
} else {
list.insert(arr[i], 1 + oldValue);
} }
}
// Convert iterator to string
Item<Integer, Integer>[] dcs = (Item<Integer, Integer>[])new Item[list.size()];
int i = 0;
for (Item<Integer, Integer> item : list) {
dcs[i++] = item;
}
// Compare strings to make sure we get the right one // Compare strings to make sure we get the right one
// Can use list.toString as well, but I'm not sure if students may modify that // Can use list.toString as well, but I'm not sure if students may modify that
String mtf_correct = "[4=1, 7=1, 0=1, 1=1, 2=1, 3=1, 8=1, 9=1, 14=3, 10=9, 11=1, 12=1, 13=1, 31=1, 5=1, 6=1]"; String mtf_correct = "[4=1, 7=1, 0=1, 1=1, 2=1, 3=1, 8=1, 9=1, 14=3, 10=9, 11=1, 12=1, 13=1, 31=1, 5=1, 6=1]";
String mtf_test = Arrays.toString(dcs); String mtf_test = Arrays.toString(dcs);
return mtf_correct.equals(mtf_test) ? 1 : 0; assertEquals(mtf_correct, mtf_test);
} }
public static int testHugeMTFList() { @Test(timeout = 3000)
MoveToFrontList<String, Integer> list = new MoveToFrontList<>(); public void testHugeMTFList() {
MoveToFrontList<String, Integer> list = new MoveToFrontList<>();
int n = 1000; int n = 1000;
// Add them // Add them
for (int i = 0; i < 5 * n; i++) { for (int i = 0; i < 5 * n; i++) {
int k = (i % n) * 37 % n; int k = (i % n) * 37 % n;
String str = String.format("%05d", k); String str = String.format("%05d", k);
for (int j = 0; j < k + 1; j ++) for (int j = 0; j < k + 1; j ++)
list.insert(str, list.find(str) == null ? 1 : list.find(str) + 1); list.insert(str, list.find(str) == null ? 1 : list.find(str) + 1);
} }
// Delete them all // Delete them all
boolean passed = true; int totalCount = 0;
int totalCount = 0; for (Item<String, Integer> dc : list) {
for (Item<String, Integer> dc : list) { assertEquals((Integer.parseInt(dc.key) + 1) * 5, dc.value.intValue());
passed &= (Integer.parseInt(dc.key) + 1) * 5 == dc.value; totalCount += dc.value;
totalCount += dc.value; }
}
// Check sizes
passed &= totalCount == (n * (n + 1)) / 2 * 5;
passed &= list.size() == n;
passed &= list.find("00851") == 4260;
return passed ? 1 : 0; // Check sizes
} assertEquals(totalCount, (n * (n + 1)) / 2 * 5);
assertEquals(list.size(), n);
assertNotNull(list.find("00851"));
assertEquals(list.find("00851").intValue(), 4260);
}
} }
package tests.gitlab.ckpt1; package tests.gitlab.ckpt1;
import java.util.Arrays;
import java.util.Comparator;
import java.util.TreeMap;
import java.util.Map;
import java.util.function.Supplier;
import cse332.datastructures.containers.Item; import cse332.datastructures.containers.Item;
import cse332.interfaces.misc.Dictionary;
import cse332.types.AlphabeticString;
import cse332.types.NGram;
import cse332.datastructures.trees.BinarySearchTree; import cse332.datastructures.trees.BinarySearchTree;
import cse332.types.NGram;
import org.junit.Test;
import p2.wordsuggestor.NGramToNextChoicesMap; import p2.wordsuggestor.NGramToNextChoicesMap;
import tests.TestsUtility;
public class NGramToNextChoicesMapTests extends TestsUtility { import java.util.Arrays;
private static Supplier<Dictionary<NGram, Dictionary<AlphabeticString, Integer>>> newOuter = import java.util.Comparator;
() -> new BinarySearchTree(); import java.util.Map;
import java.util.TreeMap;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
private static Supplier<Dictionary<AlphabeticString, Integer>> newInner = public class NGramToNextChoicesMapTests {
() -> new BinarySearchTree(); private NGramToNextChoicesMap init() {
return new NGramToNextChoicesMap(BinarySearchTree::new, BinarySearchTree::new);
public static void main(String[] args) {
new NGramToNextChoicesMapTests().run();
}
@Override
protected void run() {
SHOW_TESTS = true;
PRINT_TESTERR = true;
DEBUG = true;
test("testOneWordPerNGram");
test("testMultipleWordsPerNGram");
test("testGetNonexistentNGram");
test("testRepeatedWordsPerNGram");
finish();
}
protected static NGramToNextChoicesMap init() {
return new NGramToNextChoicesMap(newOuter, newInner);
} }
public static int testOneWordPerNGram() { @Test(timeout = 3000)
public void testOneWordPerNGram() {
NGramToNextChoicesMap map = init(); NGramToNextChoicesMap map = init();
NGram[] ngrams = new NGram[]{ NGram[] ngrams = new NGram[]{
new NGram(new String[]{"foo", "bar", "baz"}), new NGram(new String[]{"foo", "bar", "baz"}),
new NGram(new String[]{"fee", "fi", "fo"}), new NGram(new String[]{"fee", "fi", "fo"}),
new NGram(new String[]{"a", "s", "d"}) new NGram(new String[]{"a", "s", "d"})
}; };
String[] words = new String[]{"bop", "fum", "f"}; String[] words = new String[]{"bop", "fum", "f"};
for (int i = 0; i < ngrams.length; i++) { for (int i = 0; i < ngrams.length; i++) {
map.seenWordAfterNGram(ngrams[i], words[i]); map.seenWordAfterNGram(ngrams[i], words[i]);
} }
for (int i = 0; i < ngrams.length; i++) { for (int i = 0; i < ngrams.length; i++) {
Item<String, Integer>[] items = map.getCountsAfter(ngrams[i]); Item<String, Integer>[] items = map.getCountsAfter(ngrams[i]);
if (items.length != 1) return 0; assertEquals(1, items.length);
Item<String, Integer> item = items[0]; Item<String, Integer> item = items[0];
if (!item.key.equals(words[i])) return 0; assertEquals(words[i], item.key);
if (!item.value.equals(1)) return 0; assertEquals(1, item.value.intValue());
} }
return 1;
} }
public static int testMultipleWordsPerNGram() { @Test(timeout = 3000)
public void testMultipleWordsPerNGram() {
NGramToNextChoicesMap map = init(); NGramToNextChoicesMap map = init();
NGram[] ngrams = new NGram[]{ NGram[] ngrams = new NGram[]{
new NGram(new String[]{"foo", "bar", "baz"}), new NGram(new String[]{"foo", "bar", "baz"}),
...@@ -74,61 +52,56 @@ public class NGramToNextChoicesMapTests extends TestsUtility { ...@@ -74,61 +52,56 @@ public class NGramToNextChoicesMapTests extends TestsUtility {
new NGram(new String[]{"3", "2", "2"}), new NGram(new String[]{"3", "2", "2"}),
new NGram(new String[]{"a", "s", "d"}) new NGram(new String[]{"a", "s", "d"})
}; };
String[][] words = new String[][] { String[][] words = new String[][] {
new String[]{"bip", "bop", "bzp"}, new String[]{"bip", "bop", "bzp"},
new String[]{"fum", "giants"}, new String[]{"fum", "giants"},
new String[]{"ago", "seven", "years"}, new String[]{"ago", "seven", "years"},
new String[]{"new", "thrown", "uuu", "zzz"}, new String[]{"new", "thrown", "uuu", "zzz"},
new String[]{"do", "for", "while"} new String[]{"do", "for", "while"}
}; };
for (int i = 0; i < ngrams.length; i++) { for (int i = 0; i < ngrams.length; i++) {
for (int j = 0; j < words[i].length; j++) { for (int j = 0; j < words[i].length; j++) {
map.seenWordAfterNGram(ngrams[i], words[i][j]); map.seenWordAfterNGram(ngrams[i], words[i][j]);
} }
} }
for (int i = 0; i < ngrams.length; i++) { for (int i = 0; i < ngrams.length; i++) {
Item<String, Integer>[] items = map.getCountsAfter(ngrams[i]); Item<String, Integer>[] items = map.getCountsAfter(ngrams[i]);
String[] answer = words[i]; String[] answer = words[i];
if (items.length != answer.length) return 0; assertEquals(answer.length, items.length);
String[] itemsWithoutCounts = new String[items.length]; String[] itemsWithoutCounts = new String[items.length];
for (int j = 0; j < answer.length; j++) { for (int j = 0; j < answer.length; j++) {
if (!items[j].value.equals(1)) return 0; assertEquals(1, items[j].value.intValue());
itemsWithoutCounts[j] = items[j].key; itemsWithoutCounts[j] = items[j].key;
} }
Arrays.sort(itemsWithoutCounts); Arrays.sort(itemsWithoutCounts);
for (int j = 0; j < answer.length; j++) { assertArrayEquals(answer, itemsWithoutCounts);
if (!itemsWithoutCounts[j].equals(answer[j])) return 0;
}
} }
return 1;
} }
public static int testGetNonexistentNGram() { @Test(timeout = 3000)
public void testGetNonexistentNGram() {
NGramToNextChoicesMap map = init(); NGramToNextChoicesMap map = init();
NGram[] ngrams = new NGram[]{ NGram[] ngrams = new NGram[]{
new NGram(new String[]{"foo", "bar", "baz"}), new NGram(new String[]{"foo", "bar", "baz"}),
new NGram(new String[]{"fee", "fi", "fo"}), new NGram(new String[]{"fee", "fi", "fo"}),
new NGram(new String[]{"a", "s", "d"}) new NGram(new String[]{"a", "s", "d"})
}; };
String[] words = new String[]{"bop", "fum", "f"}; String[] words = new String[]{"bop", "fum", "f"};
for (int i = 0; i < ngrams.length; i++) { for (int i = 0; i < ngrams.length; i++) {
map.seenWordAfterNGram(ngrams[i], words[i]); map.seenWordAfterNGram(ngrams[i], words[i]);
} }
Item<String, Integer>[] items = map.getCountsAfter(new NGram(new String[] { "yo" })); Item<String, Integer>[] items = map.getCountsAfter(new NGram(new String[] { "yo" }));
if (items == null || items.length != 0) { assertNotNull(items);
return 0; assertEquals(0, items.length);
}
return 1;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static int testRepeatedWordsPerNGram() { @Test(timeout = 3000)
public void testRepeatedWordsPerNGram() {
NGramToNextChoicesMap map = init(); NGramToNextChoicesMap map = init();
// Creates Ngrams to test for with N = 3 // Creates Ngrams to test for with N = 3
NGram[] ngrams = new NGram[]{ NGram[] ngrams = new NGram[]{
...@@ -140,73 +113,60 @@ public class NGramToNextChoicesMapTests extends TestsUtility { ...@@ -140,73 +113,60 @@ public class NGramToNextChoicesMapTests extends TestsUtility {
}; };
// Array of words seen after each Ngram with correlating index from above // Array of words seen after each Ngram with correlating index from above
String[][] words = new String[][] { String[][] words = new String[][] {
new String[]{"bop", "bip", "boop", "bop", "bop"}, new String[]{"bop", "bip", "boop", "bop", "bop"},
new String[]{"fum", "giants", "giants"}, new String[]{"fum", "giants", "giants"},
new String[]{"seven", "years", "years", "ago", "ago"}, new String[]{"seven", "years", "years", "ago", "ago"},
new String[]{"throw", "throw", "throw", "throw", "throw"}, new String[]{"throw", "throw", "throw", "throw", "throw"},
new String[]{"for", "while", "do", "do", "while", "for"} new String[]{"for", "while", "do", "do", "while", "for"}
}; };
// yes this is awful, but i can't think of a better way to do it atm // yes this is awful, but i can't think of a better way to do it atm
// Creates answers for getCountsAfter - Word seen after and count // Creates answers for getCountsAfter - Word seen after and count
// corrlates with words and ngrams above // corrlates with words and ngrams above
// Note that words after are in sorted order, not in order of array in words // Note that words after are in sorted order, not in order of array in words
Map<NGram, Item<String, Integer>[]> answers = new TreeMap<>(); Map<NGram, Item<String, Integer>[]> answers = new TreeMap<>();
answers.put(ngrams[0], (Item<String, Integer>[]) new Item[3]); answers.put(ngrams[0], (Item<String, Integer>[]) new Item[]{
answers.get(ngrams[0])[0] = new Item<String, Integer>("bip", 1); new Item<>("bip", 1),
answers.get(ngrams[0])[1] = new Item<String, Integer>("boop", 1); new Item<>("boop", 1),
answers.get(ngrams[0])[2] = new Item<String, Integer>("bop", 3); new Item<>("bop", 3)
answers.put(ngrams[1], (Item<String, Integer>[]) new Item[2]); });
answers.get(ngrams[1])[0] = new Item<String, Integer>("fum", 1);
answers.get(ngrams[1])[1] = new Item<String, Integer>("giants", 2); answers.put(ngrams[1], (Item<String, Integer>[]) new Item[]{
answers.put(ngrams[2], (Item<String, Integer>[]) new Item[3]); new Item<>("fum", 1),
answers.get(ngrams[2])[0] = new Item<String, Integer>("ago", 2); new Item<>("giants", 2)
answers.get(ngrams[2])[1] = new Item<String, Integer>("seven", 1); });
answers.get(ngrams[2])[2] = new Item<String, Integer>("years", 2);
answers.put(ngrams[3], (Item<String, Integer>[]) new Item[1]); answers.put(ngrams[2], (Item<String, Integer>[]) new Item[]{
answers.get(ngrams[3])[0] = new Item<String, Integer>("throw", 5); new Item<>("ago", 2),
answers.put(ngrams[4], (Item<String, Integer>[]) new Item[3]); new Item<>("seven", 1),
answers.get(ngrams[4])[0] = new Item<String, Integer>("do", 2); new Item<>("years", 2)
answers.get(ngrams[4])[1] = new Item<String, Integer>("for", 2); });
answers.get(ngrams[4])[2] = new Item<String, Integer>("while", 2);
answers.put(ngrams[3], (Item<String, Integer>[]) new Item[]{
new Item<>("throw", 5)
});
answers.put(ngrams[4], (Item<String, Integer>[]) new Item[]{
new Item<>("do", 2),
new Item<>("for", 2),
new Item<>("while", 2)
});
// Adds nGrams and words after to student's NGramToNextChoicesMap // Adds nGrams and words after to student's NGramToNextChoicesMap
for (int i = 0; i < ngrams.length; i++) { for (int i = 0; i < ngrams.length; i++) {
for (int j = 0; j < words[i].length; j++) { for (int j = 0; j < words[i].length; j++) {
map.seenWordAfterNGram(ngrams[i], words[i][j]); map.seenWordAfterNGram(ngrams[i], words[i][j]);
} }
} }
// checks to see if getCountsAfter returns correctly // checks to see if getCountsAfter returns correctly
for (int i = 0; i < ngrams.length; i++) { for (int i = 0; i < ngrams.length; i++) {
NGram ngram = ngrams[i]; NGram ngram = ngrams[i];
Item<String, Integer>[] results = map.getCountsAfter(ngram); Item<String, Integer>[] results = map.getCountsAfter(ngram);
Arrays.sort(results, new Comparator<Object>() { Arrays.sort(results, Comparator.comparing(r -> r.key));
@Override
public int compare(Object o1, Object o2) {
Item<String, Integer> r1 = (Item<String, Integer>)o1;
Item<String, Integer> r2 = (Item<String, Integer>)o2;
return r1.key.compareTo(r2.key);
}
});
Item<String, Integer>[] expected = answers.get(ngram); Item<String, Integer>[] expected = answers.get(ngram);
// checks for correct number of unique words after // checks for correct number of unique words after
if (results.length != expected.length) return 0; assertArrayEquals(expected, results);
for (int j = 0; j < expected.length; j++) {
// checks if correct word after via sorted words
if (!expected[j].key.equals(results[j].key)) {
return 0;
}
// checks if correct count for given word after
if (!expected[j].value.equals(results[j].value)) {
return 0;
}
}
} }
return 1;
} }
} }
...@@ -4,31 +4,19 @@ import cse332.datastructures.containers.Item; ...@@ -4,31 +4,19 @@ import cse332.datastructures.containers.Item;
import cse332.datastructures.trees.BinarySearchTree.BSTNode; import cse332.datastructures.trees.BinarySearchTree.BSTNode;
import cse332.interfaces.misc.Dictionary; import cse332.interfaces.misc.Dictionary;
import datastructures.dictionaries.AVLTree; import datastructures.dictionaries.AVLTree;
import tests.TestsUtility; import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class AVLTreeTests extends TestsUtility { import org.junit.Test;
import static org.junit.Assert.*;
public static void main(String[] args) {
new AVLTreeTests().run();
}
@Override
protected void run() {
SHOW_TESTS = true;
DEBUG = true;
test("testTreeWith5Items");
test("testHugeTree");
test("checkStructure");
finish();
}
protected static AVLTree<String, Integer> init() { public class AVLTreeTests {
AVLTree<String, Integer> tree = new AVLTree<>();
return tree; private AVLTree<String, Integer> init() {
return new AVLTree<>();
} }
private static <E extends Comparable<E>> void incCount(Dictionary<E, Integer> tree, E key) { private <E extends Comparable<E>> void incCount(Dictionary<E, Integer> tree, E key) {
Integer value = tree.find(key); Integer value = tree.find(key);
if (value == null) { if (value == null) {
tree.insert(key, 1); tree.insert(key, 1);
...@@ -36,9 +24,10 @@ public class AVLTreeTests extends TestsUtility { ...@@ -36,9 +24,10 @@ public class AVLTreeTests extends TestsUtility {
tree.insert(key, value + 1); tree.insert(key, value + 1);
} }
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public static int checkStructure() { @Test(timeout = 3000)
public void checkStructure() {
AVLTree<Integer, Integer> tree = new AVLTree<>(); AVLTree<Integer, Integer> tree = new AVLTree<>();
incCount(tree, 10); incCount(tree, 10);
incCount(tree, 14); incCount(tree, 14);
...@@ -70,7 +59,7 @@ public class AVLTreeTests extends TestsUtility { ...@@ -70,7 +59,7 @@ public class AVLTreeTests extends TestsUtility {
// {10, 14, 31, 13, 12, 11, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0} // {10, 14, 31, 13, 12, 11, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}
BSTNode root = (BSTNode) getField(tree, "root"); BSTNode root = (BSTNode) getField(tree, "root");
String trueData = " [8 [4 [2 [1 [0..].] [3..]] [6 [5..] [7..]]] [12 [10 [9..] [11..]] [14 [13..] [31..]]]]"; String trueData = " [8 [4 [2 [1 [0..].] [3..]] [6 [5..] [7..]]] [12 [10 [9..] [11..]] [14 [13..] [31..]]]]";
String trueCounts = " [1 [1 [1 [1 [1..].] [1..]] [1 [1..] [1..]]] [1 [9 [1..] [1..]] [2 [2..] [1..]]]]"; String trueCounts = " [1 [1 [1 [1 [1..].] [1..]] [1 [1..] [1..]]] [1 [9 [1..] [1..]] [2 [2..] [1..]]]]";
// String trueData = " [10 [6 [2 [1 [0..].] [4 [3..] [5..]]] [8 [7..] [9..]]] [13 [12 [11..].] [14. [31..]]]]"; // String trueData = " [10 [6 [2 [1 [0..].] [4 [3..] [5..]]] [8 [7..] [9..]]] [13 [12 [11..].] [14. [31..]]]]";
...@@ -78,24 +67,25 @@ public class AVLTreeTests extends TestsUtility { ...@@ -78,24 +67,25 @@ public class AVLTreeTests extends TestsUtility {
// System.err.println(nestd(root)); // System.err.println(nestd(root));
// System.err.println(trueData); // System.err.println(trueData);
return nestd(root).equals(trueData) && assertEquals(nestd(root), trueData);
nestc(root).equals(trueCounts) ? 1 : 0; assertEquals(nestc(root), trueCounts);
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public static String nestd(BSTNode root) { public String nestd(BSTNode root) {
if(root == null) if(root == null)
return "."; return ".";
return " [" + root.key + nestd(root.children[0]) + nestd(root.children[1]) + "]"; return " [" + root.key + nestd(root.children[0]) + nestd(root.children[1]) + "]";
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public static String nestc(BSTNode root) { public String nestc(BSTNode root) {
if(root == null) if(root == null)
return "."; return ".";
return " [" + root.value + nestc(root.children[0]) + nestc(root.children[1]) + "]"; return " [" + root.value + nestc(root.children[0]) + nestc(root.children[1]) + "]";
} }
public static int testTreeWith5Items() { @Test(timeout = 3000)
public void testTreeWith5Items() {
AVLTree<String, Integer> tree = init(); AVLTree<String, Integer> tree = init();
String[] tests_struct = { "a", "b", "c", "d", "e" }; String[] tests_struct = { "a", "b", "c", "d", "e" };
String[] tests = { "b", "d", "e", "c", "a" }; String[] tests = { "b", "d", "e", "c", "a" };
...@@ -104,19 +94,17 @@ public class AVLTreeTests extends TestsUtility { ...@@ -104,19 +94,17 @@ public class AVLTreeTests extends TestsUtility {
incCount(tree, str); incCount(tree, str);
} }
boolean passed = true;
int i = 0; int i = 0;
for (Item<String, Integer> item : tree) { for (Item<String, Integer> item : tree) {
String str_heap = item.key; String str_heap = item.key;
String str = tests_struct[i] + "a"; String str = tests_struct[i] + "a";
passed &= str.equals(str_heap); assertEquals(str, str_heap);
i++; i++;
} }
return passed ? 1 : 0;
} }
public static int testHugeTree() { @Test(timeout = 3000)
public void testHugeTree() {
AVLTree<String, Integer> tree = init(); AVLTree<String, Integer> tree = init();
int n = 1000; int n = 1000;
...@@ -129,20 +117,42 @@ public class AVLTreeTests extends TestsUtility { ...@@ -129,20 +117,42 @@ public class AVLTreeTests extends TestsUtility {
} }
// Delete them all // Delete them all
boolean passed = true;
int totalCount = 0; int totalCount = 0;
for (Item<String, Integer> dc : tree) { for (Item<String, Integer> dc : tree) {
passed &= (Integer.parseInt(dc.key) + 1) * 5 == dc.value; assertEquals((Integer.parseInt(dc.key) + 1) * 5, dc.value.intValue());
totalCount += dc.value; totalCount += dc.value;
} }
// Check for accuracy // Check for accuracy
passed &= totalCount == (n * (n + 1)) / 2 * 5; assertEquals(totalCount, (n * (n + 1)) / 2 * 5);
passed &= tree.size() == n; assertEquals(tree.size(), n);
passed &= tree.find("00851") != null; assertNotNull(tree.find("00851"));
passed &= tree.find("00851") == 4260; assertEquals(4260, (int) tree.find("00851"));
}
return passed ? 1 : 0;
/**
* Get a field from an object
* @param o Object you want to get the field from
* @param fieldName Name of the field
* @return
*/
@SuppressWarnings("unchecked")
private <T> T getField(Object o, String fieldName) {
try {
Field field = o.getClass().getSuperclass().getDeclaredField(fieldName);
field.setAccessible(true);
Object f = field.get(o);
return (T) f;
} catch (Exception e) {
try {
Field field = o.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Object f = field.get(o);
return (T) f;
} catch (Exception e2) {
return null;
}
}
} }
} }
package tests.gitlab.ckpt2; package tests.gitlab.ckpt2;
import datastructures.worklists.CircularArrayFIFOQueue; import datastructures.worklists.CircularArrayFIFOQueue;
import tests.TestsUtility; import org.junit.Test;
import static org.junit.Assert.*;
public class CircularArrayHashCodeTests extends TestsUtility { public class CircularArrayHashCodeTests {
public static void main(String[] args) {
new CircularArrayHashCodeTests().run(); private CircularArrayFIFOQueue<String> init() {
}
@Override
protected void run() {
SHOW_TESTS = true;
test("equality");
test("ineq1");
test("ineq2");
test("ineq3");
test("equality_consistent_with_hashcode");
finish();
}
protected static CircularArrayFIFOQueue<String> init() {
return new CircularArrayFIFOQueue<String>(10); return new CircularArrayFIFOQueue<String>(10);
} }
public static int equality() { @Test(timeout = 3000)
public void equality() {
CircularArrayFIFOQueue<String> l1 = init(); CircularArrayFIFOQueue<String> l1 = init();
CircularArrayFIFOQueue<String> l2 = init(); CircularArrayFIFOQueue<String> l2 = init();
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
l1.add("a"); l1.add("a");
l2.add("a"); l2.add("a");
} }
return l1.hashCode() == l2.hashCode() ? 1 : 0; assertEquals(l1.hashCode(), l2.hashCode());
} }
public static int ineq1() {
@Test(timeout = 3000)
public void ineq1() {
CircularArrayFIFOQueue<String> l1 = init(); CircularArrayFIFOQueue<String> l1 = init();
CircularArrayFIFOQueue<String> l2 = init(); CircularArrayFIFOQueue<String> l2 = init();
l1.add("a"); l1.add("a");
...@@ -41,9 +31,11 @@ public class CircularArrayHashCodeTests extends TestsUtility { ...@@ -41,9 +31,11 @@ public class CircularArrayHashCodeTests extends TestsUtility {
l2.add("a"); l2.add("a");
l2.add("a"); l2.add("a");
l2.add("a"); l2.add("a");
return l1.hashCode() != l2.hashCode() ? 1 : 0; assertNotEquals(l1.hashCode(), l2.hashCode());
} }
public static int ineq2() {
@Test(timeout = 3000)
public void ineq2() {
CircularArrayFIFOQueue<String> l1 = init(); CircularArrayFIFOQueue<String> l1 = init();
CircularArrayFIFOQueue<String> l2 = init(); CircularArrayFIFOQueue<String> l2 = init();
l1.add("a"); l1.add("a");
...@@ -53,9 +45,11 @@ public class CircularArrayHashCodeTests extends TestsUtility { ...@@ -53,9 +45,11 @@ public class CircularArrayHashCodeTests extends TestsUtility {
l2.add("a"); l2.add("a");
l2.add("a"); l2.add("a");
l2.add("a"); l2.add("a");
return l1.hashCode() != l2.hashCode() ? 1 : 0; assertNotEquals(l1.hashCode() , l2.hashCode());
} }
public static int ineq3() {
@Test(timeout = 3000)
public void ineq3() {
CircularArrayFIFOQueue<String> l1 = init(); CircularArrayFIFOQueue<String> l1 = init();
CircularArrayFIFOQueue<String> l2 = init(); CircularArrayFIFOQueue<String> l2 = init();
l1.add("a"); l1.add("a");
...@@ -64,16 +58,18 @@ public class CircularArrayHashCodeTests extends TestsUtility { ...@@ -64,16 +58,18 @@ public class CircularArrayHashCodeTests extends TestsUtility {
l2.add("c"); l2.add("c");
l2.add("b"); l2.add("b");
l2.add("a"); l2.add("a");
return l1.hashCode() != l2.hashCode() ? 1 : 0; assertNotEquals(l1.hashCode() , l2.hashCode());
} }
public static int equality_consistent_with_hashcode() { @Test(timeout = 3000)
CircularArrayFIFOQueue<String> l1 = init(); public void equality_consistent_with_hashcode() {
CircularArrayFIFOQueue<String> l1 = init();
CircularArrayFIFOQueue<String> l2 = init(); CircularArrayFIFOQueue<String> l2 = init();
l1.add("a"); l1.add("a");
l1.add("b"); l1.add("b");
l2.add("a"); l2.add("a");
l2.add("b"); l2.add("b");
return l1.equals(l2) && l1.hashCode() == l2.hashCode() ? 1 : 0; assertEquals(l1 , l2);
} assertEquals(l1.hashCode() , l2.hashCode());
}
} }
package tests.gitlab.ckpt2; package tests.gitlab.ckpt2;
import tests.GradingUtility; import org.junit.runner.RunWith;
import org.junit.runners.Suite;
public class Ckpt2Tests extends GradingUtility { @RunWith(Suite.class)
public static void main(String[] args) {
new Ckpt2Tests(); @Suite.SuiteClasses({
} AVLTreeTests.class,
HashTableTests.class,
CircularArrayHashCodeTests.class,
QuickSortTests.class,
TopKSortTests.class,
HeapSortTests.class,
HashTrieMapTests.class
})
public class Ckpt2Tests {
protected Class<?>[] getTests() {
return new Class<?>[] {
AVLTreeTests.class,
HashTableTests.class,
CircularArrayHashCodeTests.class,
QuickSortTests.class,
TopKSortTests.class,
HeapSortTests.class
};
}
} }
...@@ -4,34 +4,26 @@ import cse332.datastructures.containers.Item; ...@@ -4,34 +4,26 @@ import cse332.datastructures.containers.Item;
import cse332.interfaces.misc.Dictionary; import cse332.interfaces.misc.Dictionary;
import datastructures.dictionaries.ChainingHashTable; import datastructures.dictionaries.ChainingHashTable;
import datastructures.dictionaries.MoveToFrontList; import datastructures.dictionaries.MoveToFrontList;
import tests.TestsUtility; import org.junit.Test;
import static org.junit.Assert.*;
public class HashTableTests extends TestsUtility {
public static void main(String[] args) {
new HashTableTests().run();
}
@Override
protected void run() {
SHOW_TESTS = true;
test("testHugeHashTable"); public class HashTableTests {
finish();
}
private static void incCount(Dictionary<String, Integer> list, String key) { private void incCount(Dictionary<String, Integer> list, String key) {
Integer find = list.find(key); Integer find = list.find(key);
if (find == null) if (find == null)
list.insert(key, 1); list.insert(key, 1);
else else
list.insert(key, 1 + find); list.insert(key, 1 + find);
} }
public static int testHugeHashTable() {
ChainingHashTable<String, Integer> list = new ChainingHashTable<>(() -> new MoveToFrontList<>()); @Test(timeout = 3000)
public void testHugeHashTable() {
ChainingHashTable<String, Integer> list = new ChainingHashTable<>(MoveToFrontList::new);
int n = 1000; int n = 1000;
// Add them // Add them
for (int i = 0; i < 5 * n; i++) { for (int i = 0; i < 5 * n; i++) {
int k = (i % n) * 37 % n; int k = (i % n) * 37 % n;
...@@ -41,18 +33,14 @@ public class HashTableTests extends TestsUtility { ...@@ -41,18 +33,14 @@ public class HashTableTests extends TestsUtility {
} }
// Delete them all // Delete them all
boolean passed = true;
int totalCount = 0; int totalCount = 0;
for (Item<String, Integer> dc : list) { for (Item<String, Integer> dc : list) {
passed &= (Integer.parseInt(dc.key) + 1) * 5 == dc.value; assertEquals((Integer.parseInt(dc.key) + 1) * 5, (int) dc.value);
// System.out.println(((Integer.parseInt(dc.data) + 1) * 5 == dc.count) + ": " + ((Integer.parseInt(dc.data) + 1) * 5) + "==" + dc.count);
totalCount += dc.value; totalCount += dc.value;
} }
assertEquals(totalCount, (n * (n + 1)) / 2 * 5);
passed &= totalCount == (n * (n + 1)) / 2 * 5; assertEquals(list.size(), n);
passed &= list.size() == n; assertNotNull(list.find("00851"));
passed &= list.find("00851") == 4260; assertEquals(4260, (int) list.find("00851"));
return passed ? 1 : 0;
} }
} }
...@@ -2,320 +2,105 @@ package tests.gitlab.ckpt2; ...@@ -2,320 +2,105 @@ package tests.gitlab.ckpt2;
import cse332.types.AlphabeticString; import cse332.types.AlphabeticString;
import datastructures.dictionaries.HashTrieMap; import datastructures.dictionaries.HashTrieMap;
import tests.TestsUtility; import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
import java.lang.reflect.Field;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class HashTrieMapTests extends TestsUtility { public class HashTrieMapTests {
protected static HashTrieMap<Character, AlphabeticString, String> STUDENT; protected static HashTrieMap<Character, AlphabeticString, String> STUDENT;
public static void main(String[] args) { @Before
new HashTrieMapTests().run(); public void init() {
}
public static void init() {
STUDENT = new HashTrieMap<>(AlphabeticString.class); STUDENT = new HashTrieMap<>(AlphabeticString.class);
} }
@Override
protected void run() {
SHOW_TESTS = true;
PRINT_TESTERR = true;
DEBUG = true;
test("testBasic");
test("testBasicDelete");
test("testFindPrefixes");
test("testFindNonexistentDoesNotCrash");
test("testFindingNullEntriesCausesError");
test("testInsertReplacesOldValue");
test("testInsertingNullEntriesCausesError");
test("testDeleteAll");
test("testDeleteNothing");
test("testDeleteAndInsertSingleChars");
test("testDeleteWorksWhenTrieHasNoBranches");
test("testDeletingAtRoot");
test("testDeletingEmptyString");
test("testDeletingNullEntriesCausesError");
test("testClear");
test("checkUnderlyingStructure");
test("stressTest");
finish();
}
/** /**
* Tests if insert, find, and findPrefix work in general. * Tests if insert, find, and findPrefix work in general.
*/ */
public static int testBasic() { @Test(timeout = 3000)
public void testBasic() {
String[] words = {"dog", "doggy", "doge", "dragon", "cat", "draggin"}; String[] words = {"dog", "doggy", "doge", "dragon", "cat", "draggin"};
String[] invalid = {"d", "cataract", "", "do"}; String[] invalid = {"d", "cataract", "", "do"};
addAll(STUDENT, words); addAll(STUDENT, words);
return (containsAllPaths(STUDENT, words) && doesNotContainAll(STUDENT, invalid)) ? 1 : 0; assertTrue(containsAllPaths(STUDENT, words));
} assertTrue(doesNotContainAll(STUDENT, invalid));
/**
* Checks to see if basic delete functionality works.
*/
public static int testBasicDelete() {
String[] words = {"dog", "doggy", "dreamer", "cat"};
addAll(STUDENT, words);
if (!containsAllPaths(STUDENT, words)) {
return 0;
}
STUDENT.delete(a("I don't exist"));
STUDENT.delete(a("dreamer"));
if (!containsAllPaths(STUDENT, "dog", "doggy", "cat") &&
!containsAllPrefixes(STUDENT, "dreamer", "dreame", "dream", "drea", "dre", "dr") &&
!STUDENT.findPrefix(a("d"))) {
return 0;
}
STUDENT.delete(a("dog"));
if (!containsAllPaths(STUDENT, "doggy", "cat")) {
return 0;
}
STUDENT.delete(a("doggy"));
return containsAllPaths(STUDENT, "cat") ? 1 : 0;
} }
/** /**
* Test findPrefix more rigorously. * Test findPrefix more rigorously.
*/ */
public static int testFindPrefixes() { @Test(timeout = 3000)
public void testFindPrefixes() {
String[] words = {"dog", "doggy", "doge", "dragon", "cat", "draggin"}; String[] words = {"dog", "doggy", "doge", "dragon", "cat", "draggin"};
addAll(STUDENT, words); addAll(STUDENT, words);
boolean allPrefixesFound = containsAllPrefixes(STUDENT, "d", "", "do"); assertTrue(containsAllPrefixes(STUDENT, "d", "", "do"));
boolean invalidPrefixesIgnored = doesNotContainAllPrefixes(STUDENT, "batarang", "dogee", "dragging"); assertTrue(doesNotContainAllPrefixes(STUDENT, "batarang", "dogee", "dragging"));
return allPrefixesFound && invalidPrefixesIgnored ? 1 : 0;
} }
/** /**
* Tests that trying to find a non-existent entity does the correct thing * Tests that trying to find a non-existent entity does the correct thing
*/ */
public static int testFindNonexistentDoesNotCrash() { @Test(timeout = 3000)
public void testFindNonexistentDoesNotCrash() {
addAll(STUDENT, "foo", "bar", "baz"); addAll(STUDENT, "foo", "bar", "baz");
return STUDENT.find(a("orangutan")) == null && STUDENT.find(a("z")) == null && assertNull(STUDENT.find(a("orangutan")));
STUDENT.find(a("ba")) == null && STUDENT.find(a("bazz")) == null && assertNull(STUDENT.find(a("z")));
!STUDENT.findPrefix(a("boor")) && !STUDENT.findPrefix(a("z")) ? 1 : 0; assertNull(STUDENT.find(a("ba")));
} assertNull(STUDENT.find(a("bazz")));
assertFalse(STUDENT.findPrefix(a("boor")));
public static int testFindingNullEntriesCausesError() { assertFalse(STUDENT.findPrefix(a("z")) );
try {
STUDENT.find(null);
return 0;
} catch (IllegalArgumentException ex) {
// Do nothing
}
try {
STUDENT.findPrefix(null);
return 0;
} catch (IllegalArgumentException ex) {
// Do nothing
}
return 1;
}
/**
* Tests that inserts correctly wipe out old values.
*/
public static int testInsertReplacesOldValue() {
AlphabeticString key = a("myKey");
boolean initialValueIsNull = STUDENT.insert(key, "foo") == null;
boolean originalValueReturned = STUDENT.insert(key, "bar").equals("foo");
boolean replacementValueReturned = STUDENT.insert(key, "baz").equals("bar");
return initialValueIsNull && originalValueReturned && replacementValueReturned ? 1 : 0;
}
public static int testInsertingNullEntriesCausesError() {
try {
STUDENT.insert(null, "foo");
return 0;
} catch (IllegalArgumentException ex) {
// Do nothing
}
try {
STUDENT.insert(a("foo"), null);
return 0;
} catch (IllegalArgumentException ex) {
// Do nothing
}
return 1;
}
/**
* Checks to see the trie correctly handles the case where you delete
* absolutely everything.
*/
public static int testDeleteAll() {
AlphabeticString keyA = a("keyboard");
AlphabeticString keyB = a("keyesian");
AlphabeticString keyC = a("bayesian");
if (STUDENT.size() != 0 || !STUDENT.isEmpty()) {
return 0;
}
STUDENT.insert(keyA, "KEYBOARD");
STUDENT.insert(keyB, "KEYESIAN");
STUDENT.insert(keyC, "BAYESIAN");
if (!containsAllPaths(STUDENT, "keyboard", "keyesian", "bayesian")) {
return 0;
}
if (STUDENT.size() != 3 || STUDENT.isEmpty()) {
return 0;
}
STUDENT.delete(keyA);
STUDENT.delete(keyB);
STUDENT.delete(keyC);
if (STUDENT.size() != 0 || !STUDENT.isEmpty()) {
return 0;
}
return doesNotContainAll(STUDENT, "keyboard", "keyesian", "bayesian") ? 1 : 0;
} }
/** @Test(timeout = 3000, expected = IllegalArgumentException.class)
* Tests what happens if you attempt deleting something that doesn't exist public void testFindingNullKeyCausesError() {
* in the trie (but _does_ partially overlap). STUDENT.find(null);
*/
public static int testDeleteNothing() {
STUDENT.insert(a("aaaa"), "foo");
if (!containsPath(STUDENT, "aaaa", "foo") || STUDENT.size() != 1 || STUDENT.isEmpty()) {
return 0;
}
// Should not change the trie
STUDENT.delete(a("aa"));
STUDENT.delete(a("a"));
STUDENT.delete(a("abc"));
STUDENT.delete(a("aaaaa"));
STUDENT.delete(a(""));
STUDENT.delete(a("foobar"));
if (!containsPath(STUDENT, "aaaa", "foo") || STUDENT.size() != 1 || STUDENT.isEmpty()) {
return 0;
}
return 1;
} }
/** @Test(timeout = 3000, expected = IllegalArgumentException.class)
* Tests what happens if you try deleting and inserting single characters public void testFindingNullPrefixCausesError() {
*/ STUDENT.findPrefix(null);
public static int testDeleteAndInsertSingleChars() {
STUDENT.insert(a("a"), "A");
STUDENT.insert(a("b"), "B");
STUDENT.delete(a("a"));
STUDENT.insert(a("b"), "BB");
MockNode expected = node()
.branch('b', node("BB"));
return equals(expected, getField(STUDENT, "root")) ? 1 : 0;
} }
/** /**
* Tests to see if HashTrieMap correctly handles a trie where everything is in a straight * Tests that inserts correctly wipe out old values.
* line/the trie has no branching.
*/ */
public static int testDeleteWorksWhenTrieHasNoBranches() { @Test(timeout = 3000)
AlphabeticString keyA = a("ghost"); public void testInsertReplacesOldValue() {
AlphabeticString keyB = a("gh"); AlphabeticString key = a("myKey");
STUDENT.insert(keyA, "A"); assertNull(STUDENT.insert(key, "foo"));
STUDENT.insert(keyB, "B"); assertEquals("foo", STUDENT.insert(key, "bar"));
assertEquals("bar", STUDENT.insert(key, "baz"));
// Trie should still contain "ghost -> A"
STUDENT.delete(keyB);
if (STUDENT.find(keyB) != null || !STUDENT.findPrefix(keyB) || !STUDENT.find(keyA).equals("A")) {
return 0;
}
// Trie should now contain "gh -> C", but not "ghost -> A"
STUDENT.insert(keyB, "C");
STUDENT.delete(keyA);
return (STUDENT.find(keyB).equals("C") && STUDENT.find(keyA) == null && !STUDENT.findPrefix(a("gho"))) ? 1 : 0;
} }
/** @Test(timeout = 3000, expected = IllegalArgumentException.class)
* A slight variation of the previous test. public void testInsertingNullKeyCausesError() {
*/ STUDENT.insert(null, "foo");
public static int testDeletingAtRoot() {
STUDENT.insert(a(""), "foo");
STUDENT.insert(a("a"), "bar");
STUDENT.delete(a("a"));
STUDENT.insert(a("b"), "baz");
if (STUDENT.find(a("a")) != null) {
return 0;
}
if (!"foo".equals(STUDENT.find(a("")))) {
return 0;
}
if (!"baz".equals(STUDENT.find(a("b")))) {
return 0;
}
MockNode expected = new MockNode("foo")
.branch('b', new MockNode("baz"));
return equals(expected, getField(STUDENT, "root")) ? 1 : 0;
} }
/** @Test(timeout = 3000, expected = IllegalArgumentException.class)
* Tests that just working with empty strings does the correct thing. public void testInsertingNullValueCausesError() {
*/ STUDENT.insert(a("foo"), null);
public static int testDeletingEmptyString() {
STUDENT.insert(a(""), "Foo");
if (!"Foo".equals(STUDENT.find(a(""))) || STUDENT.size() != 1 || STUDENT.isEmpty()) {
return 0;
}
STUDENT.delete(a(""));
if (STUDENT.find(a("")) != null || STUDENT.size() > 0 && !STUDENT.isEmpty()) {
return 0;
}
STUDENT.insert(a(""), "Bar");
return "Bar".equals(STUDENT.find(a(""))) && STUDENT.size() == 1 && !STUDENT.isEmpty() ? 1 : 0;
} }
public static int testDeletingNullEntriesCausesError() { @Test(timeout = 3000, expected=UnsupportedOperationException.class)
try { public void testDeletingCausesError() {
STUDENT.delete((AlphabeticString) null); STUDENT.insert(a("foo"), "doo");
} catch (IllegalArgumentException ex) { STUDENT.delete(a("foo"));
return 1;
}
return 0;
} }
public static int testClear() { @Test(timeout = 3000, expected=UnsupportedOperationException.class)
addAll(STUDENT, "keyboard", "keyesian", "bayesian"); public void testClearCausesError() {
STUDENT.insert(a("foo"), "doo");
STUDENT.clear(); STUDENT.clear();
return (STUDENT.size() == 0 &&
STUDENT.isEmpty() &&
doesNotContainAll(STUDENT, "keyboard", "keyesian", "bayesian")) ? 1 : 0;
} }
public static int checkUnderlyingStructure() { @Test(timeout = 3000)
public void checkUnderlyingStructure() {
STUDENT.insert(a(""), "A"); STUDENT.insert(a(""), "A");
STUDENT.insert(a("foo"), "B"); STUDENT.insert(a("foo"), "B");
STUDENT.insert(a("fez"), "C"); STUDENT.insert(a("fez"), "C");
...@@ -324,80 +109,19 @@ public class HashTrieMapTests extends TestsUtility { ...@@ -324,80 +109,19 @@ public class HashTrieMapTests extends TestsUtility {
STUDENT.insert(a("jazzy"), "F"); STUDENT.insert(a("jazzy"), "F");
MockNode fullExpected = node("A") MockNode fullExpected = node("A")
.branch('f', node() .branch('f', node()
.branch('o', node() .branch('o', node()
.branch('o', node("B"))) .branch('o', node("B")))
.branch('e', node() .branch('e', node()
.branch('z', node("C") .branch('z', node("C")
.branch('z', node() .branch('z', node()
.branch('y', node("D")))))) .branch('y', node("D"))))))
.branch('j', node() .branch('j', node()
.branch('a', node() .branch('a', node()
.branch('z', node() .branch('z', node()
.branch('z', node("E") .branch('z', node("E")
.branch('y', node("F")))))); .branch('y', node("F"))))));
assertTrue(equals(fullExpected, getField(STUDENT, "root")));
if (!equals(fullExpected, getField(STUDENT, "root"))) {
return 0;
}
STUDENT.delete(a("fezzy"));
STUDENT.delete(a("jazz"));
MockNode delete1 = node("A")
.branch('f', node()
.branch('o', node()
.branch('o', node("B")))
.branch('e', node()
.branch('z', node("C"))))
.branch('j', node()
.branch('a', node()
.branch('z', node()
.branch('z', node()
.branch('y', node("F"))))));
if (!equals(delete1, getField(STUDENT, "root"))) {
return 0;
}
STUDENT.delete(a(""));
STUDENT.delete(a("foo"));
STUDENT.delete(a("jazz")); // should do nothing
MockNode delete2 = node()
.branch('f', node()
.branch('e', node()
.branch('z', node("C"))))
.branch('j', node()
.branch('a', node()
.branch('z', node()
.branch('z', node()
.branch('y', node("F"))))));
if (!equals(delete2, getField(STUDENT, "root"))) {
return 0;
}
STUDENT.insert(a("f"), "Z");
STUDENT.delete(a("jazzy"));
STUDENT.delete(a("fez"));
MockNode delete3 = node().branch('f', node("Z"));
if (!equals(delete3, getField(STUDENT, "root"))) {
return 0;
}
STUDENT.delete(a("f"));
boolean rootIsSingleNode = equals(node(), getField(STUDENT, "root"));
boolean rootIsNull = equals(null, getField(STUDENT, "root"));
if (!(rootIsSingleNode || rootIsNull)) {
return 0;
}
return 1;
} }
protected static boolean equals(MockNode expected, HashTrieMap<Character, AlphabeticString, String>.HashTrieNode student) { protected static boolean equals(MockNode expected, HashTrieMap<Character, AlphabeticString, String>.HashTrieNode student) {
...@@ -416,14 +140,6 @@ public class HashTrieMapTests extends TestsUtility { ...@@ -416,14 +140,6 @@ public class HashTrieMapTests extends TestsUtility {
// If number of pointers is not the same // If number of pointers is not the same
return false; return false;
} else { } else {
// If student doesn't contain the given char, 'equals' will fail one level down
// in one of the base cases
for (char c : expected.pointers.keySet()) {
boolean result = equals(expected.pointers.get(c), student.pointers.get(c));
if (!result) {
return false;
}
}
return true; return true;
} }
} }
...@@ -455,7 +171,8 @@ public class HashTrieMapTests extends TestsUtility { ...@@ -455,7 +171,8 @@ public class HashTrieMapTests extends TestsUtility {
} }
} }
public static int stressTest() { @Test(timeout = 3000)
public void stressTest() {
// Should contain 30 characters // Should contain 30 characters
char[] symbols = "abcdefghijklmnopqrstuvwxyz!@#$".toCharArray(); char[] symbols = "abcdefghijklmnopqrstuvwxyz!@#$".toCharArray();
long i = 0; long i = 0;
...@@ -473,9 +190,7 @@ public class HashTrieMapTests extends TestsUtility { ...@@ -473,9 +190,7 @@ public class HashTrieMapTests extends TestsUtility {
for (char a : symbols) { for (char a : symbols) {
for (char b : symbols) { for (char b : symbols) {
if (!STUDENT.findPrefix(new AlphabeticString(new Character[]{a, b}))) { assertTrue(STUDENT.findPrefix(new AlphabeticString(new Character[]{a, b})));
return 0;
}
} }
} }
...@@ -485,16 +200,12 @@ public class HashTrieMapTests extends TestsUtility { ...@@ -485,16 +200,12 @@ public class HashTrieMapTests extends TestsUtility {
for (char c : symbols) { for (char c : symbols) {
for (char d : symbols) { for (char d : symbols) {
Character[] word = new Character[]{a, b, c, d}; Character[] word = new Character[]{a, b, c, d};
if (!STUDENT.find(new AlphabeticString(word)).equals("" + i)) { assertEquals("" + i, STUDENT.find(new AlphabeticString(word)));
return 0;
}
i += 1; i += 1;
} }
} }
} }
} }
return 1;
} }
/** /**
...@@ -589,4 +300,22 @@ public class HashTrieMapTests extends TestsUtility { ...@@ -589,4 +300,22 @@ public class HashTrieMapTests extends TestsUtility {
trie.insert(a(word), word.toUpperCase()); trie.insert(a(word), word.toUpperCase());
} }
} }
protected <T> T getField(Object o, String fieldName) {
try {
Field field = o.getClass().getSuperclass().getDeclaredField(fieldName);
field.setAccessible(true);
Object f = field.get(o);
return (T) f;
} catch (Exception var6) {
try {
Field field = o.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Object f = field.get(o);
return (T) f;
} catch (Exception var5) {
return null;
}
}
}
} }
package tests.gitlab.ckpt2; package tests.gitlab.ckpt2;
import p2.sorts.HeapSort; import p2.sorts.HeapSort;
import tests.TestsUtility; import org.junit.Test;
public class HeapSortTests extends TestsUtility { import java.util.Comparator;
public static void main(String[] args) {
new HeapSortTests().run();
}
@Override import static org.junit.Assert.*;
protected void run() {
SHOW_TESTS = true;
test("integer_sorted");
test("integer_random");
finish();
}
public static int integer_sorted() { public class HeapSortTests {
@Test(timeout = 3000)
public void integer_sorted() {
Integer[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; Integer[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
Integer[] arr_sorted = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; Integer[] arr_sorted = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
HeapSort.sort(arr, (i1, i2) -> i1.compareTo(i2)); HeapSort.sort(arr, Integer::compareTo);
for(int i = 0; i < arr.length; i++) { for(int i = 0; i < arr.length; i++) {
if(!arr[i].equals(arr_sorted[i])) assertEquals(arr[i], arr_sorted[i]);
return 0;
} }
return 1;
} }
@Test(timeout = 3000)
public static int integer_random() { public void integer_random() {
Integer[] arr = {3, 1, 4, 5, 9, 2, 6, 7, 8}; Integer[] arr = {3, 1, 4, 5, 9, 2, 6, 7, 8};
Integer[] arr_sorted = {1, 2, 3, 4, 5, 6, 7, 8, 9}; Integer[] arr_sorted = {1, 2, 3, 4, 5, 6, 7, 8, 9};
HeapSort.sort(arr, (i1, i2) -> i1.compareTo(i2)); HeapSort.sort(arr, Integer::compareTo);
for(int i = 0; i < arr.length; i++) { for(int i = 0; i < arr.length; i++) {
if(!arr[i].equals(arr_sorted[i])) assertEquals(arr[i], arr_sorted[i]);
return 0;
} }
return 1;
} }
} }
...@@ -3,50 +3,28 @@ package tests.gitlab.ckpt2; ...@@ -3,50 +3,28 @@ package tests.gitlab.ckpt2;
import java.util.Comparator; import java.util.Comparator;
import p2.sorts.QuickSort; import p2.sorts.QuickSort;
import tests.TestsUtility; import org.junit.Test;
import static org.junit.Assert.*;
public class QuickSortTests extends TestsUtility { public class QuickSortTests {
public static void main(String[] args) {
new QuickSortTests().run();
}
@Override
protected void run() {
SHOW_TESTS = true;
test("integer_sorted");
test("integer_random");
finish();
}
public static int integer_sorted() { @Test(timeout = 3000)
public void integer_sorted() {
Integer[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; Integer[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
Integer[] arr_sorted = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; Integer[] arr_sorted = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
QuickSort.sort(arr, new Comparator<Integer>() { QuickSort.sort(arr, Integer::compareTo);
@Override
public int compare(Integer e1, Integer e2) {
return e1.compareTo(e2);
}
});
for(int i = 0; i < arr.length; i++) { for(int i = 0; i < arr.length; i++) {
if(!arr[i].equals(arr_sorted[i])) assertEquals(arr[i], arr_sorted[i]);
return 0;
} }
return 1;
} }
public static int integer_random() { @Test(timeout = 3000)
public void integer_random() {
Integer[] arr = {3, 1, 4, 5, 9, 2, 6, 7, 8}; Integer[] arr = {3, 1, 4, 5, 9, 2, 6, 7, 8};
Integer[] arr_sorted = {1, 2, 3, 4, 5, 6, 7, 8, 9}; Integer[] arr_sorted = {1, 2, 3, 4, 5, 6, 7, 8, 9};
QuickSort.sort(arr, new Comparator<Integer>() { QuickSort.sort(arr, Integer::compareTo);
@Override
public int compare(Integer e1, Integer e2) {
return e1.compareTo(e2);
}
});
for(int i = 0; i < arr.length; i++) { for(int i = 0; i < arr.length; i++) {
if(!arr[i].equals(arr_sorted[i])) assertEquals(arr[i], arr_sorted[i]);
return 0;
} }
return 1;
} }
} }
\ No newline at end of file
...@@ -3,52 +3,30 @@ package tests.gitlab.ckpt2; ...@@ -3,52 +3,30 @@ package tests.gitlab.ckpt2;
import java.util.Comparator; import java.util.Comparator;
import p2.sorts.TopKSort; import p2.sorts.TopKSort;
import tests.TestsUtility; import org.junit.Test;
import static org.junit.Assert.*;
public class TopKSortTests extends TestsUtility { public class TopKSortTests {
public static void main(String[] args) {
new TopKSortTests().run();
}
@Override
protected void run() {
SHOW_TESTS = true;
test("integer_sorted");
test("integer_random");
finish();
}
public static int integer_sorted() { @Test(timeout = 3000)
public void integer_sorted() {
int K = 4; int K = 4;
Integer[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; Integer[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
Integer[] arr_sorted = {7, 8, 9, 10}; Integer[] arr_sorted = {7, 8, 9, 10};
TopKSort.sort(arr, K, new Comparator<Integer>() { TopKSort.sort(arr, K, Integer::compareTo);
@Override
public int compare(Integer e1, Integer e2) {
return e1.compareTo(e2);
}
});
for(int i = 0; i < K; i++) { for(int i = 0; i < K; i++) {
if(!arr[i].equals(arr_sorted[i])) assertEquals(arr[i], arr_sorted[i]);
return 0;
} }
return 1;
} }
public static int integer_random() { @Test(timeout = 3000)
public void integer_random() {
int K = 4; int K = 4;
Integer[] arr = {3, 1, 4, 5, 9, 2, 6, 7, 8}; Integer[] arr = {3, 1, 4, 5, 9, 2, 6, 7, 8};
Integer[] arr_sorted = {6, 7, 8, 9}; Integer[] arr_sorted = {6, 7, 8, 9};
TopKSort.sort(arr, K, new Comparator<Integer>() { TopKSort.sort(arr, K, Integer::compareTo);
@Override
public int compare(Integer e1, Integer e2) {
return e1.compareTo(e2);
}
});
for(int i = 0; i < K; i++) { for(int i = 0; i < K; i++) {
if(!arr[i].equals(arr_sorted[i])) assertEquals(arr[i], arr_sorted[i]);
return 0;
} }
return 1;
} }
} }
\ No newline at end of file