Skip to content

Commit

Permalink
updated BitCountProducer Test
Browse files Browse the repository at this point in the history
  • Loading branch information
Claudenw committed Aug 3, 2023
1 parent 0e404bd commit 8c0c182
Showing 1 changed file with 51 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,148 +21,135 @@
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assumptions.assumeTrue;

import java.util.Arrays;
import java.util.BitSet;

import org.apache.commons.collections4.bag.TreeBag;
import org.apache.commons.collections4.bloomfilter.BitCountProducer.BitCountConsumer;
import org.apache.commons.collections4.bloomfilter.CellProducer.CellConsumer;
import org.junit.jupiter.api.Test;

public abstract class AbstractBitCountProducerTest extends AbstractIndexProducerTest {
public abstract class AbstractCellProducerTest extends AbstractIndexProducerTest {

/**
* A testing BitCountConsumer that always returns true.
* A testing CellConsumer that always returns true.
*/
private static final BitCountConsumer TRUE_CONSUMER = (i, j) -> true;
private static final CellConsumer TRUE_CONSUMER = (i, j) -> true;
/**
* A testing BitCountConsumer that always returns false.
* A testing CellConsumer that always returns false.
*/
private static final BitCountConsumer FALSE_CONSUMER = (i, j) -> false;
private static final CellConsumer FALSE_CONSUMER = (i, j) -> false;

/**
* Creates an array of integer pairs comprising the index and the expected count for the index.
* The order and count for each index is dependent upon the producer created by the {@code createProducer()}
* method.
* By default returns the each {@code getExpectedIndices()} value paired with 1 (one).
* @return an array of integer pairs comprising the index and the expected count for the index.
* Creates an array of expected values that alignes with the expected indices entries.
* @return an array of expected values.
* @see AbstractIndexProducerTest#getExpectedIndices()
*/
protected int[][] getExpectedBitCount() {
return Arrays.stream(getExpectedIndices()).mapToObj(x -> new int[] {x, 1}).toArray(int[][]::new);
protected abstract int[] getExpectedValues();

@Override
protected final int getAsIndexArrayBehaviour() {
return ORDERED | DISTINCT;
}

/**
* Creates a producer with some data.
* @return a producer with some data
*/
@Override
protected abstract BitCountProducer createProducer();
protected abstract CellProducer createProducer();

/**
* Creates a producer without data.
* @return a producer that has no data.
*/
@Override
protected abstract BitCountProducer createEmptyProducer();

/**
* Gets the behavior of the {@link BitCountProducer#forEachCount(BitCountConsumer)} method.
* By default returns the value of {@code getAsIndexArrayBehaviour()} method.
* @return the behavior.
*/
protected int getForEachCountBehaviour() {
return getAsIndexArrayBehaviour();
}
protected abstract CellProducer createEmptyProducer();

@Test
public final void testForEachCountPredicates() {
final BitCountProducer populated = createProducer();
final BitCountProducer empty = createEmptyProducer();
public final void testForEachCellPredicates() {
final CellProducer populated = createProducer();
final CellProducer empty = createEmptyProducer();

assertFalse(populated.forEachCount(FALSE_CONSUMER), "non-empty should be false");
assertTrue(empty.forEachCount(FALSE_CONSUMER), "empty should be true");
assertFalse(populated.forEachCell(FALSE_CONSUMER), "non-empty should be false");
assertTrue(empty.forEachCell(FALSE_CONSUMER), "empty should be true");

assertTrue(populated.forEachCount(TRUE_CONSUMER), "non-empty should be true");
assertTrue(empty.forEachCount(TRUE_CONSUMER), "empty should be true");
assertTrue(populated.forEachCell(TRUE_CONSUMER), "non-empty should be true");
assertTrue(empty.forEachCell(TRUE_CONSUMER), "empty should be true");
}

@Test
public final void testEmptyBitCountProducer() {
final BitCountProducer empty = createEmptyProducer();
public final void testEmptyCellProducer() {
final CellProducer empty = createEmptyProducer();
final int ary[] = empty.asIndexArray();
assertEquals(0, ary.length);
assertTrue(empty.forEachCount((i, j) -> {
fail("forEachCount consumer should not be called");
assertTrue(empty.forEachCell((i, j) -> {
fail("forEachCell consumer should not be called");
return false;
}));
}

@Test
public final void testIndexConsistency() {
final BitCountProducer producer = createProducer();
final CellProducer producer = createProducer();
final BitSet bs1 = new BitSet();
final BitSet bs2 = new BitSet();
producer.forEachIndex(i -> {
bs1.set(i);
return true;
});
producer.forEachCount((i, j) -> {
producer.forEachCell((i, j) -> {
bs2.set(i);
return true;
});
assertEquals(bs1, bs2);
}

@Test
public void testForEachCountValues() {
// Assumes the collections bag works. Could be replaced with Map<Integer,Integer> with more work.
final TreeBag<Integer> expected = new TreeBag<>();
Arrays.stream(getExpectedBitCount()).forEach(c -> expected.add(c[0], c[1]));
final TreeBag<Integer> actual = new TreeBag<>();
// can not return actual.add as it returns false on duplicate 'i'
createProducer().forEachCount((i, j) -> {
actual.add(i, j);
public void testForEachCellValues() {
int[] expectedIdx = getExpectedIndices();
int[] expectedValue = getExpectedValues();
assertEquals( expectedIdx.length, expectedValue.length, "expected index length and value length do not match");
int[] idx = {0};
createProducer().forEachCell((i, j) -> {
assertEquals(expectedIdx[idx[0]], i, "bad index at "+idx[0]);
assertEquals(expectedValue[idx[0]], j, "bad value at "+idx[0]);
idx[0]++;
return true;
});
assertEquals(expected, actual);
}

/**
* Test the behavior of {@link BitCountProducer#forEachCount(BitCountConsumer)} with respect
* Test the behavior of {@link CellProducer#forEachCell(CellConsumer)} with respect
* to ordered and distinct indices. Currently the behavior is assumed to be the same as
* {@link IndexProducer#forEachIndex(java.util.function.IntPredicate)}.
*/
@Test
public final void testBehaviourForEachCount() {
final int flags = getForEachCountBehaviour();
assumeTrue((flags & (ORDERED | DISTINCT)) != 0);
public final void testBehaviourForEachCell() {
final IntList list = new IntList();
createProducer().forEachCount((i, j) -> list.add(i));
createProducer().forEachCell((i, j) -> list.add(i));
final int[] actual = list.toArray();
if ((flags & ORDERED) != 0) {
final int[] expected = Arrays.stream(actual).sorted().toArray();
assertArrayEquals(expected, actual);
}
if ((flags & DISTINCT) != 0) {
final long count = Arrays.stream(actual).distinct().count();
assertEquals(count, actual.length);
}
// check order
final int[] expected = Arrays.stream(actual).sorted().toArray();
assertArrayEquals(expected, actual);
// check distinct
final long count = Arrays.stream(actual).distinct().count();
assertEquals(count, actual.length);
}

@Test
public void testForEachCountEarlyExit() {
public void testForEachCellEarlyExit() {
final int[] passes = new int[1];
assertTrue(createEmptyProducer().forEachCount((i, j) -> {
assertTrue(createEmptyProducer().forEachCell((i, j) -> {
passes[0]++;
return false;
}));
assertEquals(0, passes[0]);

assertFalse(createProducer().forEachCount((i, j) -> {
assertFalse(createProducer().forEachCell((i, j) -> {
passes[0]++;
return false;
}));
assertEquals(1, passes[0]);
}
}

0 comments on commit 8c0c182

Please sign in to comment.