Skip to content

Commit

Permalink
Add unit-tests for IntMap implementations
Browse files Browse the repository at this point in the history
  • Loading branch information
sarveswaran-m committed Oct 13, 2023
1 parent db5add1 commit 10c0452
Show file tree
Hide file tree
Showing 8 changed files with 328 additions and 29 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package com.trivago.fastutilconcurrentwrapper;

import com.trivago.fastutilconcurrentwrapper.map.ConcurrentBusyWaitingLongIntMap;
import com.trivago.fastutilconcurrentwrapper.map.ConcurrentBusyWaitingLongLongMap;
import com.trivago.fastutilconcurrentwrapper.map.ConcurrentLongIntMap;
import com.trivago.fastutilconcurrentwrapper.map.ConcurrentLongLongMap;

public final class ConcurrentLongIntMapBuilder {
private MapMode mapMode = MapMode.BLOCKING;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.trivago.fastutilconcurrentwrapper;

import it.unimi.dsi.fastutil.ints.Int2LongFunction;
import it.unimi.dsi.fastutil.longs.Long2IntFunction;

import java.util.function.BiFunction;
Expand All @@ -11,7 +10,7 @@ public interface LongIntMap extends PrimitiveLongKeyMap {

/**
* @param key key to get
* @return 0 if the key is not present
* @return configured LongIntMap.getDefaultValue(), if the key is not present
*/
int get(long key);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.trivago.fastutilconcurrentwrapper;

import org.junit.jupiter.api.Test;

import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;

public abstract class AbstractMapTest {
protected final Random random = ThreadLocalRandom.current();

@Test
protected abstract void containsKeyReturnsFalseIfMapIsEmpty();

@Test
protected abstract void containsKeyReturnsTrueIfKeyExists();

@Test
protected abstract void containsKeyReturnsFalseIfKeyWasRemoved();

@Test
protected abstract void mapIsEmptyWhenNothingWasInserted();

@Test
protected abstract void mapIsEmptyWhenAllKeysAreDeleted();

@Test
protected abstract void sizeIsCorrect();

@Test
protected abstract void gettingExistingValueReturnsCorrectValue();

@Test
protected abstract void gettingNonExistingValueReturnsCorrectValue();

@Test
protected abstract void removingNonExistingKeyReturnsDefaultValue();

@Test
protected abstract void removingExistingKeyReturnsPreviousValue();

@Test
protected abstract void removingWithValueWhenKeyDoesNotExistReturnsFalse();

@Test
protected abstract void removingWithValueWhenValueIsDifferentReturnsFalse();

@Test
protected abstract void removingWithValueWhenValueIsSameReturnsTrue();

@Test
protected abstract void puttingValueIfAbsentReturnsSameValue();

@Test
protected abstract void checkingValueIfNotAbsentReturnsSameValue();

@Test
protected abstract void replacingValueIfPresentReturnsNewValue();

@Test
protected abstract void checkingValueIfNotPresentReturnsDefaultValue();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
package com.trivago.fastutilconcurrentwrapper.longint;

import com.trivago.fastutilconcurrentwrapper.AbstractMapTest;
import com.trivago.fastutilconcurrentwrapper.LongIntMap;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

abstract class AbstractLongIntMapTest extends AbstractMapTest {
private LongIntMap map;
// Keep the default value to easily verify that this value is returned.
protected int defaultValue;
// Some methods return the default value of the underlying Fastutil implementation.
private static final int FASTUTIL_DEFAULT_VALUE = 0;

abstract LongIntMap createMap();

@BeforeEach
void initializeMap() {
defaultValue = random.nextInt();
map = createMap();
}

@Test
protected void containsKeyReturnsFalseIfMapIsEmpty() {
final int key = random.nextInt();

final boolean contains = map.containsKey(key);

assertFalse(contains);
}

@Test
protected void containsKeyReturnsTrueIfKeyExists() {
int key = random.nextInt();
int value = random.nextInt();
map.put(key, value);

final boolean contains = map.containsKey(key);

assertTrue(contains);
}

@Test
protected void containsKeyReturnsFalseIfKeyWasRemoved() {
int key = random.nextInt();
int value = random.nextInt();
map.put(key, value);
map.remove(key);

final boolean contains = map.containsKey(key);

assertFalse(contains);
}

@Test
protected void mapIsEmptyWhenNothingWasInserted() {
final boolean empty = map.isEmpty();

assertTrue(empty);
}

@Test
protected void mapIsEmptyWhenAllKeysAreDeleted() {
int entryCount = (Math.abs(random.nextInt()) % 100) + 1;
int value = random.nextInt();

for (int key = 1; key <= entryCount; key++) {
map.put(key, value);
}
for (int key = 1; key <= entryCount; key++) {
map.remove(key);
}

final boolean empty = map.isEmpty();

assertTrue(empty);
}

@Test
protected void sizeIsCorrect() {
int entries = (Math.abs(random.nextInt()) % 50) + 1;
int value = random.nextInt();

for (int key = 1; key <= entries; key++) {
map.put(key, value);
}

final int size = map.size();

assertEquals(entries, size);
}

@Test
protected void gettingExistingValueReturnsCorrectValue() {
int key = random.nextInt();
int value = random.nextInt();
map.put(key, value);
final int returnedValue = map.get(key);

assertEquals(value, returnedValue);
}

@Test
protected void gettingNonExistingValueReturnsCorrectValue() {
int key = random.nextInt();
final int returnedValue = map.get(key);

assertEquals(defaultValue, returnedValue);
}

@Test
protected void removingNonExistingKeyReturnsDefaultValue() {
int key = random.nextInt();
final int removedValue = map.remove(key);

assertEquals(FASTUTIL_DEFAULT_VALUE, removedValue);
}

@Test
protected void removingExistingKeyReturnsPreviousValue() {
int key = random.nextInt();
int value = random.nextInt();
map.put(key, value);
final int removedValue = map.remove(key);

assertEquals(value, removedValue);
}

@Test
protected void removingWithValueWhenKeyDoesNotExistReturnsFalse() {
int key = random.nextInt();
int value = random.nextInt();
final boolean result = map.remove(key, value);

assertFalse(result);
}

@Test
protected void removingWithValueWhenValueIsDifferentReturnsFalse() {
int key = random.nextInt();
int value = random.nextInt();
map.put(key, value);
final boolean result = map.remove(key, value - 1);

assertFalse(result);
}

@Test
protected void removingWithValueWhenValueIsSameReturnsTrue() {
int key = random.nextInt();
int value = random.nextInt();
map.put(key, value);
final boolean result = map.remove(key, value);

assertTrue(result);
}

@Test
protected void puttingValueIfAbsentReturnsSameValue() {
int key = random.nextInt();
int value = random.nextInt();
map.computeIfAbsent(key, l -> value);

int result = map.get(key);

assertEquals(result, value);
}

@Test
protected void checkingValueIfNotAbsentReturnsSameValue() {
int key = random.nextInt();
int value = random.nextInt();
map.put(key, value);
int returned = map.computeIfAbsent(key, l -> value);

int result = map.get(key);

assertEquals(result, value);
assertEquals(value, returned);
}

@Test
protected void replacingValueIfPresentReturnsNewValue() {
int key = random.nextInt();
int value = random.nextInt();
map.put(key, value);

map.computeIfPresent(key, (aLongKey, anIntValue) -> 2 * anIntValue); // key + old value

int result = map.get(key);

assertEquals(result, 2 * value);
}

@Test
protected void checkingValueIfNotPresentReturnsDefaultValue() {
int key = random.nextInt();
map.computeIfPresent(key, (aLongKey, anIntValue) -> 2 * anIntValue); // key + old value

int result = map.get(key);

assertEquals(result, map.getDefaultValue());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.trivago.fastutilconcurrentwrapper.longint;

import com.trivago.fastutilconcurrentwrapper.LongIntMap;
import com.trivago.fastutilconcurrentwrapper.map.ConcurrentBusyWaitingLongIntMap;

public class ConcurrentBusyWaitingLongIntMapTest extends AbstractLongIntMapTest {

@Override
LongIntMap createMap() {
return new ConcurrentBusyWaitingLongIntMap(16, 16, 0.9F, defaultValue);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.trivago.fastutilconcurrentwrapper.longint;

import com.trivago.fastutilconcurrentwrapper.LongIntMap;
import com.trivago.fastutilconcurrentwrapper.longint.AbstractLongIntMapTest;
import com.trivago.fastutilconcurrentwrapper.map.ConcurrentLongIntMap;


public class ConcurrentPrimitiveLongIntMapTest extends AbstractLongIntMapTest {
@Override
LongIntMap createMap() {
return new ConcurrentLongIntMap(16, 16, 0.9F, defaultValue);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.trivago.fastutilconcurrentwrapper.longint;

import com.trivago.fastutilconcurrentwrapper.LongIntMap;
import com.trivago.fastutilconcurrentwrapper.wrapper.PrimitiveFastutilLongIntWrapper;

public class PrimitiveFastutilLongIntWrapperTest extends AbstractLongIntMapTest {

@Override
LongIntMap createMap() {
return new PrimitiveFastutilLongIntWrapper(5, 0.9F, defaultValue);
}
}
Loading

0 comments on commit 10c0452

Please sign in to comment.