package in.partake.model.dao.access;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import in.partake.base.PartakeException;
import in.partake.base.TimeUtil;
import in.partake.model.IPartakeDAOs;
import in.partake.model.access.DBAccess;
import in.partake.model.access.Transaction;
import in.partake.model.dao.AbstractConnectionTestCaseBase;
import in.partake.model.dao.DAOException;
import in.partake.model.dao.DataIterator;
import in.partake.model.dao.PartakeConnection;
import in.partake.model.dao.access.IAccess;
import in.partake.model.dto.PartakeModel;
import java.util.HashSet;
import java.util.Set;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* Dao のテストケースのベース。
*
* @author shinyak
*
*/
public abstract class AbstractDaoTestCaseBase<DAO extends IAccess<T, PK>, T extends PartakeModel<T>, PK> extends AbstractConnectionTestCaseBase {
protected DAO dao;
// TODO: setUp should take DAO and TestDataProvider.
// setup() should be implemented in each test case.
//
@Before
protected abstract void setup() throws Exception;
protected void setup(final DAO dao) throws Exception {
// remove the current data
TimeUtil.resetCurrentDate();
this.dao = dao;
if (dao == null)
return;
// truncate all data.
new Transaction<T>() {
@Override
protected T doExecute(PartakeConnection con, IPartakeDAOs daos) throws DAOException, PartakeException {
dao.truncate(con);
return null;
}
}.execute();
}
// 同じ (pkNumber, pkSalt) なら同じ結果を返すようにする。
// TODO: We should use TestDataProvider instead.
protected abstract T create(long pkNumber, String pkSalt, int objNumber);
// ------------------------------------------------------------
@Test
public final void testToCreate() {
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
T t1 = create(0, "create", 0);
T t2 = create(i, "create", j);
if (i == 0 && j == 0) {
Assert.assertEquals(t1, t2);
} else {
Assert.assertFalse(t1.equals(t2));
}
if (i == 0) {
Assert.assertEquals(t1.getPrimaryKey(), t2.getPrimaryKey());
} else {
Assert.assertFalse(t1.getPrimaryKey().equals(t2.getPrimaryKey()));
}
}
}
}
@Test
@SuppressWarnings("unchecked")
public final void testToPutFind() throws Exception {
new DBAccess<T>() {
@Override
protected T doExecute(PartakeConnection con, IPartakeDAOs daos) throws DAOException, PartakeException {
con.beginTransaction();
T t1 = create(System.currentTimeMillis(), "putfind", 0);
dao.put(con, t1);
con.commit();
T t2 = dao.find(con, (PK) t1.getPrimaryKey());
Assert.assertEquals(t1, t2);
Assert.assertNotSame(t1, t2);
Assert.assertFalse(t1.isFrozen());
Assert.assertTrue(t2.isFrozen());
return null;
}
}.execute();
}
@Test
@SuppressWarnings("unchecked")
public final void testToPutFindInTransaction() throws Exception {
new DBAccess<T>() {
@Override
protected T doExecute(PartakeConnection con, IPartakeDAOs daos) throws DAOException, PartakeException {
con.beginTransaction();
T t1 = create(System.currentTimeMillis(), "putfindintran", 0);
dao.put(con, t1);
T t2 = dao.find(con, (PK) t1.getPrimaryKey());
con.commit();
Assert.assertEquals(t1, t2);
Assert.assertFalse(t1.isFrozen());
Assert.assertTrue(t2.isFrozen());
return null;
}
}.execute();
}
@Test
@SuppressWarnings("unchecked")
public final void testToPutPutFind() throws Exception {
new DBAccess<T>() {
@Override
protected T doExecute(PartakeConnection con, IPartakeDAOs daos) throws DAOException, PartakeException {
long time = System.currentTimeMillis();
con.beginTransaction();
T t1 = create(time, "putputfind", 0);
dao.put(con, t1);
con.commit();
TimeUtil.waitForTick();
con.beginTransaction();
T t2 = create(time, "putputfind", 1);
dao.put(con, t2);
con.commit();
Assert.assertEquals(t1.getPrimaryKey(), t2.getPrimaryKey());
con.beginTransaction();
T t3 = dao.find(con, (PK) t1.getPrimaryKey());
con.commit();
Assert.assertFalse(t1.equals(t3));
Assert.assertEquals(t2, t3);
return null;
}
}.execute();
}
@Test
@SuppressWarnings("unchecked")
public final void testToPutRemoveFind() throws Exception {
new DBAccess<T>() {
@Override
protected T doExecute(PartakeConnection con, IPartakeDAOs daos) throws DAOException, PartakeException {
TimeUtil.waitForTick();
con.beginTransaction();
T t1 = create(System.currentTimeMillis(), "putremovefind", 0);
dao.put(con, t1);
con.commit();
TimeUtil.waitForTick();
con.beginTransaction();
dao.remove(con, (PK) t1.getPrimaryKey());
con.commit();
T t2 = dao.find(con, (PK) t1.getPrimaryKey());
Assert.assertNull(t2);
return null;
}
}.execute();
}
@Test
@SuppressWarnings("unchecked")
public final void testToPutRemovePutFind() throws Exception {
new DBAccess<T>() {
@Override
protected T doExecute(PartakeConnection con, IPartakeDAOs daos) throws DAOException, PartakeException {
con.beginTransaction();
T t1 = create(System.currentTimeMillis(), "putremovefind", 0);
dao.put(con, t1);
con.commit();
TimeUtil.waitForTick();
con.beginTransaction();
dao.remove(con, (PK) t1.getPrimaryKey());
con.commit();
TimeUtil.waitForTick();
con.beginTransaction();
dao.put(con, t1);
con.commit();
T t2 = dao.find(con, (PK) t1.getPrimaryKey());
Assert.assertEquals(t1, t2);
return null;
}
}.execute();
}
@Test
@SuppressWarnings("unchecked")
public final void testToRemoveInvalidObject() throws Exception {
new DBAccess<T>() {
@Override
protected T doExecute(PartakeConnection con, IPartakeDAOs daos) throws DAOException, PartakeException {
T t1 = create(System.currentTimeMillis(), "removeinvalid", 0);
con.beginTransaction();
dao.remove(con, (PK) t1.getPrimaryKey());
con.commit();
return null;
}
}.execute();
}
@Test
@SuppressWarnings("unchecked")
public final void testToFindWithInvalidId() throws Exception {
new DBAccess<T>() {
@Override
protected T doExecute(PartakeConnection con, IPartakeDAOs daos) throws DAOException, PartakeException {
T t1 = create(System.currentTimeMillis(), "findInvalid", 0);
con.beginTransaction();
T t = dao.find(con, (PK) t1.getPrimaryKey());
con.commit();
Assert.assertNull(t);
return null;
}
}.execute();
}
@Test
public final void testToIterate() throws Exception {
new DBAccess<T>() {
@Override
protected T doExecute(PartakeConnection con, IPartakeDAOs daos) throws DAOException, PartakeException {
Set<T> created = new HashSet<T>();
for (int i = 0; i < 3; ++i) {
T t = create(System.currentTimeMillis(), String.valueOf(i), i);
created.add(t);
con.beginTransaction();
dao.put(con, t);
con.commit();
}
int count = 0;
DataIterator<T> it = dao.getIterator(con);
try {
while (it.hasNext()) {
T t = it.next();
if (t == null) { continue; }
++count;
Assert.assertTrue(created.contains(t));
}
} finally {
it.close();
}
Assert.assertEquals(3, count);
return null;
}
}.execute();
}
@Test
public final void testToCount() throws Exception {
new DBAccess<T>() {
@Override
protected T doExecute(PartakeConnection con, IPartakeDAOs daos) throws DAOException, PartakeException {
Set<T> created = new HashSet<T>();
for (int i = 0; i < 10; ++i) {
T t = create(System.currentTimeMillis(), String.valueOf(i), i);
created.add(t);
con.beginTransaction();
dao.put(con, t);
con.commit();
}
assertThat(dao.count(con), is(10));
return null;
}
}.execute();
}
@Test
@SuppressWarnings("unchecked")
public final void testToExist() throws Exception {
new DBAccess<T>() {
@Override
protected T doExecute(PartakeConnection con, IPartakeDAOs daos) throws DAOException, PartakeException {
T t1 = create(System.currentTimeMillis(), "exist", 0);
T t2 = create(System.currentTimeMillis(), "not-exist", 0);
con.beginTransaction();
dao.put(con, t1);
con.commit();
assertThat(dao.exists(con, (PK) t1.getPrimaryKey()), is(true));
assertThat(dao.exists(con, (PK) t2.getPrimaryKey()), is(false));
return null;
}
}.execute();
}
}