package com.nicewuerfel.blockown.database;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.anyMap;
import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.google.common.base.Optional;
import com.nicewuerfel.blockown.Material;
import com.nicewuerfel.blockown.Ownable;
import com.nicewuerfel.blockown.OwnedBlock;
import com.nicewuerfel.blockown.OwnedEntity;
import com.nicewuerfel.blockown.User;
import com.nicewuerfel.blockown.output.Output;
import org.bukkit.World;
import org.bukkit.entity.EntityType;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.ArgumentMatcher;
import java.io.File;
import java.util.UUID;
public class TestCache {
private static final int USER_COUNT = 10;
private static final int BLOCK_COUNT = USER_COUNT * 2;
private static World testWorld;
private static Output output;
private static CacheAccessor cache;
private static CachedDatabase db;
private static User[] testUsers;
private static OwnedBlock[] testBlocks;
private static OwnedEntity[] testEntities;
@SuppressWarnings("unchecked")
@BeforeClass
public static void init() {
output = new TestOutput();
db = mock(CachedDatabase.class);
when(db.getOutput()).thenReturn(output);
when(db.flushDatabase(anyMap())).thenReturn(false);
when(db.getDatabaseOwner(argThat(new IsOwnable()))).thenReturn(Optional.<User>absent());
cache = new CacheAccessor(db, new File(""));
testWorld = mock(World.class);
when(testWorld.getName()).thenReturn("testWorld");
createTestUsers();
createTestBlocks();
createTestEntites();
}
private static void createTestUsers() {
testUsers = new User[USER_COUNT];
for (int i = 0; i < USER_COUNT; i++) {
testUsers[i] = User.getInstance(UUID.randomUUID());
}
}
private static void createTestBlocks() {
testBlocks = new OwnedBlock[BLOCK_COUNT];
for (int i = 0; i < BLOCK_COUNT; i++) {
OwnedBlock block = OwnedBlock.newInstance(testWorld.getName(), i, i, i, Material.ANY);
testBlocks[i] = block;
}
}
private static void createTestEntites() {
testEntities = new OwnedEntity[BLOCK_COUNT];
for (int i = 0; i < BLOCK_COUNT; i++) {
OwnedEntity entity = OwnedEntity.newInstance(UUID.randomUUID(), testWorld.getName(),
new Material(EntityType.BOAT));
testEntities[i] = entity;
}
}
@Before
public void ownHalfOfBlocks() {
for (int i = 0; i < USER_COUNT; i++) {
cache.doAction(DatabaseAction.newOwnInstance(testEntities[i], testUsers[i]));
cache.doAction(DatabaseAction.newOwnInstance(testBlocks[i], testUsers[i]));
}
}
@After
public void dropAllUsers() {
for (User user : testUsers) {
cache.doAction(DatabaseAction.newDropInstance(user));
}
}
@Rule
public ExpectedException expected = ExpectedException.none();
@Test
public void checkOwners() {
int i = 1;
while (i < USER_COUNT) {
assertEquals(testUsers[i], cache.getOwner(testBlocks[i]).get());
assertEquals(testUsers[i], cache.getOwner(testEntities[i]).get());
i++;
}
while (i < BLOCK_COUNT) {
assertFalse(cache.getOwner(testBlocks[i]).isPresent());
assertFalse(cache.getOwner(testEntities[i]).isPresent());
i++;
}
}
@Test
public void testOwn() {
int i = USER_COUNT;
while (i < BLOCK_COUNT) {
cache.doAction(DatabaseAction.newOwnInstance(testBlocks[i], testUsers[i - USER_COUNT]));
cache.doAction(DatabaseAction.newOwnInstance(testEntities[i], testUsers[i - USER_COUNT]));
i++;
}
i = USER_COUNT;
while (i < BLOCK_COUNT) {
assertEquals(testUsers[i - USER_COUNT], cache.getOwner(testBlocks[i]).get());
assertEquals(testUsers[i - USER_COUNT], cache.getOwner(testEntities[i]).get());
i++;
}
}
@Test
public void testUnown() {
cache.doAction(DatabaseAction.newUnownInstance(testBlocks[0]));
cache.doAction(DatabaseAction.newUnownInstance(testEntities[0]));
assertFalse(cache.getOwner(testBlocks[0]).isPresent());
assertFalse(cache.getOwner(testEntities[0]).isPresent());
}
@AfterClass
public static void cleanUp() {
File dumpFile = new File("dumpFile.dat");
assertTrue(!dumpFile.exists() || dumpFile.delete());
}
}
class IsOwnable extends ArgumentMatcher<Ownable> {
@Override
public boolean matches(Object argument) {
return argument instanceof Ownable;
}
}