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); } } }