package ch.akuhn.util; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotSame; import org.junit.Test; import org.junit.runner.RunWith; import ch.unibe.jexample.Given; import ch.unibe.jexample.JExample; @RunWith(JExample.class) @SuppressWarnings("unchecked") public class BagTest { private static String sortedPrint(Iterable iter) { return As.list(Get.sorted(iter)).toString(); } @Test public void addNone() { Bag<String> bag = new Bag<String>(); assertEquals(false, bag.add("aaa", 0)); } @Test(expected = IllegalArgumentException.class) public void cannotAddNegativeOccurrences() { new Bag().add("A", -1); } @Test(expected = IllegalArgumentException.class) @Given("#withAAA") public void cannotAddNegativeOccurrencesWithAAA(Bag bag) { bag.add("A", -1); } @Test @Given("#empty") public void clearEmpty(Bag bag) { bag.clear(); assertEquals(0, bag.size()); assertEquals(0, bag.uniqueSize()); assertEquals(true, bag.isEmpty()); } @Test @Given("#withMany") public void clearWithMany(Bag bag) { bag.clear(); assertEquals(0, bag.size()); assertEquals(0, bag.uniqueSize()); assertEquals(true, bag.isEmpty()); } @Test @Given("#empty") public void containsEmpty(Bag bag) { assertEquals(false, bag.contains("A")); assertEquals(false, bag.contains("B")); assertEquals(false, bag.contains("C")); assertEquals(false, bag.contains("D")); } @Test @Given("#withAAA") public void containsWithAAA(Bag bag) { assertEquals(true, bag.contains("A")); assertEquals(false, bag.contains("B")); assertEquals(false, bag.contains("C")); assertEquals(false, bag.contains("D")); } @Test @Given("#withABC") public void containsWithABC(Bag bag) { assertEquals(true, bag.contains("A")); assertEquals(true, bag.contains("B")); assertEquals(true, bag.contains("C")); assertEquals(false, bag.contains("D")); } @Test @Given("#withMany") public void containsWithMany(Bag bag) { assertEquals(true, bag.contains("A")); assertEquals(true, bag.contains("B")); assertEquals(true, bag.contains("C")); } @Test public Bag empty() { Bag bag = new Bag(); assertEquals(0, bag.size()); assertEquals(0, bag.uniqueSize()); assertEquals(true, bag.isEmpty()); return bag; } @Test public void equalsEmptyEmpty() { assertEquals(new Bag(), new Bag()); } @Test @Given("#empty,#withA,#withAAA,#withABC") public void equalsIsReflexive(Bag empty, Bag withA, Bag withAAA, Bag withABC) { assertEquals(empty, empty); assertEquals(withA, withA); assertEquals(withAAA, withAAA); assertEquals(withABC, withABC); } @Test @Given("#withABC,#withABC") public void equalsWithABC(Bag first, Bag second) { assertNotSame(first, second); assertEquals(first, second); } @Test public void hashCodeEmptyEmpty() { assertEquals(new Bag().hashCode(), new Bag().hashCode()); } @Test @Given("#withABC,#withABC") public void hashCodeWithABC(Bag first, Bag second) { assertNotSame(first, second); assertEquals(first.hashCode(), second.hashCode()); } @Test @Given("#empty") public void iterateEmpty(Bag bag) { assertEquals(false, bag.iterator().hasNext()); assertEquals(false, bag.elements().iterator().hasNext()); assertEquals(false, bag.counts().iterator().hasNext()); } @Test @Given("#withAAA") public void iterateWithAAA(Bag bag) { assertEquals("[A, A, A]", sortedPrint(bag)); assertEquals("[A]", sortedPrint(bag.elements())); assertEquals("[3 x A]", sortedPrint(bag.counts())); } @Test @Given("#withABC") public void iterateWithABC(Bag bag) { assertEquals("[A, B, C]", sortedPrint(bag)); assertEquals("[A, B, C]", sortedPrint(bag.elements())); assertEquals("[1 x A, 1 x B, 1 x C]", sortedPrint(bag.counts())); } @Test @Given("#withMany") public void iterateWithMany(Bag bag) { assertEquals("[A, A, A, A, B, C]", sortedPrint(bag)); assertEquals("[A, B, C]", sortedPrint(bag.elements())); assertEquals("[4 x A, 1 x B, 1 x C]", sortedPrint(bag.counts())); } @Test @Given("#empty") public void maxOccurrencesEmpty(Bag bag) { int max = bag.maxOccurrences(); assertEquals(0, max); } @Test @Given("#withA") public void maxOccurrencesWithA(Bag bag) { int max = bag.maxOccurrences(); assertEquals(1, max); } @Test @Given("#withAAA") public void maxOccurrencesWithAAA(Bag bag) { int max = bag.maxOccurrences(); assertEquals(3, max); } @Test @Given("#withMany") public void maxOccurrencesWithMany(Bag bag) { int max = bag.maxOccurrences(); assertEquals(4, max); } @Test @Given("#empty") public void mostOccurringEmpty(Bag bag) { Object most = bag.mostOccurring(); assertEquals(null, most); } @Test @Given("#withA") public void mostOccurringWithA(Bag bag) { Object most = bag.mostOccurring(); assertEquals("A", most); } @Test @Given("#withAAA") public void mostOccurringWithAAA(Bag bag) { Object most = bag.mostOccurring(); assertEquals("A", most); } @Test @Given("#withMany") public void mostOccurringWithMany(Bag bag) { Object most = bag.mostOccurring(); assertEquals("A", most); } @Test @Given("#empty") public void occurrenceEmpty(Bag bag) { assertEquals(0, bag.occurrences("A")); assertEquals(0, bag.occurrences("B")); assertEquals(0, bag.occurrences("C")); assertEquals(0, bag.occurrences("D")); } @Test @Given("#withAAA") public void occurrenceWithAAA(Bag bag) { assertEquals(3, bag.occurrences("A")); assertEquals(0, bag.occurrences("B")); assertEquals(0, bag.occurrences("C")); assertEquals(0, bag.occurrences("D")); } @Test @Given("#withABC") public void occurrenceWithABC(Bag bag) { assertEquals(1, bag.occurrences("A")); assertEquals(1, bag.occurrences("B")); assertEquals(1, bag.occurrences("C")); assertEquals(0, bag.occurrences("D")); } @Test @Given("#withMany") public void occurrenceWithMany(Bag bag) { assertEquals(4, bag.occurrences("A")); assertEquals(1, bag.occurrences("B")); assertEquals(1, bag.occurrences("C")); assertEquals(0, bag.occurrences("D")); } @Test @Given("#empty") public void removeAllEmpty(Bag bag) { boolean f = bag.removeAllOccurrences("A"); assertEquals(false, f); assertEquals(0, bag.size()); assertEquals(0, bag.uniqueSize()); assertEquals(true, bag.isEmpty()); } @Test @Given("#withA") public void removeAllWithA(Bag bag) { boolean f = bag.removeAllOccurrences("A"); assertEquals(true, f); assertEquals(0, bag.size()); assertEquals(0, bag.uniqueSize()); assertEquals(true, bag.isEmpty()); } @Test @Given("#withAAA") public void removeAllWithAAA(Bag bag) { boolean f = bag.removeAllOccurrences("A"); assertEquals(true, f); assertEquals(0, bag.size()); assertEquals(0, bag.uniqueSize()); assertEquals(true, bag.isEmpty()); } @Test @Given("#withMany") public void removeAllWithMany(Bag bag) { boolean f = bag.removeAllOccurrences("A"); assertEquals(true, f); assertEquals(2, bag.size()); assertEquals(2, bag.uniqueSize()); assertEquals(false, bag.isEmpty()); } @Test @Given("#empty") public void removeEmpty(Bag bag) { boolean f = bag.remove("A"); assertEquals(false, f); assertEquals(0, bag.size()); assertEquals(0, bag.uniqueSize()); assertEquals(true, bag.isEmpty()); } @Test @Given("#withA") public void removeWithA(Bag bag) { boolean f = bag.remove("A"); assertEquals(true, f); assertEquals(0, bag.size()); assertEquals(0, bag.uniqueSize()); assertEquals(true, bag.isEmpty()); } @Test @Given("#withAAA") public void removeWithAAA(Bag bag) { boolean f = bag.remove("A"); assertEquals(true, f); assertEquals(2, bag.size()); assertEquals(1, bag.uniqueSize()); assertEquals(false, bag.isEmpty()); } @Test @Given("#withMany") public void removeWithMany(Bag bag) { boolean f = bag.remove("A"); assertEquals(true, f); assertEquals(5, bag.size()); assertEquals(3, bag.uniqueSize()); assertEquals(false, bag.isEmpty()); } @Test public void testAddOccurrencesOverflow() { Bag<String> bag = new Bag<String>(); boolean changed = bag.add("A", Integer.MAX_VALUE - 200); assertEquals(Integer.MAX_VALUE - 200, bag.occurrences("A")); assertEquals(Integer.MAX_VALUE - 200, bag.size()); changed = bag.add("A", 100); assertEquals(true, changed); assertEquals(Integer.MAX_VALUE - 100, bag.occurrences("A")); assertEquals(Integer.MAX_VALUE - 100, bag.size()); changed = bag.add("A", 100); assertEquals(true, changed); assertEquals(Integer.MAX_VALUE, bag.occurrences("A")); assertEquals(Integer.MAX_VALUE, bag.size()); changed = bag.add("A", 100); assertEquals(false, changed); assertEquals(Integer.MAX_VALUE, bag.occurrences("A")); assertEquals(Integer.MAX_VALUE, bag.size()); } @Test public void testAddOccurrencesOverflow2() { Bag<String> bag = new Bag<String>(); boolean changed = bag.add("A", Integer.MAX_VALUE - 150); assertEquals(Integer.MAX_VALUE - 150, bag.occurrences("A")); assertEquals(Integer.MAX_VALUE - 150, bag.size()); changed = bag.add("A", 100); assertEquals(true, changed); assertEquals(Integer.MAX_VALUE - 50, bag.occurrences("A")); assertEquals(Integer.MAX_VALUE - 50, bag.size()); changed = bag.add("A", 100); assertEquals(true, changed); assertEquals(Integer.MAX_VALUE, bag.occurrences("A")); assertEquals(Integer.MAX_VALUE, bag.size()); changed = bag.add("A", 100); assertEquals(false, changed); assertEquals(Integer.MAX_VALUE, bag.occurrences("A")); assertEquals(Integer.MAX_VALUE, bag.size()); } @Test public void testAddOccurrencesOverflow3() { Bag<String> bag = new Bag<String>(); boolean changed = bag.add("A", Integer.MAX_VALUE - 200); assertEquals(Integer.MAX_VALUE - 200, bag.occurrences("A")); assertEquals(Integer.MAX_VALUE - 200, bag.size()); changed = bag.add("A", Integer.MAX_VALUE - 200); assertEquals(true, changed); assertEquals(Integer.MAX_VALUE, bag.occurrences("A")); assertEquals(Integer.MAX_VALUE, bag.size()); changed = bag.add("A", Integer.MAX_VALUE - 200); assertEquals(false, changed); assertEquals(Integer.MAX_VALUE, bag.occurrences("A")); assertEquals(Integer.MAX_VALUE, bag.size()); } @Test public void testAddOverflow() { Bag<String> bag = new Bag<String>(); boolean changed = bag.add("A", Integer.MAX_VALUE - 2); assertEquals(Integer.MAX_VALUE - 2, bag.occurrences("A")); assertEquals(Integer.MAX_VALUE - 2, bag.size()); changed = bag.add("A"); assertEquals(true, changed); assertEquals(Integer.MAX_VALUE - 1, bag.occurrences("A")); assertEquals(Integer.MAX_VALUE - 1, bag.size()); changed = bag.add("A"); assertEquals(true, changed); assertEquals(Integer.MAX_VALUE, bag.occurrences("A")); assertEquals(Integer.MAX_VALUE, bag.size()); changed = bag.add("A"); assertEquals(false, changed); assertEquals(Integer.MAX_VALUE, bag.occurrences("A")); assertEquals(Integer.MAX_VALUE, bag.size()); } @Test @Given("#empty,#withA,#withAAA,#withABC") public void toString(Bag empty, Bag withA, Bag withAAA, Bag withABC) { assertEquals("[]", empty.toString()); assertEquals("[A]", withA.toString()); assertEquals("[A, A, A]", withAAA.toString()); // hash key order is not deterministic, thus check for length only! assertEquals("[A, B, C]".length(), withABC.toString().length()); } @Test @Given("#empty") public Bag withA(Bag bag) { bag.add("A"); assertEquals(1, bag.size()); assertEquals(1, bag.uniqueSize()); assertEquals(false, bag.isEmpty()); return bag; } @Test @Given("#withA") public Bag withAAA(Bag bag) { bag.add("A"); bag.add("A"); assertEquals(3, bag.size()); assertEquals(1, bag.uniqueSize()); assertEquals(false, bag.isEmpty()); return bag; } @Test @Given("#withA") public Bag withABC(Bag bag) { bag.add("B"); bag.add("C"); assertEquals(3, bag.size()); assertEquals(3, bag.uniqueSize()); assertEquals(false, bag.isEmpty()); return bag; } @Test @Given("#withAAA,#withABC") public Bag withMany(Bag bag, Bag more) { bag.addAll(more); assertEquals(6, bag.size()); assertEquals(3, bag.uniqueSize()); assertEquals(false, bag.isEmpty()); return bag; } }