package liquibase.change;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.TreeSet;
import liquibase.change.core.AddAutoIncrementChange;
import liquibase.change.core.CreateTableChange;
import liquibase.change.core.DropTableChange;
import liquibase.database.core.MSSQLDatabase;
import liquibase.exception.DatabaseException;
import liquibase.exception.UnexpectedLiquibaseException;
import liquibase.servicelocator.LiquibaseService;
import liquibase.sqlgenerator.SqlGeneratorFactory;
import liquibase.statement.core.CreateSequenceStatement;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class ChangeFactoryTest {
@Before
public void setup() {
ChangeFactory.reset();
SometimesExceptionThrowingChange.timesCalled = 0;
}
@After
public void resetRegistry() {
ChangeFactory.reset();
}
@Test
public void supportStatement() throws Exception {
CreateSequenceStatement statement = new CreateSequenceStatement(null, null, "seq_my_table");
MSSQLDatabase database10 = new MSSQLDatabase() {
@Override
public int getDatabaseMajorVersion() throws DatabaseException {
return 10;
}
};
MSSQLDatabase database11 = new MSSQLDatabase() {
@Override
public int getDatabaseMajorVersion() throws DatabaseException {
return 11;
}
};
ChangeFactory.getInstance(); //make sure there is no problem with SqlGeneratorFactory.generatorsByKey cache
assertFalse("unsupported create sequence", SqlGeneratorFactory.getInstance().supports(statement, database10));
assertTrue("supported create sequence", SqlGeneratorFactory.getInstance().supports(statement, database11));
}
@Test
public void constructor() {
ChangeFactory instance = ChangeFactory.getInstance();
assertTrue(instance.getRegistry().containsKey("createTable"));
assertTrue(instance.getRegistry().containsKey("dropTable"));
}
@Test
public void getInstance() {
assertNotNull(ChangeFactory.getInstance());
assertTrue(ChangeFactory.getInstance() == ChangeFactory.getInstance());
}
@Test
public void reset() {
ChangeFactory instance1 = ChangeFactory.getInstance();
ChangeFactory.reset();
assertFalse(instance1 == ChangeFactory.getInstance());
}
@Test
public void clear() {
ChangeFactory changeFactory = ChangeFactory.getInstance();
assertTrue(changeFactory.getRegistry().size() > 5);
changeFactory.clear();
assertEquals(0, changeFactory.getRegistry().size());
}
@Test
public void register() {
ChangeFactory changeFactory = ChangeFactory.getInstance();
changeFactory.clear();
assertEquals(0, changeFactory.getRegistry().size());
changeFactory.register(CreateTableChange.class);
assertEquals(1, changeFactory.getRegistry().size());
assertTrue(changeFactory.getRegistry().containsKey("createTable"));
changeFactory.register(Priority10Change.class);
changeFactory.register(Priority5Change.class);
changeFactory.register(AnotherPriority5Change.class); //only one should be stored
assertEquals(3, changeFactory.getRegistry().get("createTable").size());
assertEquals(Priority10Change.class, changeFactory.getRegistry().get("createTable").iterator().next());
}
@Test(expected = UnexpectedLiquibaseException.class)
public void register_badClassRightAway() {
ChangeFactory changeFactory = ChangeFactory.getInstance();
changeFactory.register(ExceptionThrowingChange.class);
}
@Test(expected = UnexpectedLiquibaseException.class)
public void register_badClassLaterInComparator() {
ChangeFactory changeFactory = ChangeFactory.getInstance();
changeFactory.register(SometimesExceptionThrowingChange.class);
changeFactory.register(Priority5Change.class);
changeFactory.register(Priority10Change.class);
}
@Test
public void unregister_instance() {
ChangeFactory factory = ChangeFactory.getInstance();
factory.clear();
assertEquals(0, factory.getRegistry().size());
AddAutoIncrementChange change = new AddAutoIncrementChange();
factory.register(CreateTableChange.class);
factory.register(change.getClass());
factory.register(DropTableChange.class);
assertEquals(3, factory.getRegistry().size());
factory.unregister(ChangeFactory.getInstance().getChangeMetaData(change).getName());
assertEquals(2, factory.getRegistry().size());
}
@Test
public void unregister_doesNotExist() {
ChangeFactory factory = ChangeFactory.getInstance();
factory.clear();
assertEquals(0, factory.getRegistry().size());
factory.register(CreateTableChange.class);
factory.register(AddAutoIncrementChange.class);
factory.register(DropTableChange.class);
assertEquals(3, factory.getRegistry().size());
factory.unregister("doesNoExist");
assertEquals(3, factory.getRegistry().size());
}
@Test(expected = UnsupportedOperationException.class)
public void getRegistry() {
ChangeFactory.getInstance().getRegistry().put("x", new TreeSet<Class<? extends Change>>());
}
@Test
public void create_exists() {
Change change = ChangeFactory.getInstance().create("createTable");
assertNotNull(change);
assertTrue(change instanceof CreateTableChange);
assertNotSame(change, ChangeFactory.getInstance().create("createTable"));
}
@Test
public void create_notExists() {
Change change = ChangeFactory.getInstance().create("badChangeName");
assertNull(change);
}
@Test(expected = UnexpectedLiquibaseException.class)
public void create_badClass() {
ChangeFactory.getInstance().register(SometimesExceptionThrowingChange.class);
Change change = ChangeFactory.getInstance().create("createTable");
assertNotNull(change);
assertTrue(change instanceof CreateTableChange);
}
@LiquibaseService(skip = true)
public static class Priority5Change extends CreateTableChange {
@Override
public ChangeMetaData createChangeMetaData() {
return new ChangeMetaData("createTable", null, 5, null, null, null);
}
}
@LiquibaseService(skip = true)
public static class Priority10Change extends CreateTableChange {
@Override
public ChangeMetaData createChangeMetaData() {
return new ChangeMetaData("createTable", null, 10, null, null, null);
}
}
@LiquibaseService(skip = true)
public static class AnotherPriority5Change extends CreateTableChange {
@Override
public ChangeMetaData createChangeMetaData() {
return new ChangeMetaData("createTable", null, 5, null, null, null);
}
}
@LiquibaseService(skip = true)
public static class ExceptionThrowingChange extends CreateTableChange {
public ExceptionThrowingChange() {
throw new RuntimeException("I throw exceptions");
}
@Override
public ChangeMetaData createChangeMetaData() {
return new ChangeMetaData("createTable", null, 15, null, null, null);
}
}
@LiquibaseService(skip = true)
public static class SometimesExceptionThrowingChange extends CreateTableChange {
private static int timesCalled = 0;
public SometimesExceptionThrowingChange() {
if (timesCalled > 1) {
throw new RuntimeException("I throw exceptions");
}
timesCalled++;
}
@Override
public ChangeMetaData createChangeMetaData() {
return new ChangeMetaData("createTable", null, 15, null, null, null);
}
}
}