diff options
author | Artur Signell <artur@vaadin.com> | 2016-08-18 21:58:46 +0300 |
---|---|---|
committer | Artur Signell <artur@vaadin.com> | 2016-08-20 00:08:47 +0300 |
commit | 65370e12a0605926cb80e205c2b0e74fefe83e5b (patch) | |
tree | 013b7a60741db3c902bb1a8ea29733aa117bd0b2 /compatibility-server/src/test | |
parent | 34852cdb88c6c27b1341684204d78db0fdd061a6 (diff) | |
download | vaadin-framework-65370e12a0605926cb80e205c2b0e74fefe83e5b.tar.gz vaadin-framework-65370e12a0605926cb80e205c2b0e74fefe83e5b.zip |
Move Table/TreeTable to compatibility package
Change-Id: Ic9f2badf8688c32d704be67519c0f4c9a3da0e28
Diffstat (limited to 'compatibility-server/src/test')
42 files changed, 9810 insertions, 0 deletions
diff --git a/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/AllTests.java b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/AllTests.java new file mode 100644 index 0000000000..9c3f6c0eaa --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/AllTests.java @@ -0,0 +1,24 @@ +package com.vaadin.data.util.sqlcontainer; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +import com.vaadin.data.util.sqlcontainer.connection.J2EEConnectionPoolTest; +import com.vaadin.data.util.sqlcontainer.connection.SimpleJDBCConnectionPoolTest; +import com.vaadin.data.util.sqlcontainer.filters.BetweenTest; +import com.vaadin.data.util.sqlcontainer.filters.LikeTest; +import com.vaadin.data.util.sqlcontainer.generator.SQLGeneratorsTest; +import com.vaadin.data.util.sqlcontainer.query.FreeformQueryTest; +import com.vaadin.data.util.sqlcontainer.query.QueryBuilderTest; +import com.vaadin.data.util.sqlcontainer.query.TableQueryTest; + +@RunWith(Suite.class) +@SuiteClasses({ SimpleJDBCConnectionPoolTest.class, + J2EEConnectionPoolTest.class, LikeTest.class, QueryBuilderTest.class, + FreeformQueryTest.class, RowIdTest.class, SQLContainerTest.class, + SQLContainerTableQueryTest.class, ColumnPropertyTest.class, + TableQueryTest.class, SQLGeneratorsTest.class, UtilTest.class, + TicketTest.class, BetweenTest.class, ReadOnlyRowIdTest.class }) +public class AllTests { +} diff --git a/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/ColumnPropertyTest.java b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/ColumnPropertyTest.java new file mode 100644 index 0000000000..edc56035e1 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/ColumnPropertyTest.java @@ -0,0 +1,318 @@ +package com.vaadin.data.util.sqlcontainer; + +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Arrays; + +import org.easymock.EasyMock; +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.data.Property.ReadOnlyException; +import com.vaadin.data.util.sqlcontainer.ColumnProperty.NotNullableException; +import com.vaadin.data.util.sqlcontainer.query.QueryDelegate; + +public class ColumnPropertyTest { + + @Test + public void constructor_legalParameters_shouldSucceed() { + ColumnProperty cp = new ColumnProperty("NAME", false, true, true, false, + "Ville", String.class); + Assert.assertNotNull(cp); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor_missingPropertyId_shouldFail() { + new ColumnProperty(null, false, true, true, false, "Ville", + String.class); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor_missingType_shouldFail() { + new ColumnProperty("NAME", false, true, true, false, "Ville", null); + } + + @Test + public void getValue_defaultValue_returnsVille() { + ColumnProperty cp = new ColumnProperty("NAME", false, true, true, false, + "Ville", String.class); + Assert.assertEquals("Ville", cp.getValue()); + } + + @Test + public void setValue_readWriteNullable_returnsKalle() { + ColumnProperty cp = new ColumnProperty("NAME", false, true, true, false, + "Ville", String.class); + SQLContainer container = EasyMock.createMock(SQLContainer.class); + RowItem owner = new RowItem(container, new RowId(new Object[] { 1 }), + Arrays.asList(cp)); + container.itemChangeNotification(owner); + EasyMock.replay(container); + cp.setValue("Kalle"); + Assert.assertEquals("Kalle", cp.getValue()); + EasyMock.verify(container); + } + + @Test(expected = ReadOnlyException.class) + public void setValue_readOnlyNullable_shouldFail() { + ColumnProperty cp = new ColumnProperty("NAME", true, true, true, false, + "Ville", String.class); + SQLContainer container = EasyMock.createMock(SQLContainer.class); + new RowItem(container, new RowId(new Object[] { 1 }), + Arrays.asList(cp)); + EasyMock.replay(container); + cp.setValue("Kalle"); + EasyMock.verify(container); + } + + @Test + public void setValue_readWriteNullable_nullShouldWork() { + ColumnProperty cp = new ColumnProperty("NAME", false, true, true, false, + "Ville", String.class); + SQLContainer container = EasyMock.createMock(SQLContainer.class); + RowItem owner = new RowItem(container, new RowId(new Object[] { 1 }), + Arrays.asList(cp)); + container.itemChangeNotification(owner); + EasyMock.replay(container); + cp.setValue(null); + Assert.assertNull(cp.getValue()); + EasyMock.verify(container); + } + + @Test(expected = NotNullableException.class) + public void setValue_readWriteNotNullable_nullShouldFail() { + ColumnProperty cp = new ColumnProperty("NAME", false, true, false, + false, "Ville", String.class); + SQLContainer container = EasyMock.createMock(SQLContainer.class); + RowItem owner = new RowItem(container, new RowId(new Object[] { 1 }), + Arrays.asList(cp)); + container.itemChangeNotification(owner); + EasyMock.replay(container); + cp.setValue(null); + Assert.assertNotNull(cp.getValue()); + EasyMock.verify(container); + } + + @Test + public void getType_normal_returnsStringClass() { + ColumnProperty cp = new ColumnProperty("NAME", false, true, true, false, + "Ville", String.class); + Assert.assertSame(String.class, cp.getType()); + } + + @Test + public void isReadOnly_readWriteNullable_returnsTrue() { + ColumnProperty cp = new ColumnProperty("NAME", false, true, true, false, + "Ville", String.class); + Assert.assertFalse(cp.isReadOnly()); + } + + @Test + public void isReadOnly_readOnlyNullable_returnsTrue() { + ColumnProperty cp = new ColumnProperty("NAME", true, true, true, false, + "Ville", String.class); + Assert.assertTrue(cp.isReadOnly()); + } + + @Test + public void setReadOnly_readOnlyChangeAllowed_shouldSucceed() { + ColumnProperty cp = new ColumnProperty("NAME", false, true, true, false, + "Ville", String.class); + cp.setReadOnly(true); + Assert.assertTrue(cp.isReadOnly()); + } + + @Test + public void setReadOnly_readOnlyChangeDisallowed_shouldFail() { + ColumnProperty cp = new ColumnProperty("NAME", false, false, true, + false, "Ville", String.class); + cp.setReadOnly(true); + Assert.assertFalse(cp.isReadOnly()); + } + + @Test + public void getPropertyId_normal_returnsNAME() { + ColumnProperty cp = new ColumnProperty("NAME", false, false, true, + false, "Ville", String.class); + Assert.assertEquals("NAME", cp.getPropertyId()); + } + + @Test + public void isModified_valueModified_returnsTrue() { + ColumnProperty cp = new ColumnProperty("NAME", false, true, true, false, + "Ville", String.class); + SQLContainer container = EasyMock.createMock(SQLContainer.class); + RowItem owner = new RowItem(container, new RowId(new Object[] { 1 }), + Arrays.asList(cp)); + container.itemChangeNotification(owner); + EasyMock.replay(container); + cp.setValue("Kalle"); + Assert.assertEquals("Kalle", cp.getValue()); + Assert.assertTrue(cp.isModified()); + EasyMock.verify(container); + } + + @Test + public void isModified_valueNotModified_returnsFalse() { + ColumnProperty cp = new ColumnProperty("NAME", false, false, true, + false, "Ville", String.class); + Assert.assertFalse(cp.isModified()); + } + + @Test + public void setValue_nullOnNullable_shouldWork() { + ColumnProperty cp = new ColumnProperty("NAME", false, true, true, false, + "asdf", String.class); + SQLContainer container = EasyMock.createMock(SQLContainer.class); + new RowItem(container, new RowId(new Object[] { 1 }), + Arrays.asList(cp)); + cp.setValue(null); + Assert.assertNull(cp.getValue()); + } + + @Test + public void setValue_resetTonullOnNullable_shouldWork() { + ColumnProperty cp = new ColumnProperty("NAME", false, true, true, false, + null, String.class); + SQLContainer container = EasyMock.createMock(SQLContainer.class); + new RowItem(container, new RowId(new Object[] { 1 }), + Arrays.asList(cp)); + cp.setValue("asdf"); + Assert.assertEquals("asdf", cp.getValue()); + cp.setValue(null); + Assert.assertNull(cp.getValue()); + } + + @Test + public void setValue_sendsItemChangeNotification() throws SQLException { + + class TestContainer extends SQLContainer { + Object value = null; + boolean modified = false; + + public TestContainer(QueryDelegate delegate) throws SQLException { + super(delegate); + } + + @Override + public void itemChangeNotification(RowItem changedItem) { + ColumnProperty cp = (ColumnProperty) changedItem + .getItemProperty("NAME"); + value = cp.getValue(); + modified = cp.isModified(); + } + } + + ColumnProperty property = new ColumnProperty("NAME", false, true, true, + false, "Ville", String.class); + + Statement statement = EasyMock.createNiceMock(Statement.class); + EasyMock.replay(statement); + + ResultSetMetaData metadata = EasyMock + .createNiceMock(ResultSetMetaData.class); + EasyMock.replay(metadata); + + ResultSet resultSet = EasyMock.createNiceMock(ResultSet.class); + EasyMock.expect(resultSet.getStatement()).andReturn(statement); + EasyMock.expect(resultSet.getMetaData()).andReturn(metadata); + EasyMock.replay(resultSet); + + QueryDelegate delegate = EasyMock.createNiceMock(QueryDelegate.class); + EasyMock.expect(delegate.getResults(0, 1)).andReturn(resultSet); + EasyMock.replay(delegate); + + TestContainer container = new TestContainer(delegate); + + new RowItem(container, new RowId(new Object[] { 1 }), + Arrays.asList(property)); + + property.setValue("Kalle"); + Assert.assertEquals("Kalle", container.value); + Assert.assertTrue(container.modified); + } + + @Test + public void versionColumnsShouldNotBeInValueMap_shouldReturnFalse() { + ColumnProperty property = new ColumnProperty("NAME", false, true, true, + false, "Ville", String.class); + property.setVersionColumn(true); + + Assert.assertFalse(property.isPersistent()); + } + + @Test + public void neverWritableColumnsShouldNotBeInValueMap_shouldReturnFalse() { + ColumnProperty property = new ColumnProperty("NAME", true, false, true, + false, "Ville", String.class); + + Assert.assertFalse(property.isPersistent()); + } + + @Test + public void writableColumnsShouldBeInValueMap_shouldReturnTrue() { + ColumnProperty property = new ColumnProperty("NAME", false, true, true, + false, "Ville", String.class); + + Assert.assertTrue(property.isPersistent()); + } + + @Test + public void writableButReadOnlyColumnsShouldNotBeInValueMap_shouldReturnFalse() { + ColumnProperty property = new ColumnProperty("NAME", true, true, true, + false, "Ville", String.class); + + Assert.assertFalse(property.isPersistent()); + } + + @Test + public void primKeysShouldBeRowIdentifiers_shouldReturnTrue() { + ColumnProperty property = new ColumnProperty("NAME", false, true, true, + true, "Ville", String.class); + + Assert.assertTrue(property.isRowIdentifier()); + } + + @Test + public void versionColumnsShouldBeRowIdentifiers_shouldReturnTrue() { + ColumnProperty property = new ColumnProperty("NAME", false, true, true, + false, "Ville", String.class); + property.setVersionColumn(true); + + Assert.assertTrue(property.isRowIdentifier()); + } + + @Test + public void nonPrimKeyOrVersionColumnsShouldBeNotRowIdentifiers_shouldReturnFalse() { + ColumnProperty property = new ColumnProperty("NAME", false, true, true, + false, "Ville", String.class); + + Assert.assertFalse(property.isRowIdentifier()); + } + + @Test + public void getOldValueShouldReturnPreviousValue_shouldReturnVille() { + ColumnProperty property = new ColumnProperty("NAME", false, true, true, + false, "Ville", String.class); + + // Here we really don't care about the container management, but in + // order to set the value for a column the owner (RowItem) must be set + // and to create the owner we must have a container... + ArrayList<ColumnProperty> properties = new ArrayList<ColumnProperty>(); + properties.add(property); + + SQLContainer container = EasyMock.createNiceMock(SQLContainer.class); + RowItem rowItem = new RowItem(container, new RowId(new Object[] { 1 }), + Arrays.asList(property)); + + property.setValue("Kalle"); + // Just check that the new value was actually set... + Assert.assertEquals("Kalle", property.getValue()); + // Assert that old value is the original value... + Assert.assertEquals("Ville", property.getOldValue()); + } + +} diff --git a/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/DataGenerator.java b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/DataGenerator.java new file mode 100644 index 0000000000..8ce298c065 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/DataGenerator.java @@ -0,0 +1,133 @@ +package com.vaadin.data.util.sqlcontainer; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.data.util.sqlcontainer.SQLTestsConstants.DB; +import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool; + +public class DataGenerator { + + public static void addPeopleToDatabase(JDBCConnectionPool connectionPool) + throws SQLException { + Connection conn = connectionPool.reserveConnection(); + Statement statement = conn.createStatement(); + try { + statement.execute("drop table PEOPLE"); + if (SQLTestsConstants.db == DB.ORACLE) { + statement.execute("drop sequence people_seq"); + } + } catch (SQLException e) { + // Will fail if table doesn't exist, which is OK. + conn.rollback(); + } + statement.execute(SQLTestsConstants.peopleFirst); + if (SQLTestsConstants.peopleSecond != null) { + statement.execute(SQLTestsConstants.peopleSecond); + } + if (SQLTestsConstants.db == DB.ORACLE) { + statement.execute(SQLTestsConstants.peopleThird); + } + if (SQLTestsConstants.db == DB.MSSQL) { + statement.executeUpdate("insert into people values('Ville', '23')"); + statement.executeUpdate("insert into people values('Kalle', '7')"); + statement.executeUpdate("insert into people values('Pelle', '18')"); + statement.executeUpdate("insert into people values('Börje', '64')"); + } else { + statement.executeUpdate( + "insert into people values(default, 'Ville', '23')"); + statement.executeUpdate( + "insert into people values(default, 'Kalle', '7')"); + statement.executeUpdate( + "insert into people values(default, 'Pelle', '18')"); + statement.executeUpdate( + "insert into people values(default, 'Börje', '64')"); + } + statement.close(); + statement = conn.createStatement(); + ResultSet rs = statement.executeQuery("select * from PEOPLE"); + Assert.assertTrue(rs.next()); + statement.close(); + conn.commit(); + connectionPool.releaseConnection(conn); + } + + public static void addFiveThousandPeople(JDBCConnectionPool connectionPool) + throws SQLException { + Connection conn = connectionPool.reserveConnection(); + Statement statement = conn.createStatement(); + for (int i = 4; i < 5000; i++) { + if (SQLTestsConstants.db == DB.MSSQL) { + statement.executeUpdate("insert into people values('Person " + i + + "', '" + i % 99 + "')"); + } else { + statement.executeUpdate( + "insert into people values(default, 'Person " + i + + "', '" + i % 99 + "')"); + } + } + statement.close(); + conn.commit(); + connectionPool.releaseConnection(conn); + } + + public static void addVersionedData(JDBCConnectionPool connectionPool) + throws SQLException { + Connection conn = connectionPool.reserveConnection(); + Statement statement = conn.createStatement(); + try { + statement.execute("DROP TABLE VERSIONED"); + if (SQLTestsConstants.db == DB.ORACLE) { + statement.execute("drop sequence versioned_seq"); + statement.execute("drop sequence versioned_version"); + } + } catch (SQLException e) { + // Will fail if table doesn't exist, which is OK. + conn.rollback(); + } + for (String stmtString : SQLTestsConstants.versionStatements) { + statement.execute(stmtString); + } + if (SQLTestsConstants.db == DB.MSSQL) { + statement.executeUpdate( + "insert into VERSIONED values('Junk', default)"); + } else { + statement.executeUpdate( + "insert into VERSIONED values(default, 'Junk', default)"); + } + statement.close(); + statement = conn.createStatement(); + ResultSet rs = statement.executeQuery("select * from VERSIONED"); + Assert.assertTrue(rs.next()); + statement.close(); + conn.commit(); + connectionPool.releaseConnection(conn); + } + + public static void createGarbage(JDBCConnectionPool connectionPool) + throws SQLException { + Connection conn = connectionPool.reserveConnection(); + Statement statement = conn.createStatement(); + try { + statement.execute("drop table GARBAGE"); + if (SQLTestsConstants.db == DB.ORACLE) { + statement.execute("drop sequence garbage_seq"); + } + } catch (SQLException e) { + // Will fail if table doesn't exist, which is OK. + conn.rollback(); + } + statement.execute(SQLTestsConstants.createGarbage); + if (SQLTestsConstants.db == DB.ORACLE) { + statement.execute(SQLTestsConstants.createGarbageSecond); + statement.execute(SQLTestsConstants.createGarbageThird); + } + conn.commit(); + connectionPool.releaseConnection(conn); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/FreeformQueryUtil.java b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/FreeformQueryUtil.java new file mode 100644 index 0000000000..8688c9ae64 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/FreeformQueryUtil.java @@ -0,0 +1,68 @@ +package com.vaadin.data.util.sqlcontainer; + +import java.util.List; + +import org.junit.Test; + +import com.vaadin.data.Container.Filter; +import com.vaadin.data.util.sqlcontainer.SQLTestsConstants.DB; +import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; +import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder; + +public class FreeformQueryUtil { + + public static StatementHelper getQueryWithFilters(List<Filter> filters, + int offset, int limit) { + StatementHelper sh = new StatementHelper(); + if (SQLTestsConstants.db == DB.MSSQL) { + if (limit > 1) { + offset++; + limit--; + } + StringBuilder query = new StringBuilder(); + query.append("SELECT * FROM (SELECT row_number() OVER ("); + query.append("ORDER BY \"ID\" ASC"); + query.append(") AS rownum, * FROM \"PEOPLE\""); + + if (!filters.isEmpty()) { + query.append( + QueryBuilder.getWhereStringForFilters(filters, sh)); + } + query.append(") AS a WHERE a.rownum BETWEEN ").append(offset) + .append(" AND ").append(Integer.toString(offset + limit)); + sh.setQueryString(query.toString()); + return sh; + } else if (SQLTestsConstants.db == DB.ORACLE) { + if (limit > 1) { + offset++; + limit--; + } + StringBuilder query = new StringBuilder(); + query.append("SELECT * FROM (SELECT x.*, ROWNUM AS " + + "\"rownum\" FROM (SELECT * FROM \"PEOPLE\""); + if (!filters.isEmpty()) { + query.append( + QueryBuilder.getWhereStringForFilters(filters, sh)); + } + query.append(") x) WHERE \"rownum\" BETWEEN ? AND ?"); + sh.addParameterValue(offset); + sh.addParameterValue(offset + limit); + sh.setQueryString(query.toString()); + return sh; + } else { + StringBuilder query = new StringBuilder("SELECT * FROM people"); + if (!filters.isEmpty()) { + query.append( + QueryBuilder.getWhereStringForFilters(filters, sh)); + } + if (limit != 0 || offset != 0) { + query.append(" LIMIT ? OFFSET ?"); + sh.addParameterValue(limit); + sh.addParameterValue(offset); + } + sh.setQueryString(query.toString()); + return sh; + } + } + +} diff --git a/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/ReadOnlyRowIdTest.java b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/ReadOnlyRowIdTest.java new file mode 100644 index 0000000000..29968ecf94 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/ReadOnlyRowIdTest.java @@ -0,0 +1,55 @@ +package com.vaadin.data.util.sqlcontainer; + +import org.junit.Assert; +import org.junit.Test; + +public class ReadOnlyRowIdTest { + + @Test + public void getRowNum_shouldReturnRowNumGivenInConstructor() { + int rowNum = 1337; + ReadOnlyRowId rid = new ReadOnlyRowId(rowNum); + Assert.assertEquals(rowNum, rid.getRowNum()); + } + + @Test + public void hashCode_shouldBeEqualToHashCodeOfRowNum() { + int rowNum = 1337; + ReadOnlyRowId rid = new ReadOnlyRowId(rowNum); + Assert.assertEquals(Integer.valueOf(rowNum).hashCode(), rid.hashCode()); + } + + @Test + public void equals_compareWithNull_shouldBeFalse() { + ReadOnlyRowId rid = new ReadOnlyRowId(1337); + Assert.assertFalse(rid.equals(null)); + } + + @Test + public void equals_compareWithSameInstance_shouldBeTrue() { + ReadOnlyRowId rid = new ReadOnlyRowId(1337); + ReadOnlyRowId rid2 = rid; + Assert.assertTrue(rid.equals(rid2)); + } + + @Test + public void equals_compareWithOtherType_shouldBeFalse() { + ReadOnlyRowId rid = new ReadOnlyRowId(1337); + Assert.assertFalse(rid.equals(new Object())); + } + + @Test + public void equals_compareWithOtherRowId_shouldBeFalse() { + ReadOnlyRowId rid = new ReadOnlyRowId(1337); + ReadOnlyRowId rid2 = new ReadOnlyRowId(42); + Assert.assertFalse(rid.equals(rid2)); + } + + @Test + public void toString_rowNumberIsReturned() { + int i = 1; + ReadOnlyRowId rowId = new ReadOnlyRowId(i); + Assert.assertEquals("Unexpected toString value", String.valueOf(i), + rowId.toString()); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/RowIdTest.java b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/RowIdTest.java new file mode 100644 index 0000000000..e93048157b --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/RowIdTest.java @@ -0,0 +1,60 @@ +package com.vaadin.data.util.sqlcontainer; + +import org.junit.Assert; +import org.junit.Test; + +public class RowIdTest { + + @Test + public void constructor_withArrayOfPrimaryKeyColumns_shouldSucceed() { + RowId id = new RowId(new Object[] { "id", "name" }); + Assert.assertArrayEquals(new Object[] { "id", "name" }, id.getId()); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor_withNullParameter_shouldFail() { + new RowId(null); + } + + @Test + public void hashCode_samePrimaryKeys_sameResult() { + RowId id = new RowId(new Object[] { "id", "name" }); + RowId id2 = new RowId(new Object[] { "id", "name" }); + Assert.assertEquals(id.hashCode(), id2.hashCode()); + } + + @Test + public void hashCode_differentPrimaryKeys_differentResult() { + RowId id = new RowId(new Object[] { "id", "name" }); + RowId id2 = new RowId(new Object[] { "id" }); + Assert.assertFalse(id.hashCode() == id2.hashCode()); + } + + @Test + public void equals_samePrimaryKeys_returnsTrue() { + RowId id = new RowId(new Object[] { "id", "name" }); + RowId id2 = new RowId(new Object[] { "id", "name" }); + Assert.assertEquals(id, id2); + } + + @Test + public void equals_differentPrimaryKeys_returnsFalse() { + RowId id = new RowId(new Object[] { "id", "name" }); + RowId id2 = new RowId(new Object[] { "id" }); + Assert.assertFalse(id.equals(id2.hashCode())); + } + + @Test + public void equals_differentDataType_returnsFalse() { + RowId id = new RowId(new Object[] { "id", "name" }); + Assert.assertFalse(id.equals("Tudiluu")); + Assert.assertFalse(id.equals(new Integer(1337))); + } + + @Test + public void toString_defaultCtor_noException() { + RowId rowId = new RowId(); + Assert.assertTrue("Unexpected to string for empty Row Id", + rowId.toString().isEmpty()); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java new file mode 100644 index 0000000000..0bdcc9a3c3 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java @@ -0,0 +1,1353 @@ +package com.vaadin.data.util.sqlcontainer; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.hasItems; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; +import static org.hamcrest.core.IsNull.nullValue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.math.BigDecimal; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.easymock.EasyMock; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.data.Container.ItemSetChangeEvent; +import com.vaadin.data.Container.ItemSetChangeListener; +import com.vaadin.data.Item; +import com.vaadin.data.util.filter.Like; +import com.vaadin.data.util.sqlcontainer.SQLTestsConstants.DB; +import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool; +import com.vaadin.data.util.sqlcontainer.query.OrderBy; +import com.vaadin.data.util.sqlcontainer.query.TableQuery; +import com.vaadin.data.util.sqlcontainer.query.ValidatingSimpleJDBCConnectionPool; + +public class SQLContainerTableQueryTest { + + private static final int offset = SQLTestsConstants.offset; + private final int numberOfRowsInContainer = 4; + private final int numberOfPropertiesInContainer = 3; + private final String NAME = "NAME"; + private final String ID = "ID"; + private final String AGE = "AGE"; + private JDBCConnectionPool connectionPool; + private TableQuery query; + private SQLContainer container; + private final RowId existingItemId = getRowId(1); + private final RowId nonExistingItemId = getRowId(1337); + + @Before + public void setUp() throws SQLException { + + try { + connectionPool = new ValidatingSimpleJDBCConnectionPool( + SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL, + SQLTestsConstants.dbUser, SQLTestsConstants.dbPwd, 2, 2); + } catch (SQLException e) { + e.printStackTrace(); + Assert.fail(e.getMessage()); + } + + DataGenerator.addPeopleToDatabase(connectionPool); + + query = getTableQuery("people"); + container = new SQLContainer(query); + } + + private TableQuery getTableQuery(String tableName) { + return new TableQuery(tableName, connectionPool, + SQLTestsConstants.sqlGen); + } + + private SQLContainer getGarbageContainer() throws SQLException { + DataGenerator.createGarbage(connectionPool); + + return new SQLContainer(getTableQuery("garbage")); + } + + private Item getItem(Object id) { + return container.getItem(id); + } + + private RowId getRowId(int id) { + return new RowId(new Object[] { id + offset }); + } + + @After + public void tearDown() { + if (connectionPool != null) { + connectionPool.destroy(); + } + } + + @Test + public void itemWithExistingVersionColumnIsRemoved() throws SQLException { + container.setAutoCommit(true); + query.setVersionColumn(ID); + + assertTrue(container.removeItem(container.lastItemId())); + } + + @Test(expected = SQLException.class) + public void itemWithNonExistingVersionColumnCannotBeRemoved() + throws SQLException { + query.setVersionColumn("version"); + + container.removeItem(container.lastItemId()); + + container.commit(); + } + + @Test + public void containerContainsId() { + assertTrue(container.containsId(existingItemId)); + } + + @Test + public void containerDoesNotContainId() { + assertFalse(container.containsId(nonExistingItemId)); + } + + @Test + public void idPropertyHasCorrectType() { + if (SQLTestsConstants.db == DB.ORACLE) { + assertEquals(container.getType(ID), BigDecimal.class); + } else { + assertEquals(container.getType(ID), Integer.class); + } + } + + @Test + public void namePropertyHasCorrectType() { + assertEquals(container.getType(NAME), String.class); + } + + @Test + public void nonExistingPropertyDoesNotHaveType() { + assertThat(container.getType("adsf"), is(nullValue())); + } + + @Test + public void sizeIsReturnedCorrectly() { + assertEquals(numberOfRowsInContainer, container.size()); + } + + @Test + public void propertyIsFetchedForExistingItem() { + assertThat(container.getContainerProperty(existingItemId, NAME) + .getValue().toString(), is("Kalle")); + } + + @Test + public void containerDoesNotContainPropertyForExistingItem() { + assertThat(container.getContainerProperty(existingItemId, "asdf"), + is(nullValue())); + } + + @Test + public void containerDoesNotContainExistingPropertyForNonExistingItem() { + assertThat(container.getContainerProperty(nonExistingItemId, NAME), + is(nullValue())); + } + + @Test + public void propertyIdsAreFetched() { + ArrayList<String> propertyIds = new ArrayList<String>( + (Collection<? extends String>) container + .getContainerPropertyIds()); + + assertThat(propertyIds.size(), is(numberOfPropertiesInContainer)); + assertThat(propertyIds, hasItems(ID, NAME, AGE)); + } + + @Test + public void existingItemIsFetched() { + Item item = container.getItem(existingItemId); + + assertThat(item.getItemProperty(NAME).getValue().toString(), + is("Kalle")); + } + + @Test + public void newItemIsAdded() throws SQLException { + Object id = container.addItem(); + getItem(id).getItemProperty(NAME).setValue("foo"); + + container.commit(); + + Item item = getItem(container.lastItemId()); + assertThat(item.getItemProperty(NAME).getValue(), is("foo")); + } + + @Test + public void itemPropertyIsNotRevertedOnRefresh() { + getItem(existingItemId).getItemProperty(NAME).setValue("foo"); + + container.refresh(); + + assertThat(getItem(existingItemId).getItemProperty(NAME).getValue(), + is("foo")); + } + + @Test + public void correctItemIsFetchedFromMultipleRows() throws SQLException { + DataGenerator.addFiveThousandPeople(connectionPool); + + Item item = container.getItem(getRowId(1337)); + + assertThat((Integer) item.getItemProperty(ID).getValue(), + is(equalTo(1337 + offset))); + assertThat(item.getItemProperty(NAME).getValue().toString(), + is("Person 1337")); + } + + @Test + public void getItemIds_table_returnsItemIdsWithKeys0through3() + throws SQLException { + Collection<?> itemIds = container.getItemIds(); + assertEquals(4, itemIds.size()); + RowId zero = new RowId(new Object[] { 0 + offset }); + RowId one = new RowId(new Object[] { 1 + offset }); + RowId two = new RowId(new Object[] { 2 + offset }); + RowId three = new RowId(new Object[] { 3 + offset }); + if (SQLTestsConstants.db == DB.ORACLE) { + String[] correct = new String[] { "1", "2", "3", "4" }; + List<String> oracle = new ArrayList<String>(); + for (Object o : itemIds) { + oracle.add(o.toString()); + } + Assert.assertArrayEquals(correct, oracle.toArray()); + } else { + Assert.assertArrayEquals(new Object[] { zero, one, two, three }, + itemIds.toArray()); + } + } + + @Test + public void size_tableOneAddedItem_returnsFive() throws SQLException { + Connection conn = connectionPool.reserveConnection(); + Statement statement = conn.createStatement(); + if (SQLTestsConstants.db == DB.MSSQL) { + statement.executeUpdate("insert into people values('Bengt', 30)"); + } else { + statement.executeUpdate( + "insert into people values(default, 'Bengt', 30)"); + } + statement.close(); + conn.commit(); + connectionPool.releaseConnection(conn); + + assertEquals(5, container.size()); + } + + @Test + public void indexOfId_tableWithParameterThree_returnsThree() + throws SQLException { + if (SQLTestsConstants.db == DB.ORACLE) { + assertEquals(3, container.indexOfId( + new RowId(new Object[] { new BigDecimal(3 + offset) }))); + } else { + assertEquals(3, container + .indexOfId(new RowId(new Object[] { 3 + offset }))); + } + } + + @Test + public void indexOfId_table5000RowsWithParameter1337_returns1337() + throws SQLException { + DataGenerator.addFiveThousandPeople(connectionPool); + + if (SQLTestsConstants.db == DB.ORACLE) { + container.getItem( + new RowId(new Object[] { new BigDecimal(1337 + offset) })); + assertEquals(1337, container.indexOfId( + new RowId(new Object[] { new BigDecimal(1337 + offset) }))); + } else { + container.getItem(new RowId(new Object[] { 1337 + offset })); + assertEquals(1337, container + .indexOfId(new RowId(new Object[] { 1337 + offset }))); + } + } + + @Test + public void getIdByIndex_table5000rowsIndex1337_returnsRowId1337() + throws SQLException { + DataGenerator.addFiveThousandPeople(connectionPool); + Object itemId = container.getIdByIndex(1337); + if (SQLTestsConstants.db == DB.ORACLE) { + assertEquals(new RowId(new Object[] { 1337 + offset }).toString(), + itemId.toString()); + } else { + assertEquals(new RowId(new Object[] { 1337 + offset }), itemId); + } + } + + @Test + public void getIdByIndex_tableWithPaging5000rowsIndex1337_returnsRowId1337() + throws SQLException { + DataGenerator.addFiveThousandPeople(connectionPool); + + Object itemId = container.getIdByIndex(1337); + if (SQLTestsConstants.db == DB.ORACLE) { + assertEquals(new RowId(new Object[] { 1337 + offset }).toString(), + itemId.toString()); + } else { + assertEquals(new RowId(new Object[] { 1337 + offset }), itemId); + } + } + + @Test + public void nextItemId_tableCurrentItem1337_returnsItem1338() + throws SQLException { + DataGenerator.addFiveThousandPeople(connectionPool); + SQLContainer container = new SQLContainer(new TableQuery("people", + connectionPool, SQLTestsConstants.sqlGen)); + Object itemId = container.getIdByIndex(1337); + if (SQLTestsConstants.db == DB.ORACLE) { + assertEquals(new RowId(new Object[] { 1338 + offset }).toString(), + container.nextItemId(itemId).toString()); + } else { + assertEquals(new RowId(new Object[] { 1338 + offset }), + container.nextItemId(itemId)); + } + } + + @Test + public void prevItemId_tableCurrentItem1337_returns1336() + throws SQLException { + DataGenerator.addFiveThousandPeople(connectionPool); + Object itemId = container.getIdByIndex(1337); + if (SQLTestsConstants.db == DB.ORACLE) { + assertEquals(new RowId(new Object[] { 1336 + offset }).toString(), + container.prevItemId(itemId).toString()); + } else { + assertEquals(new RowId(new Object[] { 1336 + offset }), + container.prevItemId(itemId)); + } + } + + @Test + public void firstItemId_table_returnsItemId0() throws SQLException { + if (SQLTestsConstants.db == DB.ORACLE) { + assertEquals(new RowId(new Object[] { 0 + offset }).toString(), + container.firstItemId().toString()); + } else { + assertEquals(new RowId(new Object[] { 0 + offset }), + container.firstItemId()); + } + } + + @Test + public void lastItemId_table5000Rows_returnsItemId4999() + throws SQLException { + DataGenerator.addFiveThousandPeople(connectionPool); + + if (SQLTestsConstants.db == DB.ORACLE) { + assertEquals(new RowId(new Object[] { 4999 + offset }).toString(), + container.lastItemId().toString()); + } else { + assertEquals(new RowId(new Object[] { 4999 + offset }), + container.lastItemId()); + } + } + + @Test + public void isFirstId_tableActualFirstId_returnsTrue() throws SQLException { + if (SQLTestsConstants.db == DB.ORACLE) { + assertTrue(container.isFirstId( + new RowId(new Object[] { new BigDecimal(0 + offset) }))); + } else { + assertTrue(container + .isFirstId(new RowId(new Object[] { 0 + offset }))); + } + } + + @Test + public void isFirstId_tableSecondId_returnsFalse() throws SQLException { + if (SQLTestsConstants.db == DB.ORACLE) { + Assert.assertFalse(container.isFirstId( + new RowId(new Object[] { new BigDecimal(1 + offset) }))); + } else { + Assert.assertFalse(container + .isFirstId(new RowId(new Object[] { 1 + offset }))); + } + } + + @Test + public void isLastId_tableSecondId_returnsFalse() throws SQLException { + if (SQLTestsConstants.db == DB.ORACLE) { + Assert.assertFalse(container.isLastId( + new RowId(new Object[] { new BigDecimal(1 + offset) }))); + } else { + Assert.assertFalse( + container.isLastId(new RowId(new Object[] { 1 + offset }))); + } + } + + @Test + public void isLastId_tableLastId_returnsTrue() throws SQLException { + if (SQLTestsConstants.db == DB.ORACLE) { + assertTrue(container.isLastId( + new RowId(new Object[] { new BigDecimal(3 + offset) }))); + } else { + assertTrue( + container.isLastId(new RowId(new Object[] { 3 + offset }))); + } + } + + @Test + public void isLastId_table5000RowsLastId_returnsTrue() throws SQLException { + DataGenerator.addFiveThousandPeople(connectionPool); + if (SQLTestsConstants.db == DB.ORACLE) { + assertTrue(container.isLastId( + new RowId(new Object[] { new BigDecimal(4999 + offset) }))); + } else { + assertTrue(container + .isLastId(new RowId(new Object[] { 4999 + offset }))); + } + } + + @Test + public void allIdsFound_table5000RowsLastId_shouldSucceed() + throws SQLException { + DataGenerator.addFiveThousandPeople(connectionPool); + + for (int i = 0; i < 5000; i++) { + assertTrue(container.containsId(container.getIdByIndex(i))); + } + } + + @Test + public void allIdsFound_table5000RowsLastId_autoCommit_shouldSucceed() + throws SQLException { + DataGenerator.addFiveThousandPeople(connectionPool); + + container.setAutoCommit(true); + for (int i = 0; i < 5000; i++) { + assertTrue(container.containsId(container.getIdByIndex(i))); + } + } + + @Test + public void refresh_table_sizeShouldUpdate() throws SQLException { + assertEquals(4, container.size()); + DataGenerator.addFiveThousandPeople(connectionPool); + container.refresh(); + assertEquals(5000, container.size()); + } + + @Test + public void refresh_tableWithoutCallingRefresh_sizeShouldNotUpdate() + throws SQLException { + // Yeah, this is a weird one. We're testing that the size doesn't update + // after adding lots of items unless we call refresh inbetween. This to + // make sure that the refresh method actually refreshes stuff and isn't + // a NOP. + assertEquals(4, container.size()); + DataGenerator.addFiveThousandPeople(connectionPool); + assertEquals(4, container.size()); + } + + @Test + public void setAutoCommit_table_shouldSucceed() throws SQLException { + container.setAutoCommit(true); + assertTrue(container.isAutoCommit()); + container.setAutoCommit(false); + Assert.assertFalse(container.isAutoCommit()); + } + + @Test + public void getPageLength_table_returnsDefault100() throws SQLException { + assertEquals(100, container.getPageLength()); + } + + @Test + public void setPageLength_table_shouldSucceed() throws SQLException { + container.setPageLength(20); + assertEquals(20, container.getPageLength()); + container.setPageLength(200); + assertEquals(200, container.getPageLength()); + } + + @Test(expected = UnsupportedOperationException.class) + public void addContainerProperty_normal_isUnsupported() + throws SQLException { + container.addContainerProperty("asdf", String.class, ""); + } + + @Test(expected = UnsupportedOperationException.class) + public void removeContainerProperty_normal_isUnsupported() + throws SQLException { + container.removeContainerProperty("asdf"); + } + + @Test(expected = UnsupportedOperationException.class) + public void addItemObject_normal_isUnsupported() throws SQLException { + container.addItem("asdf"); + } + + @Test(expected = UnsupportedOperationException.class) + public void addItemAfterObjectObject_normal_isUnsupported() + throws SQLException { + container.addItemAfter("asdf", "foo"); + } + + @Test(expected = UnsupportedOperationException.class) + public void addItemAtIntObject_normal_isUnsupported() throws SQLException { + container.addItemAt(2, "asdf"); + } + + @Test(expected = UnsupportedOperationException.class) + public void addItemAtInt_normal_isUnsupported() throws SQLException { + container.addItemAt(2); + } + + @Test(expected = UnsupportedOperationException.class) + public void addItemAfterObject_normal_isUnsupported() throws SQLException { + container.addItemAfter("asdf"); + } + + @Test + public void addItem_tableAddOneNewItem_returnsItemId() throws SQLException { + Object itemId = container.addItem(); + Assert.assertNotNull(itemId); + } + + @Test + public void addItem_tableAddOneNewItem_autoCommit_returnsFinalItemId() + throws SQLException { + container.setAutoCommit(true); + Object itemId = container.addItem(); + Assert.assertNotNull(itemId); + assertTrue(itemId instanceof RowId); + Assert.assertFalse(itemId instanceof TemporaryRowId); + } + + @Test + public void addItem_tableAddOneNewItem_autoCommit_sizeIsIncreased() + throws SQLException { + container.setAutoCommit(true); + int originalSize = container.size(); + container.addItem(); + assertEquals(originalSize + 1, container.size()); + } + + @Test + public void addItem_tableAddOneNewItem_shouldChangeSize() + throws SQLException { + int size = container.size(); + container.addItem(); + assertEquals(size + 1, container.size()); + } + + @Test + public void addItem_tableAddTwoNewItems_shouldChangeSize() + throws SQLException { + int size = container.size(); + Object id1 = container.addItem(); + Object id2 = container.addItem(); + assertEquals(size + 2, container.size()); + Assert.assertNotSame(id1, id2); + Assert.assertFalse(id1.equals(id2)); + } + + @Test + public void nextItemId_tableNewlyAddedItem_returnsNewlyAdded() + throws SQLException { + Object lastId = container.lastItemId(); + Object id = container.addItem(); + assertEquals(id, container.nextItemId(lastId)); + } + + @Test + public void lastItemId_tableNewlyAddedItem_returnsNewlyAdded() + throws SQLException { + Object lastId = container.lastItemId(); + Object id = container.addItem(); + assertEquals(id, container.lastItemId()); + Assert.assertNotSame(lastId, container.lastItemId()); + } + + @Test + public void indexOfId_tableNewlyAddedItem_returnsFour() + throws SQLException { + Object id = container.addItem(); + assertEquals(4, container.indexOfId(id)); + } + + @Test + public void getItem_tableNewlyAddedItem_returnsNewlyAdded() + throws SQLException { + Object id = container.addItem(); + Assert.assertNotNull(container.getItem(id)); + } + + @Test + public void getItemIds_tableNewlyAddedItem_containsNewlyAdded() + throws SQLException { + Object id = container.addItem(); + assertTrue(container.getItemIds().contains(id)); + } + + @Test + public void getContainerProperty_tableNewlyAddedItem_returnsPropertyOfNewlyAddedItem() + throws SQLException { + Object id = container.addItem(); + Item item = container.getItem(id); + item.getItemProperty(NAME).setValue("asdf"); + assertEquals("asdf", + container.getContainerProperty(id, NAME).getValue()); + } + + @Test + public void containsId_tableNewlyAddedItem_returnsTrue() + throws SQLException { + Object id = container.addItem(); + + assertTrue(container.containsId(id)); + } + + @Test + public void prevItemId_tableTwoNewlyAddedItems_returnsFirstAddedItem() + throws SQLException { + Object id1 = container.addItem(); + Object id2 = container.addItem(); + + assertEquals(id1, container.prevItemId(id2)); + } + + @Test + public void firstItemId_tableEmptyResultSet_returnsFirstAddedItem() + throws SQLException { + SQLContainer garbageContainer = getGarbageContainer(); + + Object id = garbageContainer.addItem(); + + Assert.assertSame(id, garbageContainer.firstItemId()); + } + + @Test + public void isFirstId_tableEmptyResultSet_returnsFirstAddedItem() + throws SQLException { + SQLContainer garbageContainer = getGarbageContainer(); + + Object id = garbageContainer.addItem(); + + assertTrue(garbageContainer.isFirstId(id)); + } + + @Test + public void isLastId_tableOneItemAdded_returnsTrueForAddedItem() + throws SQLException { + Object id = container.addItem(); + + assertTrue(container.isLastId(id)); + } + + @Test + public void isLastId_tableTwoItemsAdded_returnsTrueForLastAddedItem() + throws SQLException { + container.addItem(); + + Object id2 = container.addItem(); + + assertTrue(container.isLastId(id2)); + } + + @Test + public void getIdByIndex_tableOneItemAddedLastIndexInContainer_returnsAddedItem() + throws SQLException { + Object id = container.addItem(); + + assertEquals(id, container.getIdByIndex(container.size() - 1)); + } + + @Test + public void removeItem_tableNoAddedItems_removesItemFromContainer() + throws SQLException { + int originalSize = container.size(); + Object id = container.firstItemId(); + + assertTrue(container.removeItem(id)); + + Assert.assertNotSame(id, container.firstItemId()); + assertEquals(originalSize - 1, container.size()); + } + + @Test + public void containsId_tableRemovedItem_returnsFalse() throws SQLException { + Object id = container.firstItemId(); + assertTrue(container.removeItem(id)); + Assert.assertFalse(container.containsId(id)); + } + + @Test + public void removeItem_tableOneAddedItem_removesTheAddedItem() + throws SQLException { + Object id = container.addItem(); + int size = container.size(); + + assertTrue(container.removeItem(id)); + Assert.assertFalse(container.containsId(id)); + assertEquals(size - 1, container.size()); + } + + @Test + public void getItem_tableItemRemoved_returnsNull() throws SQLException { + Object id = container.firstItemId(); + + assertTrue(container.removeItem(id)); + Assert.assertNull(container.getItem(id)); + } + + @Test + public void getItem_tableAddedItemRemoved_returnsNull() + throws SQLException { + Object id = container.addItem(); + + Assert.assertNotNull(container.getItem(id)); + assertTrue(container.removeItem(id)); + Assert.assertNull(container.getItem(id)); + } + + @Test + public void getItemIds_tableItemRemoved_shouldNotContainRemovedItem() + throws SQLException { + Object id = container.firstItemId(); + + assertTrue(container.getItemIds().contains(id)); + assertTrue(container.removeItem(id)); + Assert.assertFalse(container.getItemIds().contains(id)); + } + + @Test + public void getItemIds_tableAddedItemRemoved_shouldNotContainRemovedItem() + throws SQLException { + Object id = container.addItem(); + + assertTrue(container.getItemIds().contains(id)); + assertTrue(container.removeItem(id)); + Assert.assertFalse(container.getItemIds().contains(id)); + } + + @Test + public void containsId_tableItemRemoved_returnsFalse() throws SQLException { + Object id = container.firstItemId(); + + assertTrue(container.containsId(id)); + assertTrue(container.removeItem(id)); + Assert.assertFalse(container.containsId(id)); + } + + @Test + public void containsId_tableAddedItemRemoved_returnsFalse() + throws SQLException { + Object id = container.addItem(); + + assertTrue(container.containsId(id)); + assertTrue(container.removeItem(id)); + Assert.assertFalse(container.containsId(id)); + } + + @Test + public void nextItemId_tableItemRemoved_skipsRemovedItem() + throws SQLException { + Object first = container.getIdByIndex(0); + Object second = container.getIdByIndex(1); + Object third = container.getIdByIndex(2); + + assertTrue(container.removeItem(second)); + assertEquals(third, container.nextItemId(first)); + } + + @Test + public void nextItemId_tableAddedItemRemoved_skipsRemovedItem() + throws SQLException { + Object first = container.lastItemId(); + Object second = container.addItem(); + Object third = container.addItem(); + + assertTrue(container.removeItem(second)); + assertEquals(third, container.nextItemId(first)); + } + + @Test + public void prevItemId_tableItemRemoved_skipsRemovedItem() + throws SQLException { + Object first = container.getIdByIndex(0); + Object second = container.getIdByIndex(1); + Object third = container.getIdByIndex(2); + + assertTrue(container.removeItem(second)); + assertEquals(first, container.prevItemId(third)); + } + + @Test + public void prevItemId_tableAddedItemRemoved_skipsRemovedItem() + throws SQLException { + Object first = container.lastItemId(); + Object second = container.addItem(); + Object third = container.addItem(); + + assertTrue(container.removeItem(second)); + assertEquals(first, container.prevItemId(third)); + } + + @Test + public void firstItemId_tableFirstItemRemoved_resultChanges() + throws SQLException { + Object first = container.firstItemId(); + + assertTrue(container.removeItem(first)); + Assert.assertNotSame(first, container.firstItemId()); + } + + @Test + public void firstItemId_tableNewlyAddedFirstItemRemoved_resultChanges() + throws SQLException { + SQLContainer garbageContainer = getGarbageContainer(); + + Object first = garbageContainer.addItem(); + Object second = garbageContainer.addItem(); + + Assert.assertSame(first, garbageContainer.firstItemId()); + assertTrue(garbageContainer.removeItem(first)); + Assert.assertSame(second, garbageContainer.firstItemId()); + } + + @Test + public void lastItemId_tableLastItemRemoved_resultChanges() + throws SQLException { + Object last = container.lastItemId(); + + assertTrue(container.removeItem(last)); + Assert.assertNotSame(last, container.lastItemId()); + } + + @Test + public void lastItemId_tableAddedLastItemRemoved_resultChanges() + throws SQLException { + Object last = container.addItem(); + + Assert.assertSame(last, container.lastItemId()); + assertTrue(container.removeItem(last)); + Assert.assertNotSame(last, container.lastItemId()); + } + + @Test + public void isFirstId_tableFirstItemRemoved_returnsFalse() + throws SQLException { + Object first = container.firstItemId(); + + assertTrue(container.removeItem(first)); + Assert.assertFalse(container.isFirstId(first)); + } + + @Test + public void isFirstId_tableAddedFirstItemRemoved_returnsFalse() + throws SQLException { + SQLContainer garbageContainer = getGarbageContainer(); + + Object first = garbageContainer.addItem(); + garbageContainer.addItem(); + + Assert.assertSame(first, garbageContainer.firstItemId()); + assertTrue(garbageContainer.removeItem(first)); + Assert.assertFalse(garbageContainer.isFirstId(first)); + } + + @Test + public void isLastId_tableLastItemRemoved_returnsFalse() + throws SQLException { + Object last = container.lastItemId(); + + assertTrue(container.removeItem(last)); + Assert.assertFalse(container.isLastId(last)); + } + + @Test + public void isLastId_tableAddedLastItemRemoved_returnsFalse() + throws SQLException { + Object last = container.addItem(); + + Assert.assertSame(last, container.lastItemId()); + assertTrue(container.removeItem(last)); + Assert.assertFalse(container.isLastId(last)); + } + + @Test + public void indexOfId_tableItemRemoved_returnsNegOne() throws SQLException { + Object id = container.getIdByIndex(2); + + assertTrue(container.removeItem(id)); + assertEquals(-1, container.indexOfId(id)); + } + + @Test + public void indexOfId_tableAddedItemRemoved_returnsNegOne() + throws SQLException { + Object id = container.addItem(); + + assertTrue(container.indexOfId(id) != -1); + assertTrue(container.removeItem(id)); + assertEquals(-1, container.indexOfId(id)); + } + + @Test + public void getIdByIndex_tableItemRemoved_resultChanges() + throws SQLException { + Object id = container.getIdByIndex(2); + + assertTrue(container.removeItem(id)); + Assert.assertNotSame(id, container.getIdByIndex(2)); + } + + @Test + public void getIdByIndex_tableAddedItemRemoved_resultChanges() + throws SQLException { + Object id = container.addItem(); + container.addItem(); + int index = container.indexOfId(id); + + assertTrue(container.removeItem(id)); + Assert.assertNotSame(id, container.getIdByIndex(index)); + } + + @Test + public void removeAllItems_table_shouldSucceed() throws SQLException { + assertTrue(container.removeAllItems()); + assertEquals(0, container.size()); + } + + @Test + public void removeAllItems_tableAddedItems_shouldSucceed() + throws SQLException { + container.addItem(); + container.addItem(); + + assertTrue(container.removeAllItems()); + assertEquals(0, container.size()); + } + + // Set timeout to ensure there is no infinite looping (#12882) + @Test(timeout = 1000) + public void removeAllItems_manyItems_commit_shouldSucceed() + throws SQLException { + final int itemNumber = (SQLContainer.CACHE_RATIO + 1) + * SQLContainer.DEFAULT_PAGE_LENGTH + 1; + + container.removeAllItems(); + + assertEquals(container.size(), 0); + for (int i = 0; i < itemNumber; ++i) { + container.addItem(); + } + container.commit(); + assertEquals(container.size(), itemNumber); + assertTrue(container.removeAllItems()); + container.commit(); + assertEquals(container.size(), 0); + } + + @Test + public void commit_tableAddedItem_shouldBeWrittenToDB() + throws SQLException { + Object id = container.addItem(); + container.getContainerProperty(id, NAME).setValue("New Name"); + + assertTrue(id instanceof TemporaryRowId); + Assert.assertSame(id, container.lastItemId()); + container.commit(); + Assert.assertFalse(container.lastItemId() instanceof TemporaryRowId); + assertEquals("New Name", container + .getContainerProperty(container.lastItemId(), NAME).getValue()); + } + + @Test + public void commit_tableTwoAddedItems_shouldBeWrittenToDB() + throws SQLException { + Object id = container.addItem(); + Object id2 = container.addItem(); + container.getContainerProperty(id, NAME).setValue("Herbert"); + container.getContainerProperty(id2, NAME).setValue("Larry"); + assertTrue(id2 instanceof TemporaryRowId); + Assert.assertSame(id2, container.lastItemId()); + container.commit(); + Object nextToLast = container.getIdByIndex(container.size() - 2); + + Assert.assertFalse(nextToLast instanceof TemporaryRowId); + assertEquals("Herbert", + container.getContainerProperty(nextToLast, NAME).getValue()); + Assert.assertFalse(container.lastItemId() instanceof TemporaryRowId); + assertEquals("Larry", container + .getContainerProperty(container.lastItemId(), NAME).getValue()); + } + + @Test + public void commit_tableRemovedItem_shouldBeRemovedFromDB() + throws SQLException { + Object last = container.lastItemId(); + container.removeItem(last); + container.commit(); + + Assert.assertFalse(last.equals(container.lastItemId())); + } + + @Test + public void commit_tableLastItemUpdated_shouldUpdateRowInDB() + throws SQLException { + Object last = container.lastItemId(); + container.getContainerProperty(last, NAME).setValue("Donald"); + container.commit(); + + assertEquals("Donald", container + .getContainerProperty(container.lastItemId(), NAME).getValue()); + } + + @Test + public void commit_removeModifiedItem_shouldSucceed() throws SQLException { + int size = container.size(); + Object key = container.firstItemId(); + Item row = container.getItem(key); + row.getItemProperty(NAME).setValue("Pekka"); + + assertTrue(container.removeItem(key)); + container.commit(); + assertEquals(size - 1, container.size()); + } + + @Test + public void rollback_tableItemAdded_discardsAddedItem() + throws SQLException { + int size = container.size(); + Object id = container.addItem(); + container.getContainerProperty(id, NAME).setValue("foo"); + assertEquals(size + 1, container.size()); + container.rollback(); + assertEquals(size, container.size()); + Assert.assertFalse("foo".equals( + container.getContainerProperty(container.lastItemId(), NAME) + .getValue())); + } + + @Test + public void rollback_tableItemRemoved_restoresRemovedItem() + throws SQLException { + int size = container.size(); + Object last = container.lastItemId(); + container.removeItem(last); + assertEquals(size - 1, container.size()); + container.rollback(); + assertEquals(size, container.size()); + assertEquals(last, container.lastItemId()); + } + + @Test + public void rollback_tableItemChanged_discardsChanges() + throws SQLException { + Object last = container.lastItemId(); + container.getContainerProperty(last, NAME).setValue("foo"); + container.rollback(); + Assert.assertFalse("foo".equals( + container.getContainerProperty(container.lastItemId(), NAME) + .getValue())); + } + + @Test + public void itemChangeNotification_table_isModifiedReturnsTrue() + throws SQLException { + Assert.assertFalse(container.isModified()); + RowItem last = (RowItem) container.getItem(container.lastItemId()); + container.itemChangeNotification(last); + assertTrue(container.isModified()); + } + + @Test + public void itemSetChangeListeners_table_shouldFire() throws SQLException { + ItemSetChangeListener listener = EasyMock + .createMock(ItemSetChangeListener.class); + listener.containerItemSetChange(EasyMock.isA(ItemSetChangeEvent.class)); + EasyMock.replay(listener); + + container.addListener(listener); + container.addItem(); + + EasyMock.verify(listener); + } + + @Test + public void itemSetChangeListeners_tableItemRemoved_shouldFire() + throws SQLException { + ItemSetChangeListener listener = EasyMock + .createMock(ItemSetChangeListener.class); + listener.containerItemSetChange(EasyMock.isA(ItemSetChangeEvent.class)); + EasyMock.expectLastCall().anyTimes(); + EasyMock.replay(listener); + + container.addListener(listener); + container.removeItem(container.lastItemId()); + + EasyMock.verify(listener); + } + + @Test + public void removeListener_table_shouldNotFire() throws SQLException { + ItemSetChangeListener listener = EasyMock + .createMock(ItemSetChangeListener.class); + EasyMock.replay(listener); + + container.addListener(listener); + container.removeListener(listener); + container.addItem(); + + EasyMock.verify(listener); + } + + @Test + public void isModified_tableRemovedItem_returnsTrue() throws SQLException { + Assert.assertFalse(container.isModified()); + container.removeItem(container.lastItemId()); + assertTrue(container.isModified()); + } + + @Test + public void isModified_tableAddedItem_returnsTrue() throws SQLException { + Assert.assertFalse(container.isModified()); + container.addItem(); + assertTrue(container.isModified()); + } + + @Test + public void isModified_tableChangedItem_returnsTrue() throws SQLException { + Assert.assertFalse(container.isModified()); + container.getContainerProperty(container.lastItemId(), NAME) + .setValue("foo"); + assertTrue(container.isModified()); + } + + @Test + public void getSortableContainerPropertyIds_table_returnsAllPropertyIds() + throws SQLException { + Collection<?> sortableIds = container.getSortableContainerPropertyIds(); + assertTrue(sortableIds.contains(ID)); + assertTrue(sortableIds.contains(NAME)); + assertTrue(sortableIds.contains("AGE")); + assertEquals(3, sortableIds.size()); + if (SQLTestsConstants.db == DB.MSSQL + || SQLTestsConstants.db == DB.ORACLE) { + Assert.assertFalse(sortableIds.contains("rownum")); + } + } + + @Test + public void addOrderBy_table_shouldReorderResults() throws SQLException { + // Ville, Kalle, Pelle, Börje + assertEquals("Ville", + container.getContainerProperty(container.firstItemId(), NAME) + .getValue()); + assertEquals("Börje", container + .getContainerProperty(container.lastItemId(), NAME).getValue()); + + container.addOrderBy(new OrderBy(NAME, true)); + // Börje, Kalle, Pelle, Ville + assertEquals("Börje", + container.getContainerProperty(container.firstItemId(), NAME) + .getValue()); + assertEquals("Ville", container + .getContainerProperty(container.lastItemId(), NAME).getValue()); + } + + @Test(expected = IllegalArgumentException.class) + public void addOrderBy_tableIllegalColumn_shouldFail() throws SQLException { + container.addOrderBy(new OrderBy("asdf", true)); + } + + @Test + public void sort_table_sortsByName() throws SQLException { + // Ville, Kalle, Pelle, Börje + assertEquals("Ville", + container.getContainerProperty(container.firstItemId(), NAME) + .getValue()); + assertEquals("Börje", container + .getContainerProperty(container.lastItemId(), NAME).getValue()); + + container.sort(new Object[] { NAME }, new boolean[] { true }); + + // Börje, Kalle, Pelle, Ville + assertEquals("Börje", + container.getContainerProperty(container.firstItemId(), NAME) + .getValue()); + assertEquals("Ville", container + .getContainerProperty(container.lastItemId(), NAME).getValue()); + } + + @Test + public void addFilter_table_filtersResults() throws SQLException { + // Ville, Kalle, Pelle, Börje + assertEquals(4, container.size()); + assertEquals("Börje", container + .getContainerProperty(container.lastItemId(), NAME).getValue()); + + container.addContainerFilter(new Like(NAME, "%lle")); + // Ville, Kalle, Pelle + assertEquals(3, container.size()); + assertEquals("Pelle", container + .getContainerProperty(container.lastItemId(), NAME).getValue()); + } + + @Test + public void addContainerFilter_filtersResults() throws SQLException { + // Ville, Kalle, Pelle, Börje + assertEquals(4, container.size()); + + container.addContainerFilter(NAME, "Vi", false, false); + + // Ville + assertEquals(1, container.size()); + assertEquals("Ville", container + .getContainerProperty(container.lastItemId(), NAME).getValue()); + } + + @Test + public void addContainerFilter_ignoreCase_filtersResults() + throws SQLException { + // Ville, Kalle, Pelle, Börje + assertEquals(4, container.size()); + + container.addContainerFilter(NAME, "vi", true, false); + + // Ville + assertEquals(1, container.size()); + assertEquals("Ville", container + .getContainerProperty(container.lastItemId(), NAME).getValue()); + } + + @Test + public void removeAllContainerFilters_table_noFiltering() + throws SQLException { + // Ville, Kalle, Pelle, Börje + assertEquals(4, container.size()); + + container.addContainerFilter(NAME, "Vi", false, false); + + // Ville + assertEquals(1, container.size()); + assertEquals("Ville", container + .getContainerProperty(container.lastItemId(), NAME).getValue()); + + container.removeAllContainerFilters(); + + assertEquals(4, container.size()); + assertEquals("Börje", container + .getContainerProperty(container.lastItemId(), NAME).getValue()); + } + + @Test + public void removeContainerFilters_table_noFiltering() throws SQLException { + // Ville, Kalle, Pelle, Börje + assertEquals(4, container.size()); + + container.addContainerFilter(NAME, "Vi", false, false); + + // Ville + assertEquals(1, container.size()); + assertEquals("Ville", container + .getContainerProperty(container.lastItemId(), NAME).getValue()); + + container.removeContainerFilters(NAME); + + assertEquals(4, container.size()); + assertEquals("Börje", container + .getContainerProperty(container.lastItemId(), NAME).getValue()); + } + + @Test + public void addFilter_tableBufferedItems_alsoFiltersBufferedItems() + throws SQLException { + // Ville, Kalle, Pelle, Börje + assertEquals(4, container.size()); + assertEquals("Börje", container + .getContainerProperty(container.lastItemId(), NAME).getValue()); + + Object id1 = container.addItem(); + container.getContainerProperty(id1, NAME).setValue("Palle"); + Object id2 = container.addItem(); + container.getContainerProperty(id2, NAME).setValue("Bengt"); + + container.addContainerFilter(new Like(NAME, "%lle")); + + // Ville, Kalle, Pelle, Palle + assertEquals(4, container.size()); + assertEquals("Ville", + container.getContainerProperty(container.getIdByIndex(0), NAME) + .getValue()); + assertEquals("Kalle", + container.getContainerProperty(container.getIdByIndex(1), NAME) + .getValue()); + assertEquals("Pelle", + container.getContainerProperty(container.getIdByIndex(2), NAME) + .getValue()); + assertEquals("Palle", + container.getContainerProperty(container.getIdByIndex(3), NAME) + .getValue()); + + try { + container.getIdByIndex(4); + Assert.fail( + "SQLContainer.getIdByIndex() returned a value for an index beyond the end of the container"); + } catch (IndexOutOfBoundsException e) { + // should throw exception - item is filtered out + } + Assert.assertNull(container.nextItemId(container.getIdByIndex(3))); + + Assert.assertFalse(container.containsId(id2)); + Assert.assertFalse(container.getItemIds().contains(id2)); + + Assert.assertNull(container.getItem(id2)); + assertEquals(-1, container.indexOfId(id2)); + + Assert.assertNotSame(id2, container.lastItemId()); + Assert.assertSame(id1, container.lastItemId()); + } + + @Test + public void sort_tableBufferedItems_sortsBufferedItemsLastInOrderAdded() + throws SQLException { + // Ville, Kalle, Pelle, Börje + assertEquals("Ville", + container.getContainerProperty(container.firstItemId(), NAME) + .getValue()); + assertEquals("Börje", container + .getContainerProperty(container.lastItemId(), NAME).getValue()); + + Object id1 = container.addItem(); + container.getContainerProperty(id1, NAME).setValue("Wilbert"); + Object id2 = container.addItem(); + container.getContainerProperty(id2, NAME).setValue("Albert"); + + container.sort(new Object[] { NAME }, new boolean[] { true }); + + // Börje, Kalle, Pelle, Ville, Wilbert, Albert + assertEquals("Börje", + container.getContainerProperty(container.firstItemId(), NAME) + .getValue()); + assertEquals("Wilbert", + container.getContainerProperty( + container.getIdByIndex(container.size() - 2), NAME) + .getValue()); + assertEquals("Albert", container + .getContainerProperty(container.lastItemId(), NAME).getValue()); + } + +} diff --git a/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLContainerTest.java b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLContainerTest.java new file mode 100644 index 0000000000..d499ceed92 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLContainerTest.java @@ -0,0 +1,2469 @@ +package com.vaadin.data.util.sqlcontainer; + +import java.math.BigDecimal; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.logging.Handler; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +import org.easymock.EasyMock; +import org.easymock.IAnswer; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.data.Container.Filter; +import com.vaadin.data.Container.ItemSetChangeEvent; +import com.vaadin.data.Container.ItemSetChangeListener; +import com.vaadin.data.Item; +import com.vaadin.data.util.filter.Compare.Equal; +import com.vaadin.data.util.filter.Like; +import com.vaadin.data.util.sqlcontainer.SQLTestsConstants.DB; +import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool; +import com.vaadin.data.util.sqlcontainer.query.FreeformQuery; +import com.vaadin.data.util.sqlcontainer.query.FreeformQueryDelegate; +import com.vaadin.data.util.sqlcontainer.query.FreeformStatementDelegate; +import com.vaadin.data.util.sqlcontainer.query.OrderBy; +import com.vaadin.data.util.sqlcontainer.query.ValidatingSimpleJDBCConnectionPool; +import com.vaadin.data.util.sqlcontainer.query.generator.MSSQLGenerator; +import com.vaadin.data.util.sqlcontainer.query.generator.OracleGenerator; +import com.vaadin.data.util.sqlcontainer.query.generator.SQLGenerator; +import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; +import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder; + +public class SQLContainerTest { + private static final int offset = SQLTestsConstants.offset; + private JDBCConnectionPool connectionPool; + + @Before + public void setUp() throws SQLException { + + try { + connectionPool = new ValidatingSimpleJDBCConnectionPool( + SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL, + SQLTestsConstants.dbUser, SQLTestsConstants.dbPwd, 2, 2); + } catch (SQLException e) { + e.printStackTrace(); + Assert.fail(e.getMessage()); + } + + DataGenerator.addPeopleToDatabase(connectionPool); + } + + @After + public void tearDown() { + if (connectionPool != null) { + connectionPool.destroy(); + } + } + + @Test + public void constructor_withFreeformQuery_shouldSucceed() + throws SQLException { + new SQLContainer(new FreeformQuery("SELECT * FROM people", + connectionPool, "ID")); + } + + @Test(expected = SQLException.class) + public void constructor_withIllegalFreeformQuery_shouldFail() + throws SQLException { + SQLContainer c = new SQLContainer( + new FreeformQuery("SELECT * FROM asdf", connectionPool, "ID")); + c.getItem(c.firstItemId()); + } + + @Test + public void containsId_withFreeformQueryAndExistingId_returnsTrue() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Assert.assertTrue(container.containsId(new RowId(new Object[] { 1 }))); + } + + @Test + public void containsId_withFreeformQueryAndNonexistingId_returnsFalse() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Assert.assertFalse( + container.containsId(new RowId(new Object[] { 1337 }))); + } + + @Test + public void getContainerProperty_freeformExistingItemIdAndPropertyId_returnsProperty() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + if (SQLTestsConstants.db == DB.ORACLE) { + Assert.assertEquals("Ville", + container.getContainerProperty(new RowId( + new Object[] { new BigDecimal(0 + offset) }), + "NAME").getValue()); + } else { + Assert.assertEquals("Ville", + container.getContainerProperty( + new RowId(new Object[] { 0 + offset }), "NAME") + .getValue()); + } + } + + @Test + public void getContainerProperty_freeformExistingItemIdAndNonexistingPropertyId_returnsNull() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Assert.assertNull(container.getContainerProperty( + new RowId(new Object[] { 1 + offset }), "asdf")); + } + + @Test + public void getContainerProperty_freeformNonexistingItemId_returnsNull() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Assert.assertNull(container.getContainerProperty( + new RowId(new Object[] { 1337 + offset }), "NAME")); + } + + @Test + public void getContainerPropertyIds_freeform_returnsIDAndNAME() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Collection<?> propertyIds = container.getContainerPropertyIds(); + Assert.assertEquals(3, propertyIds.size()); + Assert.assertArrayEquals(new String[] { "ID", "NAME", "AGE" }, + propertyIds.toArray()); + } + + @Test + public void getItem_freeformExistingItemId_returnsItem() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Item item; + if (SQLTestsConstants.db == DB.ORACLE) { + item = container.getItem( + new RowId(new Object[] { new BigDecimal(0 + offset) })); + } else { + item = container.getItem(new RowId(new Object[] { 0 + offset })); + } + Assert.assertNotNull(item); + Assert.assertEquals("Ville", item.getItemProperty("NAME").getValue()); + } + + @Test + public void nextItemNullAtEnd_freeformExistingItem() throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object lastItemId = container.lastItemId(); + Object afterLast = container.nextItemId(lastItemId); + Assert.assertNull(afterLast); + } + + @Test + public void prevItemNullAtStart_freeformExistingItem() throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object firstItemId = container.firstItemId(); + Object beforeFirst = container.prevItemId(firstItemId); + Assert.assertNull(beforeFirst); + } + + @Test + public void getItem_freeform5000RowsWithParameter1337_returnsItemWithId1337() + throws SQLException { + DataGenerator.addFiveThousandPeople(connectionPool); + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Item item; + if (SQLTestsConstants.db == DB.ORACLE) { + item = container.getItem( + new RowId(new Object[] { new BigDecimal(1337 + offset) })); + Assert.assertNotNull(item); + Assert.assertEquals(new BigDecimal(1337 + offset), + item.getItemProperty("ID").getValue()); + } else { + item = container.getItem(new RowId(new Object[] { 1337 + offset })); + Assert.assertNotNull(item); + Assert.assertEquals(1337 + offset, + item.getItemProperty("ID").getValue()); + } + Assert.assertEquals("Person 1337", + item.getItemProperty("NAME").getValue()); + } + + @Test + public void getItemIds_freeform_returnsItemIdsWithKeys0through3() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Collection<?> itemIds = container.getItemIds(); + Assert.assertEquals(4, itemIds.size()); + RowId zero = new RowId(new Object[] { 0 + offset }); + RowId one = new RowId(new Object[] { 1 + offset }); + RowId two = new RowId(new Object[] { 2 + offset }); + RowId three = new RowId(new Object[] { 3 + offset }); + if (SQLTestsConstants.db == DB.ORACLE) { + String[] correct = new String[] { "1", "2", "3", "4" }; + List<String> oracle = new ArrayList<String>(); + for (Object o : itemIds) { + oracle.add(o.toString()); + } + Assert.assertArrayEquals(correct, oracle.toArray()); + } else { + Assert.assertArrayEquals(new Object[] { zero, one, two, three }, + itemIds.toArray()); + } + } + + @Test + public void getType_freeformNAMEPropertyId_returnsString() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Assert.assertEquals(String.class, container.getType("NAME")); + } + + @Test + public void getType_freeformIDPropertyId_returnsInteger() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + if (SQLTestsConstants.db == DB.ORACLE) { + Assert.assertEquals(BigDecimal.class, container.getType("ID")); + } else { + Assert.assertEquals(Integer.class, container.getType("ID")); + } + } + + @Test + public void getType_freeformNonexistingPropertyId_returnsNull() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Assert.assertNull(container.getType("asdf")); + } + + @Test + public void size_freeform_returnsFour() throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Assert.assertEquals(4, container.size()); + } + + @Test + public void size_freeformOneAddedItem_returnsFive() throws SQLException { + Connection conn = connectionPool.reserveConnection(); + Statement statement = conn.createStatement(); + if (SQLTestsConstants.db == DB.MSSQL) { + statement.executeUpdate("insert into people values('Bengt', '42')"); + } else { + statement.executeUpdate( + "insert into people values(default, 'Bengt', '42')"); + } + statement.close(); + conn.commit(); + connectionPool.releaseConnection(conn); + + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Assert.assertEquals(5, container.size()); + } + + @Test + public void indexOfId_freeformWithParameterThree_returnsThree() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + if (SQLTestsConstants.db == DB.ORACLE) { + Assert.assertEquals(3, container.indexOfId( + new RowId(new Object[] { new BigDecimal(3 + offset) }))); + } else { + Assert.assertEquals(3, container + .indexOfId(new RowId(new Object[] { 3 + offset }))); + } + } + + @Test + public void indexOfId_freeform5000RowsWithParameter1337_returns1337() + throws SQLException { + DataGenerator.addFiveThousandPeople(connectionPool); + SQLContainer container = new SQLContainer( + new FreeformQuery("SELECT * FROM people ORDER BY \"ID\" ASC", + connectionPool, "ID")); + if (SQLTestsConstants.db == DB.ORACLE) { + container.getItem( + new RowId(new Object[] { new BigDecimal(1337 + offset) })); + Assert.assertEquals(1337, container.indexOfId( + new RowId(new Object[] { new BigDecimal(1337 + offset) }))); + } else { + container.getItem(new RowId(new Object[] { 1337 + offset })); + Assert.assertEquals(1337, container + .indexOfId(new RowId(new Object[] { 1337 + offset }))); + } + } + + @Test + public void getIdByIndex_freeform5000rowsIndex1337_returnsRowId1337() + throws SQLException { + DataGenerator.addFiveThousandPeople(connectionPool); + SQLContainer container = new SQLContainer( + new FreeformQuery("SELECT * FROM people ORDER BY \"ID\" ASC", + connectionPool, "ID")); + Object itemId = container.getIdByIndex(1337); + if (SQLTestsConstants.db == DB.ORACLE) { + Assert.assertEquals( + new RowId(new Object[] { new BigDecimal(1337 + offset) }), + itemId); + } else { + Assert.assertEquals(new RowId(new Object[] { 1337 + offset }), + itemId); + } + } + + @SuppressWarnings("unchecked") + @Test + public void getIdByIndex_freeformWithPaging5000rowsIndex1337_returnsRowId1337() + throws SQLException { + DataGenerator.addFiveThousandPeople(connectionPool); + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + connectionPool, "ID"); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + EasyMock.expect( + delegate.getQueryString(EasyMock.anyInt(), EasyMock.anyInt())) + .andAnswer(new IAnswer<String>() { + @Override + public String answer() throws Throwable { + Object[] args = EasyMock.getCurrentArguments(); + int offset = (Integer) (args[0]); + int limit = (Integer) (args[1]); + if (SQLTestsConstants.db == DB.MSSQL) { + int start = offset + 1; + int end = offset + limit + 1; + String q = "SELECT * FROM (SELECT row_number() OVER" + + " ( ORDER BY \"ID\" ASC) AS rownum, * FROM people)" + + " AS a WHERE a.rownum BETWEEN " + start + + " AND " + end; + return q; + } else if (SQLTestsConstants.db == DB.ORACLE) { + int start = offset + 1; + int end = offset + limit + 1; + String q = "SELECT * FROM (SELECT x.*, ROWNUM AS r FROM" + + " (SELECT * FROM people ORDER BY \"ID\" ASC) x) " + + " WHERE r BETWEEN " + start + " AND " + + end; + return q; + } else { + return "SELECT * FROM people LIMIT " + limit + + " OFFSET " + offset; + } + } + }).anyTimes(); + delegate.setFilters(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setFilters(EasyMock.isA(List.class)); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(EasyMock.isA(List.class)); + EasyMock.expectLastCall().anyTimes(); + EasyMock.expect(delegate.getCountQuery()) + .andThrow(new UnsupportedOperationException()).anyTimes(); + EasyMock.replay(delegate); + query.setDelegate(delegate); + SQLContainer container = new SQLContainer(query); + Object itemId = container.getIdByIndex(1337); + if (SQLTestsConstants.db == DB.ORACLE) { + Assert.assertEquals( + new RowId(new Object[] { 1337 + offset }).toString(), + itemId.toString()); + } else { + Assert.assertEquals(new RowId(new Object[] { 1337 + offset }), + itemId); + } + } + + @Test + public void nextItemId_freeformCurrentItem1337_returnsItem1338() + throws SQLException { + DataGenerator.addFiveThousandPeople(connectionPool); + SQLContainer container = new SQLContainer( + new FreeformQuery("SELECT * FROM people ORDER BY \"ID\" ASC", + connectionPool, "ID")); + Object itemId = container.getIdByIndex(1337); + if (SQLTestsConstants.db == DB.ORACLE) { + Assert.assertEquals( + new RowId(new Object[] { 1338 + offset }).toString(), + container.nextItemId(itemId).toString()); + } else { + Assert.assertEquals(new RowId(new Object[] { 1338 + offset }), + container.nextItemId(itemId)); + } + } + + @Test + public void prevItemId_freeformCurrentItem1337_returns1336() + throws SQLException { + DataGenerator.addFiveThousandPeople(connectionPool); + SQLContainer container = new SQLContainer( + new FreeformQuery("SELECT * FROM people ORDER BY \"ID\" ASC", + connectionPool, "ID")); + Object itemId = container.getIdByIndex(1337); + if (SQLTestsConstants.db == DB.ORACLE) { + Assert.assertEquals( + new RowId(new Object[] { 1336 + offset }).toString(), + container.prevItemId(itemId).toString()); + } else { + Assert.assertEquals(new RowId(new Object[] { 1336 + offset }), + container.prevItemId(itemId)); + } + } + + @Test + public void firstItemId_freeform_returnsItemId0() throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + if (SQLTestsConstants.db == DB.ORACLE) { + Assert.assertEquals( + new RowId(new Object[] { 0 + offset }).toString(), + container.firstItemId().toString()); + } else { + Assert.assertEquals(new RowId(new Object[] { 0 + offset }), + container.firstItemId()); + } + } + + @Test + public void lastItemId_freeform5000Rows_returnsItemId4999() + throws SQLException { + DataGenerator.addFiveThousandPeople(connectionPool); + + SQLContainer container = new SQLContainer( + new FreeformQuery("SELECT * FROM people ORDER BY \"ID\" ASC", + connectionPool, "ID")); + if (SQLTestsConstants.db == DB.ORACLE) { + Assert.assertEquals( + new RowId(new Object[] { 4999 + offset }).toString(), + container.lastItemId().toString()); + } else { + Assert.assertEquals(new RowId(new Object[] { 4999 + offset }), + container.lastItemId()); + } + } + + @Test + public void isFirstId_freeformActualFirstId_returnsTrue() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + if (SQLTestsConstants.db == DB.ORACLE) { + Assert.assertTrue(container.isFirstId( + new RowId(new Object[] { new BigDecimal(0 + offset) }))); + } else { + Assert.assertTrue(container + .isFirstId(new RowId(new Object[] { 0 + offset }))); + } + } + + @Test + public void isFirstId_freeformSecondId_returnsFalse() throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + if (SQLTestsConstants.db == DB.ORACLE) { + Assert.assertFalse(container.isFirstId( + new RowId(new Object[] { new BigDecimal(1 + offset) }))); + } else { + Assert.assertFalse(container + .isFirstId(new RowId(new Object[] { 1 + offset }))); + } + } + + @Test + public void isLastId_freeformSecondId_returnsFalse() throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + if (SQLTestsConstants.db == DB.ORACLE) { + Assert.assertFalse(container.isLastId( + new RowId(new Object[] { new BigDecimal(1 + offset) }))); + } else { + Assert.assertFalse( + container.isLastId(new RowId(new Object[] { 1 + offset }))); + } + } + + @Test + public void isLastId_freeformLastId_returnsTrue() throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + if (SQLTestsConstants.db == DB.ORACLE) { + Assert.assertTrue(container.isLastId( + new RowId(new Object[] { new BigDecimal(3 + offset) }))); + } else { + Assert.assertTrue( + container.isLastId(new RowId(new Object[] { 3 + offset }))); + } + } + + @Test + public void isLastId_freeform5000RowsLastId_returnsTrue() + throws SQLException { + DataGenerator.addFiveThousandPeople(connectionPool); + SQLContainer container = new SQLContainer( + new FreeformQuery("SELECT * FROM people ORDER BY \"ID\" ASC", + connectionPool, "ID")); + if (SQLTestsConstants.db == DB.ORACLE) { + Assert.assertTrue(container.isLastId( + new RowId(new Object[] { new BigDecimal(4999 + offset) }))); + } else { + Assert.assertTrue(container + .isLastId(new RowId(new Object[] { 4999 + offset }))); + } + } + + @Test + public void refresh_freeform_sizeShouldUpdate() throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Assert.assertEquals(4, container.size()); + DataGenerator.addFiveThousandPeople(connectionPool); + container.refresh(); + Assert.assertEquals(5000, container.size()); + } + + @Test + public void refresh_freeformWithoutCallingRefresh_sizeShouldNotUpdate() + throws SQLException { + // Yeah, this is a weird one. We're testing that the size doesn't update + // after adding lots of items unless we call refresh inbetween. This to + // make sure that the refresh method actually refreshes stuff and isn't + // a NOP. + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Assert.assertEquals(4, container.size()); + DataGenerator.addFiveThousandPeople(connectionPool); + Assert.assertEquals(4, container.size()); + } + + @Test + public void setAutoCommit_freeform_shouldSucceed() throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + container.setAutoCommit(true); + Assert.assertTrue(container.isAutoCommit()); + container.setAutoCommit(false); + Assert.assertFalse(container.isAutoCommit()); + } + + @Test + public void getPageLength_freeform_returnsDefault100() throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Assert.assertEquals(100, container.getPageLength()); + } + + @Test + public void setPageLength_freeform_shouldSucceed() throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + container.setPageLength(20); + Assert.assertEquals(20, container.getPageLength()); + container.setPageLength(200); + Assert.assertEquals(200, container.getPageLength()); + } + + @Test(expected = UnsupportedOperationException.class) + public void addContainerProperty_normal_isUnsupported() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + container.addContainerProperty("asdf", String.class, ""); + } + + @Test(expected = UnsupportedOperationException.class) + public void removeContainerProperty_normal_isUnsupported() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + container.removeContainerProperty("asdf"); + } + + @Test(expected = UnsupportedOperationException.class) + public void addItemObject_normal_isUnsupported() throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + container.addItem("asdf"); + } + + @Test(expected = UnsupportedOperationException.class) + public void addItemAfterObjectObject_normal_isUnsupported() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + container.addItemAfter("asdf", "foo"); + } + + @Test(expected = UnsupportedOperationException.class) + public void addItemAtIntObject_normal_isUnsupported() throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + container.addItemAt(2, "asdf"); + } + + @Test(expected = UnsupportedOperationException.class) + public void addItemAtInt_normal_isUnsupported() throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + container.addItemAt(2); + } + + @Test(expected = UnsupportedOperationException.class) + public void addItemAfterObject_normal_isUnsupported() throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + container.addItemAfter("asdf"); + } + + @Test + public void addItem_freeformAddOneNewItem_returnsItemId() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object itemId = container.addItem(); + Assert.assertNotNull(itemId); + } + + @Test + public void addItem_freeformAddOneNewItem_shouldChangeSize() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + int size = container.size(); + container.addItem(); + Assert.assertEquals(size + 1, container.size()); + } + + @Test + public void addItem_freeformAddTwoNewItems_shouldChangeSize() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + int size = container.size(); + Object id1 = container.addItem(); + Object id2 = container.addItem(); + Assert.assertEquals(size + 2, container.size()); + Assert.assertNotSame(id1, id2); + Assert.assertFalse(id1.equals(id2)); + } + + @Test + public void nextItemId_freeformNewlyAddedItem_returnsNewlyAdded() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object lastId = container.lastItemId(); + Object id = container.addItem(); + Assert.assertEquals(id, container.nextItemId(lastId)); + } + + @Test + public void lastItemId_freeformNewlyAddedItem_returnsNewlyAdded() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object lastId = container.lastItemId(); + Object id = container.addItem(); + Assert.assertEquals(id, container.lastItemId()); + Assert.assertNotSame(lastId, container.lastItemId()); + } + + @Test + public void indexOfId_freeformNewlyAddedItem_returnsFour() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object id = container.addItem(); + Assert.assertEquals(4, container.indexOfId(id)); + } + + @Test + public void getItem_freeformNewlyAddedItem_returnsNewlyAdded() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object id = container.addItem(); + Assert.assertNotNull(container.getItem(id)); + } + + @Test + public void getItem_freeformNewlyAddedItemAndFiltered_returnsNull() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + container.addContainerFilter(new Equal("NAME", "asdf")); + Object id = container.addItem(); + Assert.assertNull(container.getItem(id)); + } + + @Test + public void getItemUnfiltered_freeformNewlyAddedItemAndFiltered_returnsNewlyAdded() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + container.addContainerFilter(new Equal("NAME", "asdf")); + Object id = container.addItem(); + Assert.assertNotNull(container.getItemUnfiltered(id)); + } + + @Test + public void getItemIds_freeformNewlyAddedItem_containsNewlyAdded() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object id = container.addItem(); + Assert.assertTrue(container.getItemIds().contains(id)); + } + + @Test + public void getContainerProperty_freeformNewlyAddedItem_returnsPropertyOfNewlyAddedItem() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object id = container.addItem(); + Item item = container.getItem(id); + item.getItemProperty("NAME").setValue("asdf"); + Assert.assertEquals("asdf", + container.getContainerProperty(id, "NAME").getValue()); + } + + @Test + public void containsId_freeformNewlyAddedItem_returnsTrue() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object id = container.addItem(); + Assert.assertTrue(container.containsId(id)); + } + + @Test + public void prevItemId_freeformTwoNewlyAddedItems_returnsFirstAddedItem() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object id1 = container.addItem(); + Object id2 = container.addItem(); + Assert.assertEquals(id1, container.prevItemId(id2)); + } + + @Test + public void firstItemId_freeformEmptyResultSet_returnsFirstAddedItem() + throws SQLException { + DataGenerator.createGarbage(connectionPool); + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM GARBAGE", connectionPool, "ID")); + Object id = container.addItem(); + Assert.assertSame(id, container.firstItemId()); + } + + @Test + public void isFirstId_freeformEmptyResultSet_returnsFirstAddedItem() + throws SQLException { + DataGenerator.createGarbage(connectionPool); + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM GARBAGE", connectionPool, "ID")); + Object id = container.addItem(); + Assert.assertTrue(container.isFirstId(id)); + } + + @Test + public void isLastId_freeformOneItemAdded_returnsTrueForAddedItem() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object id = container.addItem(); + Assert.assertTrue(container.isLastId(id)); + } + + @Test + public void isLastId_freeformTwoItemsAdded_returnsTrueForLastAddedItem() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + container.addItem(); + Object id2 = container.addItem(); + Assert.assertTrue(container.isLastId(id2)); + } + + @Test + public void getIdByIndex_freeformOneItemAddedLastIndexInContainer_returnsAddedItem() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object id = container.addItem(); + Assert.assertEquals(id, container.getIdByIndex(container.size() - 1)); + } + + @Test + public void removeItem_freeformNoAddedItems_removesItemFromContainer() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + int size = container.size(); + Object id = container.firstItemId(); + Assert.assertTrue(container.removeItem(id)); + Assert.assertNotSame(id, container.firstItemId()); + Assert.assertEquals(size - 1, container.size()); + } + + @Test + public void containsId_freeformRemovedItem_returnsFalse() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object id = container.firstItemId(); + Assert.assertTrue(container.removeItem(id)); + Assert.assertFalse(container.containsId(id)); + } + + @Test + public void containsId_unknownObject() throws SQLException { + + Handler ensureNoLogging = new Handler() { + + @Override + public void publish(LogRecord record) { + Assert.fail("No messages should be logged"); + + } + + @Override + public void flush() { + } + + @Override + public void close() throws SecurityException { + } + }; + + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Logger logger = Logger.getLogger(SQLContainer.class.getName()); + + logger.addHandler(ensureNoLogging); + try { + Assert.assertFalse(container.containsId(new Object())); + } finally { + logger.removeHandler(ensureNoLogging); + } + } + + @Test + public void removeItem_freeformOneAddedItem_removesTheAddedItem() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object id = container.addItem(); + int size = container.size(); + Assert.assertTrue(container.removeItem(id)); + Assert.assertFalse(container.containsId(id)); + Assert.assertEquals(size - 1, container.size()); + } + + @Test + public void getItem_freeformItemRemoved_returnsNull() throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object id = container.firstItemId(); + Assert.assertTrue(container.removeItem(id)); + Assert.assertNull(container.getItem(id)); + } + + @Test + public void getItem_freeformAddedItemRemoved_returnsNull() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object id = container.addItem(); + Assert.assertNotNull(container.getItem(id)); + Assert.assertTrue(container.removeItem(id)); + Assert.assertNull(container.getItem(id)); + } + + @Test + public void getItemIds_freeformItemRemoved_shouldNotContainRemovedItem() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object id = container.firstItemId(); + Assert.assertTrue(container.getItemIds().contains(id)); + Assert.assertTrue(container.removeItem(id)); + Assert.assertFalse(container.getItemIds().contains(id)); + } + + @Test + public void getItemIds_freeformAddedItemRemoved_shouldNotContainRemovedItem() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object id = container.addItem(); + Assert.assertTrue(container.getItemIds().contains(id)); + Assert.assertTrue(container.removeItem(id)); + Assert.assertFalse(container.getItemIds().contains(id)); + } + + @Test + public void containsId_freeformItemRemoved_returnsFalse() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object id = container.firstItemId(); + Assert.assertTrue(container.containsId(id)); + Assert.assertTrue(container.removeItem(id)); + Assert.assertFalse(container.containsId(id)); + } + + @Test + public void containsId_freeformAddedItemRemoved_returnsFalse() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object id = container.addItem(); + Assert.assertTrue(container.containsId(id)); + Assert.assertTrue(container.removeItem(id)); + Assert.assertFalse(container.containsId(id)); + } + + @Test + public void nextItemId_freeformItemRemoved_skipsRemovedItem() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object first = container.getIdByIndex(0); + Object second = container.getIdByIndex(1); + Object third = container.getIdByIndex(2); + Assert.assertTrue(container.removeItem(second)); + Assert.assertEquals(third, container.nextItemId(first)); + } + + @Test + public void nextItemId_freeformAddedItemRemoved_skipsRemovedItem() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object first = container.lastItemId(); + Object second = container.addItem(); + Object third = container.addItem(); + Assert.assertTrue(container.removeItem(second)); + Assert.assertEquals(third, container.nextItemId(first)); + } + + @Test + public void prevItemId_freeformItemRemoved_skipsRemovedItem() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object first = container.getIdByIndex(0); + Object second = container.getIdByIndex(1); + Object third = container.getIdByIndex(2); + Assert.assertTrue(container.removeItem(second)); + Assert.assertEquals(first, container.prevItemId(third)); + } + + @Test + public void prevItemId_freeformAddedItemRemoved_skipsRemovedItem() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object first = container.lastItemId(); + Object second = container.addItem(); + Object third = container.addItem(); + Assert.assertTrue(container.removeItem(second)); + Assert.assertEquals(first, container.prevItemId(third)); + } + + @Test + public void firstItemId_freeformFirstItemRemoved_resultChanges() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object first = container.firstItemId(); + Assert.assertTrue(container.removeItem(first)); + Assert.assertNotSame(first, container.firstItemId()); + } + + @Test + public void firstItemId_freeformNewlyAddedFirstItemRemoved_resultChanges() + throws SQLException { + DataGenerator.createGarbage(connectionPool); + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM GARBAGE", connectionPool, "ID")); + Object first = container.addItem(); + Object second = container.addItem(); + Assert.assertSame(first, container.firstItemId()); + Assert.assertTrue(container.removeItem(first)); + Assert.assertSame(second, container.firstItemId()); + } + + @Test + public void lastItemId_freeformLastItemRemoved_resultChanges() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object last = container.lastItemId(); + Assert.assertTrue(container.removeItem(last)); + Assert.assertNotSame(last, container.lastItemId()); + } + + @Test + public void lastItemId_freeformAddedLastItemRemoved_resultChanges() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object last = container.addItem(); + Assert.assertSame(last, container.lastItemId()); + Assert.assertTrue(container.removeItem(last)); + Assert.assertNotSame(last, container.lastItemId()); + } + + @Test + public void isFirstId_freeformFirstItemRemoved_returnsFalse() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object first = container.firstItemId(); + Assert.assertTrue(container.removeItem(first)); + Assert.assertFalse(container.isFirstId(first)); + } + + @Test + public void isFirstId_freeformAddedFirstItemRemoved_returnsFalse() + throws SQLException { + DataGenerator.createGarbage(connectionPool); + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM GARBAGE", connectionPool, "ID")); + Object first = container.addItem(); + container.addItem(); + Assert.assertSame(first, container.firstItemId()); + Assert.assertTrue(container.removeItem(first)); + Assert.assertFalse(container.isFirstId(first)); + } + + @Test + public void isLastId_freeformLastItemRemoved_returnsFalse() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object last = container.lastItemId(); + Assert.assertTrue(container.removeItem(last)); + Assert.assertFalse(container.isLastId(last)); + } + + @Test + public void isLastId_freeformAddedLastItemRemoved_returnsFalse() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object last = container.addItem(); + Assert.assertSame(last, container.lastItemId()); + Assert.assertTrue(container.removeItem(last)); + Assert.assertFalse(container.isLastId(last)); + } + + @Test + public void indexOfId_freeformItemRemoved_returnsNegOne() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object id = container.getIdByIndex(2); + Assert.assertTrue(container.removeItem(id)); + Assert.assertEquals(-1, container.indexOfId(id)); + } + + @Test + public void indexOfId_freeformAddedItemRemoved_returnsNegOne() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object id = container.addItem(); + Assert.assertTrue(container.indexOfId(id) != -1); + Assert.assertTrue(container.removeItem(id)); + Assert.assertEquals(-1, container.indexOfId(id)); + } + + @Test + public void getIdByIndex_freeformItemRemoved_resultChanges() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object id = container.getIdByIndex(2); + Assert.assertTrue(container.removeItem(id)); + Assert.assertNotSame(id, container.getIdByIndex(2)); + } + + @Test + public void getIdByIndex_freeformAddedItemRemoved_resultChanges() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object id = container.addItem(); + container.addItem(); + int index = container.indexOfId(id); + Assert.assertTrue(container.removeItem(id)); + Assert.assertNotSame(id, container.getIdByIndex(index)); + } + + @Test + public void removeAllItems_freeform_shouldSucceed() throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Assert.assertTrue(container.removeAllItems()); + Assert.assertEquals(0, container.size()); + } + + @Test + public void removeAllItems_freeformAddedItems_shouldSucceed() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + container.addItem(); + container.addItem(); + Assert.assertTrue(container.removeAllItems()); + Assert.assertEquals(0, container.size()); + } + + @SuppressWarnings("unchecked") + @Test + public void commit_freeformAddedItem_shouldBeWrittenToDB() + throws SQLException { + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + EasyMock.expect(delegate.storeRow(EasyMock.isA(Connection.class), + EasyMock.isA(RowItem.class))).andAnswer(new IAnswer<Integer>() { + @Override + public Integer answer() throws Throwable { + Connection conn = (Connection) EasyMock + .getCurrentArguments()[0]; + RowItem item = (RowItem) EasyMock + .getCurrentArguments()[1]; + Statement statement = conn.createStatement(); + if (SQLTestsConstants.db == DB.MSSQL) { + statement + .executeUpdate("insert into people values('" + + item.getItemProperty("NAME") + .getValue() + + "', '" + + item.getItemProperty("AGE") + .getValue() + + "')"); + } else { + statement.executeUpdate( + "insert into people values(default, '" + + item.getItemProperty("NAME") + .getValue() + + "', '" + + item.getItemProperty("AGE") + .getValue() + + "')"); + } + statement.close(); + conn.commit(); + connectionPool.releaseConnection(conn); + return 1; + } + }).anyTimes(); + EasyMock.expect( + delegate.getQueryString(EasyMock.anyInt(), EasyMock.anyInt())) + .andAnswer(new IAnswer<String>() { + @Override + public String answer() throws Throwable { + Object[] args = EasyMock.getCurrentArguments(); + int offset = (Integer) (args[0]); + int limit = (Integer) (args[1]); + if (SQLTestsConstants.db == DB.MSSQL) { + int start = offset + 1; + int end = offset + limit + 1; + String q = "SELECT * FROM (SELECT row_number() OVER" + + " ( ORDER BY \"ID\" ASC) AS rownum, * FROM people)" + + " AS a WHERE a.rownum BETWEEN " + start + + " AND " + end; + return q; + } else if (SQLTestsConstants.db == DB.ORACLE) { + int start = offset + 1; + int end = offset + limit + 1; + String q = "SELECT * FROM (SELECT x.*, ROWNUM AS r FROM" + + " (SELECT * FROM people ORDER BY \"ID\" ASC) x) " + + " WHERE r BETWEEN " + start + " AND " + + end; + return q; + } else { + return "SELECT * FROM people LIMIT " + limit + + " OFFSET " + offset; + } + } + }).anyTimes(); + delegate.setFilters(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setFilters(EasyMock.isA(List.class)); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(EasyMock.isA(List.class)); + EasyMock.expectLastCall().anyTimes(); + EasyMock.expect(delegate.getCountQuery()) + .andThrow(new UnsupportedOperationException()).anyTimes(); + + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + connectionPool, "ID"); + query.setDelegate(delegate); + EasyMock.replay(delegate); + SQLContainer container = new SQLContainer(query); + Object id = container.addItem(); + container.getContainerProperty(id, "NAME").setValue("New Name"); + container.getContainerProperty(id, "AGE").setValue(30); + Assert.assertTrue(id instanceof TemporaryRowId); + Assert.assertSame(id, container.lastItemId()); + container.commit(); + Assert.assertFalse(container.lastItemId() instanceof TemporaryRowId); + Assert.assertEquals("New Name", + container.getContainerProperty(container.lastItemId(), "NAME") + .getValue()); + EasyMock.verify(delegate); + } + + @SuppressWarnings("unchecked") + @Test + public void commit_freeformTwoAddedItems_shouldBeWrittenToDB() + throws SQLException { + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + EasyMock.expect(delegate.storeRow(EasyMock.isA(Connection.class), + EasyMock.isA(RowItem.class))).andAnswer(new IAnswer<Integer>() { + @Override + public Integer answer() throws Throwable { + Connection conn = (Connection) EasyMock + .getCurrentArguments()[0]; + RowItem item = (RowItem) EasyMock + .getCurrentArguments()[1]; + Statement statement = conn.createStatement(); + if (SQLTestsConstants.db == DB.MSSQL) { + statement + .executeUpdate("insert into people values('" + + item.getItemProperty("NAME") + .getValue() + + "', '" + + item.getItemProperty("AGE") + .getValue() + + "')"); + } else { + statement.executeUpdate( + "insert into people values(default, '" + + item.getItemProperty("NAME") + .getValue() + + "', '" + + item.getItemProperty("AGE") + .getValue() + + "')"); + } + statement.close(); + conn.commit(); + connectionPool.releaseConnection(conn); + return 1; + } + }).anyTimes(); + EasyMock.expect( + delegate.getQueryString(EasyMock.anyInt(), EasyMock.anyInt())) + .andAnswer(new IAnswer<String>() { + @Override + public String answer() throws Throwable { + Object[] args = EasyMock.getCurrentArguments(); + int offset = (Integer) (args[0]); + int limit = (Integer) (args[1]); + if (SQLTestsConstants.db == DB.MSSQL) { + int start = offset + 1; + int end = offset + limit + 1; + String q = "SELECT * FROM (SELECT row_number() OVER" + + " ( ORDER BY \"ID\" ASC) AS rownum, * FROM people)" + + " AS a WHERE a.rownum BETWEEN " + start + + " AND " + end; + return q; + } else if (SQLTestsConstants.db == DB.ORACLE) { + int start = offset + 1; + int end = offset + limit + 1; + String q = "SELECT * FROM (SELECT x.*, ROWNUM AS r FROM" + + " (SELECT * FROM people ORDER BY \"ID\" ASC) x) " + + " WHERE r BETWEEN " + start + " AND " + + end; + return q; + } else { + return "SELECT * FROM people LIMIT " + limit + + " OFFSET " + offset; + } + } + }).anyTimes(); + delegate.setFilters(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setFilters(EasyMock.isA(List.class)); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(EasyMock.isA(List.class)); + EasyMock.expectLastCall().anyTimes(); + EasyMock.expect(delegate.getCountQuery()) + .andThrow(new UnsupportedOperationException()).anyTimes(); + + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + connectionPool, "ID"); + query.setDelegate(delegate); + EasyMock.replay(delegate); + SQLContainer container = new SQLContainer(query); + Object id = container.addItem(); + Object id2 = container.addItem(); + container.getContainerProperty(id, "NAME").setValue("Herbert"); + container.getContainerProperty(id, "AGE").setValue(30); + container.getContainerProperty(id2, "NAME").setValue("Larry"); + container.getContainerProperty(id2, "AGE").setValue(50); + Assert.assertTrue(id2 instanceof TemporaryRowId); + Assert.assertSame(id2, container.lastItemId()); + container.commit(); + Object nextToLast = container.getIdByIndex(container.size() - 2); + Assert.assertFalse(nextToLast instanceof TemporaryRowId); + Assert.assertEquals("Herbert", + container.getContainerProperty(nextToLast, "NAME").getValue()); + Assert.assertFalse(container.lastItemId() instanceof TemporaryRowId); + Assert.assertEquals("Larry", + container.getContainerProperty(container.lastItemId(), "NAME") + .getValue()); + EasyMock.verify(delegate); + } + + @SuppressWarnings("unchecked") + @Test + public void commit_freeformRemovedItem_shouldBeRemovedFromDB() + throws SQLException { + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + EasyMock.expect(delegate.removeRow(EasyMock.isA(Connection.class), + EasyMock.isA(RowItem.class))).andAnswer(new IAnswer<Boolean>() { + @Override + public Boolean answer() throws Throwable { + Connection conn = (Connection) EasyMock + .getCurrentArguments()[0]; + RowItem item = (RowItem) EasyMock + .getCurrentArguments()[1]; + Statement statement = conn.createStatement(); + statement.executeUpdate( + "DELETE FROM people WHERE \"ID\"=" + item + .getItemProperty("ID").getValue()); + statement.close(); + return true; + } + }).anyTimes(); + EasyMock.expect( + delegate.getQueryString(EasyMock.anyInt(), EasyMock.anyInt())) + .andAnswer(new IAnswer<String>() { + @Override + public String answer() throws Throwable { + Object[] args = EasyMock.getCurrentArguments(); + int offset = (Integer) (args[0]); + int limit = (Integer) (args[1]); + if (SQLTestsConstants.db == DB.MSSQL) { + int start = offset + 1; + int end = offset + limit + 1; + String q = "SELECT * FROM (SELECT row_number() OVER" + + " ( ORDER BY \"ID\" ASC) AS rownum, * FROM people)" + + " AS a WHERE a.rownum BETWEEN " + start + + " AND " + end; + return q; + } else if (SQLTestsConstants.db == DB.ORACLE) { + int start = offset + 1; + int end = offset + limit + 1; + String q = "SELECT * FROM (SELECT x.*, ROWNUM AS r FROM" + + " (SELECT * FROM people ORDER BY \"ID\" ASC) x) " + + " WHERE r BETWEEN " + start + " AND " + + end; + return q; + } else { + return "SELECT * FROM people LIMIT " + limit + + " OFFSET " + offset; + } + } + }).anyTimes(); + delegate.setFilters(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setFilters(EasyMock.isA(List.class)); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(EasyMock.isA(List.class)); + EasyMock.expectLastCall().anyTimes(); + EasyMock.expect(delegate.getCountQuery()) + .andThrow(new UnsupportedOperationException()).anyTimes(); + + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + connectionPool, "ID"); + query.setDelegate(delegate); + EasyMock.replay(delegate); + SQLContainer container = new SQLContainer(query); + Object last = container.lastItemId(); + container.removeItem(last); + container.commit(); + Assert.assertFalse(last.equals(container.lastItemId())); + EasyMock.verify(delegate); + } + + @SuppressWarnings("unchecked") + @Test + public void commit_freeformLastItemUpdated_shouldUpdateRowInDB() + throws SQLException { + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + EasyMock.expect(delegate.storeRow(EasyMock.isA(Connection.class), + EasyMock.isA(RowItem.class))).andAnswer(new IAnswer<Integer>() { + @Override + public Integer answer() throws Throwable { + Connection conn = (Connection) EasyMock + .getCurrentArguments()[0]; + RowItem item = (RowItem) EasyMock + .getCurrentArguments()[1]; + Statement statement = conn.createStatement(); + statement.executeUpdate("UPDATE people SET \"NAME\"='" + + item.getItemProperty("NAME").getValue() + + "' WHERE \"ID\"=" + + item.getItemProperty("ID").getValue()); + statement.close(); + conn.commit(); + connectionPool.releaseConnection(conn); + return 1; + } + }).anyTimes(); + EasyMock.expect( + delegate.getQueryString(EasyMock.anyInt(), EasyMock.anyInt())) + .andAnswer(new IAnswer<String>() { + @Override + public String answer() throws Throwable { + Object[] args = EasyMock.getCurrentArguments(); + int offset = (Integer) (args[0]); + int limit = (Integer) (args[1]); + if (SQLTestsConstants.db == DB.MSSQL) { + int start = offset + 1; + int end = offset + limit + 1; + String q = "SELECT * FROM (SELECT row_number() OVER" + + " ( ORDER BY \"ID\" ASC) AS rownum, * FROM people)" + + " AS a WHERE a.rownum BETWEEN " + start + + " AND " + end; + return q; + } else if (SQLTestsConstants.db == DB.ORACLE) { + int start = offset + 1; + int end = offset + limit + 1; + String q = "SELECT * FROM (SELECT x.*, ROWNUM AS r FROM" + + " (SELECT * FROM people ORDER BY \"ID\" ASC) x) " + + " WHERE r BETWEEN " + start + " AND " + + end; + return q; + } else { + return "SELECT * FROM people LIMIT " + limit + + " OFFSET " + offset; + } + } + }).anyTimes(); + delegate.setFilters(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setFilters(EasyMock.isA(List.class)); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(EasyMock.isA(List.class)); + EasyMock.expectLastCall().anyTimes(); + EasyMock.expect(delegate.getCountQuery()) + .andThrow(new UnsupportedOperationException()).anyTimes(); + + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + connectionPool, "ID"); + query.setDelegate(delegate); + EasyMock.replay(delegate); + SQLContainer container = new SQLContainer(query); + Object last = container.lastItemId(); + container.getContainerProperty(last, "NAME").setValue("Donald"); + container.commit(); + Assert.assertEquals("Donald", + container.getContainerProperty(container.lastItemId(), "NAME") + .getValue()); + EasyMock.verify(delegate); + } + + @Test + public void rollback_freeformItemAdded_discardsAddedItem() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + int size = container.size(); + Object id = container.addItem(); + container.getContainerProperty(id, "NAME").setValue("foo"); + Assert.assertEquals(size + 1, container.size()); + container.rollback(); + Assert.assertEquals(size, container.size()); + Assert.assertFalse("foo".equals( + container.getContainerProperty(container.lastItemId(), "NAME") + .getValue())); + } + + @Test + public void rollback_freeformItemRemoved_restoresRemovedItem() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + int size = container.size(); + Object last = container.lastItemId(); + container.removeItem(last); + Assert.assertEquals(size - 1, container.size()); + container.rollback(); + Assert.assertEquals(size, container.size()); + Assert.assertEquals(last, container.lastItemId()); + } + + @Test + public void rollback_freeformItemChanged_discardsChanges() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Object last = container.lastItemId(); + container.getContainerProperty(last, "NAME").setValue("foo"); + container.rollback(); + Assert.assertFalse("foo".equals( + container.getContainerProperty(container.lastItemId(), "NAME") + .getValue())); + } + + @Test + public void itemChangeNotification_freeform_isModifiedReturnsTrue() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Assert.assertFalse(container.isModified()); + RowItem last = (RowItem) container.getItem(container.lastItemId()); + container.itemChangeNotification(last); + Assert.assertTrue(container.isModified()); + } + + @Test + public void itemSetChangeListeners_freeform_shouldFire() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + ItemSetChangeListener listener = EasyMock + .createMock(ItemSetChangeListener.class); + listener.containerItemSetChange(EasyMock.isA(ItemSetChangeEvent.class)); + EasyMock.replay(listener); + + container.addListener(listener); + container.addItem(); + + EasyMock.verify(listener); + } + + @Test + public void itemSetChangeListeners_freeformItemRemoved_shouldFire() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + ItemSetChangeListener listener = EasyMock + .createMock(ItemSetChangeListener.class); + listener.containerItemSetChange(EasyMock.isA(ItemSetChangeEvent.class)); + EasyMock.expectLastCall().anyTimes(); + EasyMock.replay(listener); + + container.addListener(listener); + container.removeItem(container.lastItemId()); + + EasyMock.verify(listener); + } + + @Test + public void removeListener_freeform_shouldNotFire() throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + ItemSetChangeListener listener = EasyMock + .createMock(ItemSetChangeListener.class); + EasyMock.replay(listener); + + container.addListener(listener); + container.removeListener(listener); + container.addItem(); + + EasyMock.verify(listener); + } + + @Test + public void isModified_freeformRemovedItem_returnsTrue() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Assert.assertFalse(container.isModified()); + container.removeItem(container.lastItemId()); + Assert.assertTrue(container.isModified()); + } + + @Test + public void isModified_freeformAddedItem_returnsTrue() throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Assert.assertFalse(container.isModified()); + container.addItem(); + Assert.assertTrue(container.isModified()); + } + + @Test + public void isModified_freeformChangedItem_returnsTrue() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Assert.assertFalse(container.isModified()); + container.getContainerProperty(container.lastItemId(), "NAME") + .setValue("foo"); + Assert.assertTrue(container.isModified()); + } + + @Test + public void getSortableContainerPropertyIds_freeform_returnsAllPropertyIds() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + Collection<?> sortableIds = container.getSortableContainerPropertyIds(); + Assert.assertTrue(sortableIds.contains("ID")); + Assert.assertTrue(sortableIds.contains("NAME")); + Assert.assertTrue(sortableIds.contains("AGE")); + Assert.assertEquals(3, sortableIds.size()); + } + + @SuppressWarnings("unchecked") + @Test + public void addOrderBy_freeform_shouldReorderResults() throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + connectionPool, "ID"); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + final ArrayList<OrderBy> orderBys = new ArrayList<OrderBy>(); + delegate.setFilters(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setFilters(EasyMock.isA(List.class)); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(EasyMock.isA(List.class)); + EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() { + @Override + public Object answer() throws Throwable { + List<OrderBy> orders = (List<OrderBy>) EasyMock + .getCurrentArguments()[0]; + orderBys.clear(); + orderBys.addAll(orders); + return null; + } + }).anyTimes(); + EasyMock.expect( + delegate.getQueryString(EasyMock.anyInt(), EasyMock.anyInt())) + .andAnswer(new IAnswer<String>() { + @Override + public String answer() throws Throwable { + Object[] args = EasyMock.getCurrentArguments(); + int offset = (Integer) (args[0]); + int limit = (Integer) (args[1]); + if (SQLTestsConstants.db == DB.MSSQL) { + SQLGenerator gen = new MSSQLGenerator(); + if (orderBys == null || orderBys.isEmpty()) { + List<OrderBy> ob = new ArrayList<OrderBy>(); + ob.add(new OrderBy("ID", true)); + return gen + .generateSelectQuery("people", null, ob, + offset, limit, null) + .getQueryString(); + } else { + return gen + .generateSelectQuery("people", null, + orderBys, offset, limit, null) + .getQueryString(); + } + } else if (SQLTestsConstants.db == DB.ORACLE) { + SQLGenerator gen = new OracleGenerator(); + if (orderBys == null || orderBys.isEmpty()) { + List<OrderBy> ob = new ArrayList<OrderBy>(); + ob.add(new OrderBy("ID", true)); + return gen + .generateSelectQuery("people", null, ob, + offset, limit, null) + .getQueryString(); + } else { + return gen + .generateSelectQuery("people", null, + orderBys, offset, limit, null) + .getQueryString(); + } + } else { + StringBuffer query = new StringBuffer( + "SELECT * FROM people"); + if (!orderBys.isEmpty()) { + query.append(" ORDER BY "); + for (OrderBy orderBy : orderBys) { + query.append( + "\"" + orderBy.getColumn() + "\""); + if (orderBy.isAscending()) { + query.append(" ASC"); + } else { + query.append(" DESC"); + } + } + } + query.append(" LIMIT ").append(limit) + .append(" OFFSET ").append(offset); + return query.toString(); + } + } + }).anyTimes(); + EasyMock.expect(delegate.getCountQuery()) + .andThrow(new UnsupportedOperationException()).anyTimes(); + + EasyMock.replay(delegate); + query.setDelegate(delegate); + SQLContainer container = new SQLContainer(query); + // Ville, Kalle, Pelle, Börje + Assert.assertEquals("Ville", + container.getContainerProperty(container.firstItemId(), "NAME") + .getValue()); + Assert.assertEquals("Börje", + container.getContainerProperty(container.lastItemId(), "NAME") + .getValue()); + + container.addOrderBy(new OrderBy("NAME", true)); + // Börje, Kalle, Pelle, Ville + Assert.assertEquals("Börje", + container.getContainerProperty(container.firstItemId(), "NAME") + .getValue()); + Assert.assertEquals("Ville", + container.getContainerProperty(container.lastItemId(), "NAME") + .getValue()); + + EasyMock.verify(delegate); + } + + @Test(expected = IllegalArgumentException.class) + public void addOrderBy_freeformIllegalColumn_shouldFail() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", connectionPool, "ID")); + container.addOrderBy(new OrderBy("asdf", true)); + } + + @SuppressWarnings("unchecked") + @Test + public void sort_freeform_sortsByName() throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + connectionPool, "ID"); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + final ArrayList<OrderBy> orderBys = new ArrayList<OrderBy>(); + delegate.setFilters(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setFilters(EasyMock.isA(List.class)); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(EasyMock.isA(List.class)); + EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() { + @Override + public Object answer() throws Throwable { + List<OrderBy> orders = (List<OrderBy>) EasyMock + .getCurrentArguments()[0]; + orderBys.clear(); + orderBys.addAll(orders); + return null; + } + }).anyTimes(); + EasyMock.expect( + delegate.getQueryString(EasyMock.anyInt(), EasyMock.anyInt())) + .andAnswer(new IAnswer<String>() { + @Override + public String answer() throws Throwable { + Object[] args = EasyMock.getCurrentArguments(); + int offset = (Integer) (args[0]); + int limit = (Integer) (args[1]); + if (SQLTestsConstants.db == DB.MSSQL) { + SQLGenerator gen = new MSSQLGenerator(); + if (orderBys == null || orderBys.isEmpty()) { + List<OrderBy> ob = new ArrayList<OrderBy>(); + ob.add(new OrderBy("ID", true)); + return gen + .generateSelectQuery("people", null, ob, + offset, limit, null) + .getQueryString(); + } else { + return gen + .generateSelectQuery("people", null, + orderBys, offset, limit, null) + .getQueryString(); + } + } else if (SQLTestsConstants.db == DB.ORACLE) { + SQLGenerator gen = new OracleGenerator(); + if (orderBys == null || orderBys.isEmpty()) { + List<OrderBy> ob = new ArrayList<OrderBy>(); + ob.add(new OrderBy("ID", true)); + return gen + .generateSelectQuery("people", null, ob, + offset, limit, null) + .getQueryString(); + } else { + return gen + .generateSelectQuery("people", null, + orderBys, offset, limit, null) + .getQueryString(); + } + } else { + StringBuffer query = new StringBuffer( + "SELECT * FROM people"); + if (!orderBys.isEmpty()) { + query.append(" ORDER BY "); + for (OrderBy orderBy : orderBys) { + query.append( + "\"" + orderBy.getColumn() + "\""); + if (orderBy.isAscending()) { + query.append(" ASC"); + } else { + query.append(" DESC"); + } + } + } + query.append(" LIMIT ").append(limit) + .append(" OFFSET ").append(offset); + return query.toString(); + } + } + }).anyTimes(); + EasyMock.expect(delegate.getCountQuery()) + .andThrow(new UnsupportedOperationException()).anyTimes(); + EasyMock.replay(delegate); + + query.setDelegate(delegate); + SQLContainer container = new SQLContainer(query); + // Ville, Kalle, Pelle, Börje + Assert.assertEquals("Ville", + container.getContainerProperty(container.firstItemId(), "NAME") + .getValue()); + Assert.assertEquals("Börje", + container.getContainerProperty(container.lastItemId(), "NAME") + .getValue()); + + container.sort(new Object[] { "NAME" }, new boolean[] { true }); + + // Börje, Kalle, Pelle, Ville + Assert.assertEquals("Börje", + container.getContainerProperty(container.firstItemId(), "NAME") + .getValue()); + Assert.assertEquals("Ville", + container.getContainerProperty(container.lastItemId(), "NAME") + .getValue()); + + EasyMock.verify(delegate); + } + + @SuppressWarnings("unchecked") + @Test + public void addFilter_freeform_filtersResults() throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + connectionPool, "ID"); + FreeformStatementDelegate delegate = EasyMock + .createMock(FreeformStatementDelegate.class); + final ArrayList<Filter> filters = new ArrayList<Filter>(); + delegate.setFilters(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(EasyMock.isA(List.class)); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setFilters(EasyMock.isA(List.class)); + EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() { + @Override + public Object answer() throws Throwable { + List<Filter> orders = (List<Filter>) EasyMock + .getCurrentArguments()[0]; + filters.clear(); + filters.addAll(orders); + return null; + } + }).anyTimes(); + EasyMock.expect(delegate.getQueryStatement(EasyMock.anyInt(), + EasyMock.anyInt())).andAnswer(new IAnswer<StatementHelper>() { + @Override + public StatementHelper answer() throws Throwable { + Object[] args = EasyMock.getCurrentArguments(); + int offset = (Integer) (args[0]); + int limit = (Integer) (args[1]); + return FreeformQueryUtil.getQueryWithFilters(filters, + offset, limit); + } + }).anyTimes(); + EasyMock.expect(delegate.getCountStatement()) + .andAnswer(new IAnswer<StatementHelper>() { + @Override + public StatementHelper answer() throws Throwable { + StatementHelper sh = new StatementHelper(); + StringBuffer query = new StringBuffer( + "SELECT COUNT(*) FROM people"); + if (!filters.isEmpty()) { + query.append(QueryBuilder + .getWhereStringForFilters(filters, sh)); + } + sh.setQueryString(query.toString()); + return sh; + } + }).anyTimes(); + + EasyMock.replay(delegate); + query.setDelegate(delegate); + SQLContainer container = new SQLContainer(query); + // Ville, Kalle, Pelle, Börje + Assert.assertEquals(4, container.size()); + Assert.assertEquals("Börje", + container.getContainerProperty(container.lastItemId(), "NAME") + .getValue()); + + container.addContainerFilter(new Like("NAME", "%lle")); + // Ville, Kalle, Pelle + Assert.assertEquals(3, container.size()); + Assert.assertEquals("Pelle", + container.getContainerProperty(container.lastItemId(), "NAME") + .getValue()); + + EasyMock.verify(delegate); + } + + @SuppressWarnings("unchecked") + @Test + public void addContainerFilter_filtersResults() throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + connectionPool, "ID"); + FreeformStatementDelegate delegate = EasyMock + .createMock(FreeformStatementDelegate.class); + final ArrayList<Filter> filters = new ArrayList<Filter>(); + delegate.setFilters(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(EasyMock.isA(List.class)); + EasyMock.expectLastCall().anyTimes(); + delegate.setFilters(EasyMock.isA(List.class)); + EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() { + @Override + public Object answer() throws Throwable { + List<Filter> orders = (List<Filter>) EasyMock + .getCurrentArguments()[0]; + filters.clear(); + filters.addAll(orders); + return null; + } + }).anyTimes(); + EasyMock.expect(delegate.getQueryStatement(EasyMock.anyInt(), + EasyMock.anyInt())).andAnswer(new IAnswer<StatementHelper>() { + @Override + public StatementHelper answer() throws Throwable { + Object[] args = EasyMock.getCurrentArguments(); + int offset = (Integer) (args[0]); + int limit = (Integer) (args[1]); + return FreeformQueryUtil.getQueryWithFilters(filters, + offset, limit); + } + }).anyTimes(); + EasyMock.expect(delegate.getCountStatement()) + .andAnswer(new IAnswer<StatementHelper>() { + @Override + public StatementHelper answer() throws Throwable { + StatementHelper sh = new StatementHelper(); + StringBuffer query = new StringBuffer( + "SELECT COUNT(*) FROM people"); + if (!filters.isEmpty()) { + query.append(QueryBuilder + .getWhereStringForFilters(filters, sh)); + } + sh.setQueryString(query.toString()); + return sh; + } + }).anyTimes(); + + EasyMock.replay(delegate); + query.setDelegate(delegate); + SQLContainer container = new SQLContainer(query); + // Ville, Kalle, Pelle, Börje + Assert.assertEquals(4, container.size()); + + container.addContainerFilter("NAME", "Vi", false, false); + + // Ville + Assert.assertEquals(1, container.size()); + Assert.assertEquals("Ville", + container.getContainerProperty(container.lastItemId(), "NAME") + .getValue()); + + EasyMock.verify(delegate); + } + + @SuppressWarnings("unchecked") + @Test + public void addContainerFilter_ignoreCase_filtersResults() + throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + connectionPool, "ID"); + FreeformStatementDelegate delegate = EasyMock + .createMock(FreeformStatementDelegate.class); + final ArrayList<Filter> filters = new ArrayList<Filter>(); + delegate.setFilters(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(EasyMock.isA(List.class)); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setFilters(EasyMock.isA(List.class)); + EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() { + @Override + public Object answer() throws Throwable { + List<Filter> orders = (List<Filter>) EasyMock + .getCurrentArguments()[0]; + filters.clear(); + filters.addAll(orders); + return null; + } + }).anyTimes(); + EasyMock.expect(delegate.getQueryStatement(EasyMock.anyInt(), + EasyMock.anyInt())).andAnswer(new IAnswer<StatementHelper>() { + @Override + public StatementHelper answer() throws Throwable { + Object[] args = EasyMock.getCurrentArguments(); + int offset = (Integer) (args[0]); + int limit = (Integer) (args[1]); + return FreeformQueryUtil.getQueryWithFilters(filters, + offset, limit); + } + }).anyTimes(); + EasyMock.expect(delegate.getCountStatement()) + .andAnswer(new IAnswer<StatementHelper>() { + @Override + public StatementHelper answer() throws Throwable { + StatementHelper sh = new StatementHelper(); + StringBuffer query = new StringBuffer( + "SELECT COUNT(*) FROM people"); + if (!filters.isEmpty()) { + query.append(QueryBuilder + .getWhereStringForFilters(filters, sh)); + } + sh.setQueryString(query.toString()); + return sh; + } + }).anyTimes(); + + EasyMock.replay(delegate); + query.setDelegate(delegate); + SQLContainer container = new SQLContainer(query); + // Ville, Kalle, Pelle, Börje + Assert.assertEquals(4, container.size()); + + // FIXME LIKE %asdf% doesn't match a string that begins with asdf + container.addContainerFilter("NAME", "vi", true, true); + + // Ville + Assert.assertEquals(1, container.size()); + Assert.assertEquals("Ville", + container.getContainerProperty(container.lastItemId(), "NAME") + .getValue()); + + EasyMock.verify(delegate); + } + + @SuppressWarnings("unchecked") + @Test + public void removeAllContainerFilters_freeform_noFiltering() + throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + connectionPool, "ID"); + FreeformStatementDelegate delegate = EasyMock + .createMock(FreeformStatementDelegate.class); + final ArrayList<Filter> filters = new ArrayList<Filter>(); + delegate.setFilters(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(EasyMock.isA(List.class)); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setFilters(EasyMock.isA(List.class)); + EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() { + @Override + public Object answer() throws Throwable { + List<Filter> orders = (List<Filter>) EasyMock + .getCurrentArguments()[0]; + filters.clear(); + filters.addAll(orders); + return null; + } + }).anyTimes(); + EasyMock.expect(delegate.getQueryStatement(EasyMock.anyInt(), + EasyMock.anyInt())).andAnswer(new IAnswer<StatementHelper>() { + @Override + public StatementHelper answer() throws Throwable { + Object[] args = EasyMock.getCurrentArguments(); + int offset = (Integer) (args[0]); + int limit = (Integer) (args[1]); + return FreeformQueryUtil.getQueryWithFilters(filters, + offset, limit); + } + }).anyTimes(); + EasyMock.expect(delegate.getCountStatement()) + .andAnswer(new IAnswer<StatementHelper>() { + @Override + public StatementHelper answer() throws Throwable { + StatementHelper sh = new StatementHelper(); + StringBuffer query = new StringBuffer( + "SELECT COUNT(*) FROM people"); + if (!filters.isEmpty()) { + query.append(QueryBuilder + .getWhereStringForFilters(filters, sh)); + } + sh.setQueryString(query.toString()); + return sh; + } + }).anyTimes(); + + EasyMock.replay(delegate); + query.setDelegate(delegate); + SQLContainer container = new SQLContainer(query); + // Ville, Kalle, Pelle, Börje + Assert.assertEquals(4, container.size()); + + container.addContainerFilter("NAME", "Vi", false, false); + + // Ville + Assert.assertEquals(1, container.size()); + Assert.assertEquals("Ville", + container.getContainerProperty(container.lastItemId(), "NAME") + .getValue()); + + container.removeAllContainerFilters(); + + Assert.assertEquals(4, container.size()); + Assert.assertEquals("Börje", + container.getContainerProperty(container.lastItemId(), "NAME") + .getValue()); + + EasyMock.verify(delegate); + } + + @SuppressWarnings("unchecked") + @Test + public void removeContainerFilters_freeform_noFiltering() + throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + connectionPool, "ID"); + FreeformStatementDelegate delegate = EasyMock + .createMock(FreeformStatementDelegate.class); + final ArrayList<Filter> filters = new ArrayList<Filter>(); + delegate.setFilters(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(EasyMock.isA(List.class)); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setFilters(EasyMock.isA(List.class)); + EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() { + @Override + public Object answer() throws Throwable { + List<Filter> orders = (List<Filter>) EasyMock + .getCurrentArguments()[0]; + filters.clear(); + filters.addAll(orders); + return null; + } + }).anyTimes(); + EasyMock.expect(delegate.getQueryStatement(EasyMock.anyInt(), + EasyMock.anyInt())).andAnswer(new IAnswer<StatementHelper>() { + @Override + public StatementHelper answer() throws Throwable { + Object[] args = EasyMock.getCurrentArguments(); + int offset = (Integer) (args[0]); + int limit = (Integer) (args[1]); + return FreeformQueryUtil.getQueryWithFilters(filters, + offset, limit); + } + }).anyTimes(); + EasyMock.expect(delegate.getCountStatement()) + .andAnswer(new IAnswer<StatementHelper>() { + @Override + public StatementHelper answer() throws Throwable { + StatementHelper sh = new StatementHelper(); + StringBuffer query = new StringBuffer( + "SELECT COUNT(*) FROM people"); + if (!filters.isEmpty()) { + query.append(QueryBuilder + .getWhereStringForFilters(filters, sh)); + } + sh.setQueryString(query.toString()); + return sh; + } + }).anyTimes(); + + EasyMock.replay(delegate); + query.setDelegate(delegate); + SQLContainer container = new SQLContainer(query); + // Ville, Kalle, Pelle, Börje + Assert.assertEquals(4, container.size()); + + container.addContainerFilter("NAME", "Vi", false, true); + + // Ville + Assert.assertEquals(1, container.size()); + Assert.assertEquals("Ville", + container.getContainerProperty(container.lastItemId(), "NAME") + .getValue()); + + container.removeContainerFilters("NAME"); + + Assert.assertEquals(4, container.size()); + Assert.assertEquals("Börje", + container.getContainerProperty(container.lastItemId(), "NAME") + .getValue()); + + EasyMock.verify(delegate); + } + + @SuppressWarnings("unchecked") + @Test + public void addFilter_freeformBufferedItems_alsoFiltersBufferedItems() + throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + connectionPool, "ID"); + FreeformStatementDelegate delegate = EasyMock + .createMock(FreeformStatementDelegate.class); + final ArrayList<Filter> filters = new ArrayList<Filter>(); + delegate.setFilters(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(EasyMock.isA(List.class)); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setFilters(EasyMock.isA(List.class)); + EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() { + @Override + public Object answer() throws Throwable { + List<Filter> orders = (List<Filter>) EasyMock + .getCurrentArguments()[0]; + filters.clear(); + filters.addAll(orders); + return null; + } + }).anyTimes(); + EasyMock.expect(delegate.getQueryStatement(EasyMock.anyInt(), + EasyMock.anyInt())).andAnswer(new IAnswer<StatementHelper>() { + @Override + public StatementHelper answer() throws Throwable { + Object[] args = EasyMock.getCurrentArguments(); + int offset = (Integer) (args[0]); + int limit = (Integer) (args[1]); + return FreeformQueryUtil.getQueryWithFilters(filters, + offset, limit); + } + }).anyTimes(); + EasyMock.expect(delegate.getCountStatement()) + .andAnswer(new IAnswer<StatementHelper>() { + @Override + public StatementHelper answer() throws Throwable { + StatementHelper sh = new StatementHelper(); + StringBuffer query = new StringBuffer( + "SELECT COUNT(*) FROM people"); + if (!filters.isEmpty()) { + query.append(QueryBuilder + .getWhereStringForFilters(filters, sh)); + } + sh.setQueryString(query.toString()); + return sh; + } + }).anyTimes(); + + EasyMock.replay(delegate); + query.setDelegate(delegate); + SQLContainer container = new SQLContainer(query); + // Ville, Kalle, Pelle, Börje + Assert.assertEquals(4, container.size()); + Assert.assertEquals("Börje", + container.getContainerProperty(container.lastItemId(), "NAME") + .getValue()); + + Object id1 = container.addItem(); + container.getContainerProperty(id1, "NAME").setValue("Palle"); + Object id2 = container.addItem(); + container.getContainerProperty(id2, "NAME").setValue("Bengt"); + + container.addContainerFilter(new Like("NAME", "%lle")); + + // Ville, Kalle, Pelle, Palle + Assert.assertEquals(4, container.size()); + Assert.assertEquals("Ville", + container + .getContainerProperty(container.getIdByIndex(0), "NAME") + .getValue()); + Assert.assertEquals("Kalle", + container + .getContainerProperty(container.getIdByIndex(1), "NAME") + .getValue()); + Assert.assertEquals("Pelle", + container + .getContainerProperty(container.getIdByIndex(2), "NAME") + .getValue()); + Assert.assertEquals("Palle", + container + .getContainerProperty(container.getIdByIndex(3), "NAME") + .getValue()); + + try { + container.getIdByIndex(4); + Assert.fail( + "SQLContainer.getIdByIndex() returned a value for an index beyond the end of the container"); + } catch (IndexOutOfBoundsException e) { + // should throw exception - item is filtered out + } + container.nextItemId(container.getIdByIndex(3)); + + Assert.assertFalse(container.containsId(id2)); + Assert.assertFalse(container.getItemIds().contains(id2)); + + Assert.assertNull(container.getItem(id2)); + Assert.assertEquals(-1, container.indexOfId(id2)); + + Assert.assertNotSame(id2, container.lastItemId()); + Assert.assertSame(id1, container.lastItemId()); + + EasyMock.verify(delegate); + } + + @SuppressWarnings("unchecked") + @Test + public void sort_freeformBufferedItems_sortsBufferedItemsLastInOrderAdded() + throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + connectionPool, "ID"); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + final ArrayList<OrderBy> orderBys = new ArrayList<OrderBy>(); + delegate.setFilters(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setFilters(EasyMock.isA(List.class)); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(EasyMock.isA(List.class)); + EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() { + @Override + public Object answer() throws Throwable { + List<OrderBy> orders = (List<OrderBy>) EasyMock + .getCurrentArguments()[0]; + orderBys.clear(); + orderBys.addAll(orders); + return null; + } + }).anyTimes(); + EasyMock.expect( + delegate.getQueryString(EasyMock.anyInt(), EasyMock.anyInt())) + .andAnswer(new IAnswer<String>() { + @Override + public String answer() throws Throwable { + Object[] args = EasyMock.getCurrentArguments(); + int offset = (Integer) (args[0]); + int limit = (Integer) (args[1]); + if (SQLTestsConstants.db == DB.MSSQL) { + SQLGenerator gen = new MSSQLGenerator(); + if (orderBys == null || orderBys.isEmpty()) { + List<OrderBy> ob = new ArrayList<OrderBy>(); + ob.add(new OrderBy("ID", true)); + return gen + .generateSelectQuery("people", null, ob, + offset, limit, null) + .getQueryString(); + } else { + return gen + .generateSelectQuery("people", null, + orderBys, offset, limit, null) + .getQueryString(); + } + } else if (SQLTestsConstants.db == DB.ORACLE) { + SQLGenerator gen = new OracleGenerator(); + if (orderBys == null || orderBys.isEmpty()) { + List<OrderBy> ob = new ArrayList<OrderBy>(); + ob.add(new OrderBy("ID", true)); + return gen + .generateSelectQuery("people", null, ob, + offset, limit, null) + .getQueryString(); + } else { + return gen + .generateSelectQuery("people", null, + orderBys, offset, limit, null) + .getQueryString(); + } + } else { + StringBuffer query = new StringBuffer( + "SELECT * FROM people"); + if (!orderBys.isEmpty()) { + query.append(" ORDER BY "); + for (OrderBy orderBy : orderBys) { + query.append( + "\"" + orderBy.getColumn() + "\""); + if (orderBy.isAscending()) { + query.append(" ASC"); + } else { + query.append(" DESC"); + } + } + } + query.append(" LIMIT ").append(limit) + .append(" OFFSET ").append(offset); + return query.toString(); + } + } + }).anyTimes(); + EasyMock.expect(delegate.getCountQuery()) + .andThrow(new UnsupportedOperationException()).anyTimes(); + EasyMock.replay(delegate); + + query.setDelegate(delegate); + SQLContainer container = new SQLContainer(query); + // Ville, Kalle, Pelle, Börje + Assert.assertEquals("Ville", + container.getContainerProperty(container.firstItemId(), "NAME") + .getValue()); + Assert.assertEquals("Börje", + container.getContainerProperty(container.lastItemId(), "NAME") + .getValue()); + + Object id1 = container.addItem(); + container.getContainerProperty(id1, "NAME").setValue("Wilbert"); + Object id2 = container.addItem(); + container.getContainerProperty(id2, "NAME").setValue("Albert"); + + container.sort(new Object[] { "NAME" }, new boolean[] { true }); + + // Börje, Kalle, Pelle, Ville, Wilbert, Albert + Assert.assertEquals("Börje", + container.getContainerProperty(container.firstItemId(), "NAME") + .getValue()); + Assert.assertEquals("Wilbert", + container.getContainerProperty( + container.getIdByIndex(container.size() - 2), "NAME") + .getValue()); + Assert.assertEquals("Albert", + container.getContainerProperty(container.lastItemId(), "NAME") + .getValue()); + + EasyMock.verify(delegate); + } + +} diff --git a/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLTestsConstants.java b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLTestsConstants.java new file mode 100755 index 0000000000..3718cf756d --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLTestsConstants.java @@ -0,0 +1,154 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.data.util.sqlcontainer; + +import com.vaadin.data.util.sqlcontainer.query.generator.DefaultSQLGenerator; +import com.vaadin.data.util.sqlcontainer.query.generator.MSSQLGenerator; +import com.vaadin.data.util.sqlcontainer.query.generator.OracleGenerator; +import com.vaadin.data.util.sqlcontainer.query.generator.SQLGenerator; + +public class SQLTestsConstants { + + /* Set the DB used for testing here! */ + public enum DB { + HSQLDB, MYSQL, POSTGRESQL, MSSQL, ORACLE; + } + + /* 0 = HSQLDB, 1 = MYSQL, 2 = POSTGRESQL, 3 = MSSQL, 4 = ORACLE */ + public static final DB db = DB.HSQLDB; + + /* Auto-increment column offset (HSQLDB = 0, MYSQL = 1, POSTGRES = 1) */ + public static int offset; + /* Garbage table creation query (=three queries for oracle) */ + public static String createGarbage; + public static String createGarbageSecond; + public static String createGarbageThird; + /* DB Drivers, urls, usernames and passwords */ + public static String dbDriver; + public static String dbURL; + public static String dbUser; + public static String dbPwd; + /* People -test table creation statement(s) */ + public static String peopleFirst; + public static String peopleSecond; + public static String peopleThird; + /* Schema test creation statement(s) */ + public static String createSchema; + public static String createProductTable; + public static String dropSchema; + /* Versioned -test table createion statement(s) */ + public static String[] versionStatements; + /* SQL Generator used during the testing */ + public static SQLGenerator sqlGen; + + /* Set DB-specific settings based on selected DB */ + static { + sqlGen = new DefaultSQLGenerator(); + switch (db) { + case HSQLDB: + offset = 0; + createGarbage = "create table garbage (id integer generated always as identity, type varchar(32), PRIMARY KEY(id))"; + dbDriver = "org.hsqldb.jdbc.JDBCDriver"; + dbURL = "jdbc:hsqldb:mem:sqlcontainer"; + dbUser = "SA"; + dbPwd = ""; + peopleFirst = "create table people (id integer generated always as identity, name varchar(32), AGE INTEGER)"; + peopleSecond = "alter table people add primary key (id)"; + versionStatements = new String[] { + "create table versioned (id integer generated always as identity, text varchar(255), version tinyint default 0)", + "alter table versioned add primary key (id)" }; + // TODO these should ideally exist for all databases + createSchema = "create schema oaas authorization DBA"; + createProductTable = "create table oaas.product (\"ID\" integer generated always as identity primary key, \"NAME\" VARCHAR(32))"; + dropSchema = "drop schema if exists oaas cascade"; + break; + case MYSQL: + offset = 1; + createGarbage = "create table GARBAGE (ID integer auto_increment, type varchar(32), PRIMARY KEY(ID))"; + dbDriver = "com.mysql.jdbc.Driver"; + dbURL = "jdbc:mysql:///sqlcontainer"; + dbUser = "sqlcontainer"; + dbPwd = "sqlcontainer"; + peopleFirst = "create table PEOPLE (ID integer auto_increment not null, NAME varchar(32), AGE INTEGER, primary key(ID))"; + peopleSecond = null; + versionStatements = new String[] { + "create table VERSIONED (ID integer auto_increment not null, TEXT varchar(255), VERSION tinyint default 0, primary key(ID))", + "CREATE TRIGGER upd_version BEFORE UPDATE ON VERSIONED" + + " FOR EACH ROW SET NEW.VERSION = OLD.VERSION+1" }; + break; + case POSTGRESQL: + offset = 1; + createGarbage = "create table GARBAGE (\"ID\" serial PRIMARY KEY, \"TYPE\" varchar(32))"; + dbDriver = "org.postgresql.Driver"; + dbURL = "jdbc:postgresql://localhost:5432/test"; + dbUser = "postgres"; + dbPwd = "postgres"; + peopleFirst = "create table PEOPLE (\"ID\" serial primary key, \"NAME\" VARCHAR(32), \"AGE\" INTEGER)"; + peopleSecond = null; + versionStatements = new String[] { + "create table VERSIONED (\"ID\" serial primary key, \"TEXT\" VARCHAR(255), \"VERSION\" INTEGER DEFAULT 0)", + "CREATE OR REPLACE FUNCTION zz_row_version() RETURNS TRIGGER AS $$" + + "BEGIN" + " IF TG_OP = 'UPDATE'" + + " AND NEW.\"VERSION\" = old.\"VERSION\"" + + " AND ROW(NEW.*) IS DISTINCT FROM ROW (old.*)" + + " THEN" + + " NEW.\"VERSION\" := NEW.\"VERSION\" + 1;" + + " END IF;" + " RETURN NEW;" + "END;" + + "$$ LANGUAGE plpgsql;", + "CREATE TRIGGER \"mytable_modify_dt_tr\" BEFORE UPDATE" + + " ON VERSIONED FOR EACH ROW" + + " EXECUTE PROCEDURE \"public\".\"zz_row_version\"();" }; + createSchema = "create schema oaas"; + createProductTable = "create table oaas.product (\"ID\" serial primary key, \"NAME\" VARCHAR(32))"; + dropSchema = "drop schema oaas cascade"; + break; + case MSSQL: + offset = 1; + createGarbage = "create table GARBAGE (\"ID\" int identity(1,1) primary key, \"TYPE\" varchar(32))"; + dbDriver = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; + dbURL = "jdbc:sqlserver://localhost:1433;databaseName=tempdb;"; + dbUser = "sa"; + dbPwd = "sa"; + peopleFirst = "create table PEOPLE (\"ID\" int identity(1,1) primary key, \"NAME\" VARCHAR(32), \"AGE\" INTEGER)"; + peopleSecond = null; + versionStatements = new String[] { + "create table VERSIONED (\"ID\" int identity(1,1) primary key, \"TEXT\" VARCHAR(255), \"VERSION\" rowversion not null)" }; + sqlGen = new MSSQLGenerator(); + break; + case ORACLE: + offset = 1; + createGarbage = "create table GARBAGE (\"ID\" integer primary key, \"TYPE\" varchar2(32))"; + createGarbageSecond = "create sequence garbage_seq start with 1 increment by 1 nomaxvalue"; + createGarbageThird = "create trigger garbage_trigger before insert on GARBAGE for each row begin select garbage_seq.nextval into :new.ID from dual; end;"; + dbDriver = "oracle.jdbc.OracleDriver"; + dbURL = "jdbc:oracle:thin:test/test@localhost:1521:XE"; + dbUser = "test"; + dbPwd = "test"; + peopleFirst = "create table PEOPLE (\"ID\" integer primary key, \"NAME\" VARCHAR2(32), \"AGE\" INTEGER)"; + peopleSecond = "create sequence people_seq start with 1 increment by 1 nomaxvalue"; + peopleThird = "create trigger people_trigger before insert on PEOPLE for each row begin select people_seq.nextval into :new.ID from dual; end;"; + versionStatements = new String[] { + "create table VERSIONED (\"ID\" integer primary key, \"TEXT\" VARCHAR(255), \"VERSION\" INTEGER DEFAULT 0)", + "create sequence versioned_seq start with 1 increment by 1 nomaxvalue", + "create trigger versioned_trigger before insert on VERSIONED for each row begin select versioned_seq.nextval into :new.ID from dual; end;", + "create sequence versioned_version start with 1 increment by 1 nomaxvalue", + "create trigger versioned_version_trigger before insert or update on VERSIONED for each row begin select versioned_version.nextval into :new.VERSION from dual; end;" }; + sqlGen = new OracleGenerator(); + break; + } + } + +} diff --git a/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/TicketTest.java b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/TicketTest.java new file mode 100644 index 0000000000..1a19eda542 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/TicketTest.java @@ -0,0 +1,195 @@ +package com.vaadin.data.util.sqlcontainer; + +import java.math.BigDecimal; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.easymock.EasyMock; +import org.easymock.IAnswer; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.data.Container.Filter; +import com.vaadin.data.Item; +import com.vaadin.data.util.filter.Compare.Equal; +import com.vaadin.data.util.sqlcontainer.SQLTestsConstants.DB; +import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool; +import com.vaadin.data.util.sqlcontainer.query.FreeformQuery; +import com.vaadin.data.util.sqlcontainer.query.FreeformStatementDelegate; +import com.vaadin.data.util.sqlcontainer.query.TableQuery; +import com.vaadin.data.util.sqlcontainer.query.ValidatingSimpleJDBCConnectionPool; +import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; +import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder; +import com.vaadin.ui.Table; +import com.vaadin.ui.Window; + +public class TicketTest { + + private JDBCConnectionPool connectionPool; + + @Before + public void setUp() throws SQLException { + connectionPool = new ValidatingSimpleJDBCConnectionPool( + SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL, + SQLTestsConstants.dbUser, SQLTestsConstants.dbPwd, 2, 2); + DataGenerator.addPeopleToDatabase(connectionPool); + } + + @Test + public void ticket5867_throwsIllegalState_transactionAlreadyActive() + throws SQLException { + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people", Arrays.asList("ID"), connectionPool)); + Table table = new Table(); + Window w = new Window(); + w.setContent(table); + table.setContainerDataSource(container); + } + + @SuppressWarnings("unchecked") + @Test + public void ticket6136_freeform_ageIs18() throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + FreeformStatementDelegate delegate = EasyMock + .createMock(FreeformStatementDelegate.class); + final ArrayList<Filter> filters = new ArrayList<Filter>(); + delegate.setFilters(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(EasyMock.isA(List.class)); + EasyMock.expectLastCall().anyTimes(); + delegate.setOrderBy(null); + EasyMock.expectLastCall().anyTimes(); + delegate.setFilters(EasyMock.isA(List.class)); + EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() { + @Override + public Object answer() throws Throwable { + List<Filter> orders = (List<Filter>) EasyMock + .getCurrentArguments()[0]; + filters.clear(); + filters.addAll(orders); + return null; + } + }).anyTimes(); + EasyMock.expect(delegate.getQueryStatement(EasyMock.anyInt(), + EasyMock.anyInt())).andAnswer(new IAnswer<StatementHelper>() { + @Override + public StatementHelper answer() throws Throwable { + Object[] args = EasyMock.getCurrentArguments(); + int offset = (Integer) (args[0]); + int limit = (Integer) (args[1]); + return FreeformQueryUtil.getQueryWithFilters(filters, + offset, limit); + } + }).anyTimes(); + EasyMock.expect(delegate.getCountStatement()) + .andAnswer(new IAnswer<StatementHelper>() { + @Override + public StatementHelper answer() throws Throwable { + StatementHelper sh = new StatementHelper(); + StringBuffer query = new StringBuffer( + "SELECT COUNT(*) FROM people"); + if (!filters.isEmpty()) { + query.append(QueryBuilder + .getWhereStringForFilters(filters, sh)); + } + sh.setQueryString(query.toString()); + return sh; + } + }).anyTimes(); + + EasyMock.replay(delegate); + query.setDelegate(delegate); + SQLContainer container = new SQLContainer(query); + // Ville, Kalle, Pelle, Börje + Assert.assertEquals(4, container.size()); + Assert.assertEquals("Börje", + container.getContainerProperty(container.lastItemId(), "NAME") + .getValue()); + + container.addContainerFilter(new Equal("AGE", 18)); + // Pelle + Assert.assertEquals(1, container.size()); + Assert.assertEquals("Pelle", + container.getContainerProperty(container.firstItemId(), "NAME") + .getValue()); + if (SQLTestsConstants.db == DB.ORACLE) { + Assert.assertEquals(new BigDecimal(18), container + .getContainerProperty(container.firstItemId(), "AGE") + .getValue()); + } else { + Assert.assertEquals(18, container + .getContainerProperty(container.firstItemId(), "AGE") + .getValue()); + } + + EasyMock.verify(delegate); + } + + @Test + public void ticket6136_table_ageIs18() throws SQLException { + TableQuery query = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + SQLContainer container = new SQLContainer(query); + // Ville, Kalle, Pelle, Börje + Assert.assertEquals(4, container.size()); + + container.addContainerFilter(new Equal("AGE", 18)); + + // Pelle + Assert.assertEquals(1, container.size()); + Assert.assertEquals("Pelle", + container.getContainerProperty(container.firstItemId(), "NAME") + .getValue()); + if (SQLTestsConstants.db == DB.ORACLE) { + Assert.assertEquals(new BigDecimal(18), container + .getContainerProperty(container.firstItemId(), "AGE") + .getValue()); + } else { + Assert.assertEquals(18, container + .getContainerProperty(container.firstItemId(), "AGE") + .getValue()); + } + } + + @Test + public void ticket7434_getItem_Modified_Changed_Unchanged() + throws SQLException { + SQLContainer container = new SQLContainer(new TableQuery("people", + connectionPool, SQLTestsConstants.sqlGen)); + + Object id = container.firstItemId(); + Item item = container.getItem(id); + String name = (String) item.getItemProperty("NAME").getValue(); + + // set a different name + item.getItemProperty("NAME").setValue("otherName"); + Assert.assertEquals("otherName", + item.getItemProperty("NAME").getValue()); + + // access the item and reset the name to its old value + Item item2 = container.getItem(id); + item2.getItemProperty("NAME").setValue(name); + Assert.assertEquals(name, item2.getItemProperty("NAME").getValue()); + + Item item3 = container.getItem(id); + String name3 = (String) item3.getItemProperty("NAME").getValue(); + + Assert.assertEquals(name, name3); + } + + @Test + public void ticket10032_empty_set_metadata_correctly_handled() + throws SQLException { + // If problem exists will break when method getPropertyIds() + // is called in constructor SQLContainer(QueryDelegate delegate). + SQLContainer container = new SQLContainer(new FreeformQuery( + "SELECT * FROM people WHERE name='does_not_exist'", + Arrays.asList("ID"), connectionPool)); + Assert.assertTrue("Got items while expected empty set", + container.size() == 0); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/UtilTest.java b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/UtilTest.java new file mode 100644 index 0000000000..a575d649f1 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/UtilTest.java @@ -0,0 +1,50 @@ +package com.vaadin.data.util.sqlcontainer; + +import org.junit.Assert; +import org.junit.Test; + +public class UtilTest { + + @Test + public void escapeSQL_noQuotes_returnsSameString() { + Assert.assertEquals("asdf", SQLUtil.escapeSQL("asdf")); + } + + @Test + public void escapeSQL_singleQuotes_returnsEscapedString() { + Assert.assertEquals("O''Brien", SQLUtil.escapeSQL("O'Brien")); + } + + @Test + public void escapeSQL_severalQuotes_returnsEscapedString() { + Assert.assertEquals("asdf''ghjk''qwerty", + SQLUtil.escapeSQL("asdf'ghjk'qwerty")); + } + + @Test + public void escapeSQL_doubleQuotes_returnsEscapedString() { + Assert.assertEquals("asdf\\\"foo", SQLUtil.escapeSQL("asdf\"foo")); + } + + @Test + public void escapeSQL_multipleDoubleQuotes_returnsEscapedString() { + Assert.assertEquals("asdf\\\"foo\\\"bar", + SQLUtil.escapeSQL("asdf\"foo\"bar")); + } + + @Test + public void escapeSQL_backslashes_returnsEscapedString() { + Assert.assertEquals("foo\\\\nbar\\\\r", + SQLUtil.escapeSQL("foo\\nbar\\r")); + } + + @Test + public void escapeSQL_x00_removesX00() { + Assert.assertEquals("foobar", SQLUtil.escapeSQL("foo\\x00bar")); + } + + @Test + public void escapeSQL_x1a_removesX1a() { + Assert.assertEquals("foobar", SQLUtil.escapeSQL("foo\\x1abar")); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPoolTest.java b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPoolTest.java new file mode 100644 index 0000000000..1463a27217 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPoolTest.java @@ -0,0 +1,107 @@ +package com.vaadin.data.util.sqlcontainer.connection; + +import java.sql.Connection; +import java.sql.SQLException; + +import javax.naming.Context; +import javax.naming.NamingException; +import javax.sql.DataSource; + +import org.easymock.EasyMock; +import org.junit.Assert; +import org.junit.Test; + +public class J2EEConnectionPoolTest { + + @Test + public void reserveConnection_dataSourceSpecified_shouldReturnValidConnection() + throws SQLException { + Connection connection = EasyMock.createMock(Connection.class); + connection.setAutoCommit(false); + EasyMock.expectLastCall(); + DataSource ds = EasyMock.createMock(DataSource.class); + ds.getConnection(); + EasyMock.expectLastCall().andReturn(connection); + EasyMock.replay(connection, ds); + + J2EEConnectionPool pool = new J2EEConnectionPool(ds); + Connection c = pool.reserveConnection(); + Assert.assertEquals(connection, c); + EasyMock.verify(connection, ds); + } + + @Test + public void releaseConnection_shouldCloseConnection() throws SQLException { + Connection connection = EasyMock.createMock(Connection.class); + connection.setAutoCommit(false); + EasyMock.expectLastCall(); + connection.close(); + EasyMock.expectLastCall(); + DataSource ds = EasyMock.createMock(DataSource.class); + ds.getConnection(); + EasyMock.expectLastCall().andReturn(connection); + EasyMock.replay(connection, ds); + + J2EEConnectionPool pool = new J2EEConnectionPool(ds); + Connection c = pool.reserveConnection(); + Assert.assertEquals(connection, c); + pool.releaseConnection(c); + EasyMock.verify(connection, ds); + } + + @Test + public void reserveConnection_dataSourceLookedUp_shouldReturnValidConnection() + throws SQLException, NamingException { + Connection connection = EasyMock.createMock(Connection.class); + connection.setAutoCommit(false); + EasyMock.expectLastCall(); + connection.close(); + EasyMock.expectLastCall(); + + DataSource ds = EasyMock.createMock(DataSource.class); + ds.getConnection(); + EasyMock.expectLastCall().andReturn(connection); + + System.setProperty("java.naming.factory.initial", + "com.vaadin.data.util.sqlcontainer.connection.MockInitialContextFactory"); + Context context = EasyMock.createMock(Context.class); + context.lookup("testDataSource"); + EasyMock.expectLastCall().andReturn(ds); + MockInitialContextFactory.setMockContext(context); + + EasyMock.replay(context, connection, ds); + + J2EEConnectionPool pool = new J2EEConnectionPool("testDataSource"); + Connection c = pool.reserveConnection(); + Assert.assertEquals(connection, c); + pool.releaseConnection(c); + EasyMock.verify(context, connection, ds); + } + + @Test(expected = SQLException.class) + public void reserveConnection_nonExistantDataSourceLookedUp_shouldFail() + throws SQLException, NamingException { + System.setProperty("java.naming.factory.initial", + "com.vaadin.addon.sqlcontainer.connection.MockInitialContextFactory"); + Context context = EasyMock.createMock(Context.class); + context.lookup("foo"); + EasyMock.expectLastCall().andThrow(new NamingException("fail")); + MockInitialContextFactory.setMockContext(context); + + EasyMock.replay(context); + + J2EEConnectionPool pool = new J2EEConnectionPool("foo"); + pool.reserveConnection(); + EasyMock.verify(context); + } + + @Test + public void releaseConnection_null_shouldSucceed() throws SQLException { + DataSource ds = EasyMock.createMock(DataSource.class); + EasyMock.replay(ds); + + J2EEConnectionPool pool = new J2EEConnectionPool(ds); + pool.releaseConnection(null); + EasyMock.verify(ds); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/MockInitialContextFactory.java b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/MockInitialContextFactory.java new file mode 100644 index 0000000000..1c70c8dad7 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/MockInitialContextFactory.java @@ -0,0 +1,27 @@ +package com.vaadin.data.util.sqlcontainer.connection; + +import javax.naming.Context; +import javax.naming.NamingException; +import javax.naming.spi.InitialContextFactory; + +import org.junit.Test; + +/** + * Provides a JNDI initial context factory for the MockContext. + */ +public class MockInitialContextFactory implements InitialContextFactory { + private static Context mockCtx = null; + + public static void setMockContext(Context ctx) { + mockCtx = ctx; + } + + @Override + public Context getInitialContext(java.util.Hashtable<?, ?> environment) + throws NamingException { + if (mockCtx == null) { + throw new IllegalStateException("mock context was not set."); + } + return mockCtx; + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPoolTest.java b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPoolTest.java new file mode 100644 index 0000000000..5a6ae78aeb --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPoolTest.java @@ -0,0 +1,185 @@ +package com.vaadin.data.util.sqlcontainer.connection; + +import java.sql.Connection; +import java.sql.SQLException; + +import org.easymock.EasyMock; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.data.util.sqlcontainer.SQLTestsConstants; +import com.vaadin.data.util.sqlcontainer.query.ValidatingSimpleJDBCConnectionPool; + +public class SimpleJDBCConnectionPoolTest { + private JDBCConnectionPool connectionPool; + + @Before + public void setUp() throws SQLException { + connectionPool = new ValidatingSimpleJDBCConnectionPool( + SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL, + SQLTestsConstants.dbUser, SQLTestsConstants.dbPwd, 2, 2); + } + + @Test + public void reserveConnection_reserveNewConnection_returnsConnection() + throws SQLException { + Connection conn = connectionPool.reserveConnection(); + Assert.assertNotNull(conn); + } + + @Test + public void releaseConnection_releaseUnused_shouldNotThrowException() + throws SQLException { + Connection conn = connectionPool.reserveConnection(); + connectionPool.releaseConnection(conn); + Assert.assertFalse(conn.isClosed()); + } + + @Test(expected = SQLException.class) + public void reserveConnection_noConnectionsLeft_shouldFail() + throws SQLException { + try { + connectionPool.reserveConnection(); + connectionPool.reserveConnection(); + } catch (SQLException e) { + e.printStackTrace(); + Assert.fail( + "Exception before all connections used! " + e.getMessage()); + } + + connectionPool.reserveConnection(); + Assert.fail( + "Reserving connection didn't fail even though no connections are available!"); + } + + @Test + public void reserveConnection_oneConnectionLeft_returnsConnection() + throws SQLException { + try { + connectionPool.reserveConnection(); + } catch (SQLException e) { + e.printStackTrace(); + Assert.fail( + "Exception before all connections used! " + e.getMessage()); + } + + Connection conn = connectionPool.reserveConnection(); + Assert.assertNotNull(conn); + } + + @Test + public void reserveConnection_oneConnectionJustReleased_returnsConnection() + throws SQLException { + Connection conn2 = null; + try { + connectionPool.reserveConnection(); + conn2 = connectionPool.reserveConnection(); + } catch (SQLException e) { + e.printStackTrace(); + Assert.fail( + "Exception before all connections used! " + e.getMessage()); + } + + connectionPool.releaseConnection(conn2); + + connectionPool.reserveConnection(); + } + + @Test(expected = IllegalArgumentException.class) + public void construct_allParametersNull_shouldFail() throws SQLException { + SimpleJDBCConnectionPool cp = new SimpleJDBCConnectionPool(null, null, + null, null); + } + + @Test(expected = IllegalArgumentException.class) + public void construct_onlyDriverNameGiven_shouldFail() throws SQLException { + SimpleJDBCConnectionPool cp = new SimpleJDBCConnectionPool( + SQLTestsConstants.dbDriver, null, null, null); + } + + @Test(expected = IllegalArgumentException.class) + public void construct_onlyDriverNameAndUrlGiven_shouldFail() + throws SQLException { + SimpleJDBCConnectionPool cp = new SimpleJDBCConnectionPool( + SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL, null, + null); + } + + @Test(expected = IllegalArgumentException.class) + public void construct_onlyDriverNameAndUrlAndUserGiven_shouldFail() + throws SQLException { + SimpleJDBCConnectionPool cp = new SimpleJDBCConnectionPool( + SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL, + SQLTestsConstants.dbUser, null); + } + + @Test(expected = RuntimeException.class) + public void construct_nonExistingDriver_shouldFail() throws SQLException { + SimpleJDBCConnectionPool cp = new SimpleJDBCConnectionPool("foo", + SQLTestsConstants.dbURL, SQLTestsConstants.dbUser, + SQLTestsConstants.dbPwd); + } + + @Test + public void reserveConnection_newConnectionOpened_shouldSucceed() + throws SQLException { + connectionPool = new SimpleJDBCConnectionPool( + SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL, + SQLTestsConstants.dbUser, SQLTestsConstants.dbPwd, 0, 2); + Connection c = connectionPool.reserveConnection(); + Assert.assertNotNull(c); + } + + @Test + public void releaseConnection_nullConnection_shouldDoNothing() { + connectionPool.releaseConnection(null); + } + + @Test + public void releaseConnection_failingRollback_shouldCallClose() + throws SQLException { + Connection c = EasyMock.createMock(Connection.class); + c.getAutoCommit(); + EasyMock.expectLastCall().andReturn(false); + c.rollback(); + EasyMock.expectLastCall().andThrow(new SQLException("Rollback failed")); + c.close(); + EasyMock.expectLastCall().atLeastOnce(); + EasyMock.replay(c); + // make sure the connection pool is initialized + // Bypass validation + JDBCConnectionPool realPool = ((ValidatingSimpleJDBCConnectionPool) connectionPool) + .getRealPool(); + realPool.reserveConnection(); + realPool.releaseConnection(c); + EasyMock.verify(c); + } + + @Test + public void destroy_shouldCloseAllConnections() throws SQLException { + Connection c1 = connectionPool.reserveConnection(); + Connection c2 = connectionPool.reserveConnection(); + try { + connectionPool.destroy(); + } catch (RuntimeException e) { + // The test connection pool throws an exception when the pool was + // not empty but only after cleanup of the real pool has been done + } + + Assert.assertTrue(c1.isClosed()); + Assert.assertTrue(c2.isClosed()); + } + + @Test + public void destroy_shouldCloseAllConnections2() throws SQLException { + Connection c1 = connectionPool.reserveConnection(); + Connection c2 = connectionPool.reserveConnection(); + connectionPool.releaseConnection(c1); + connectionPool.releaseConnection(c2); + connectionPool.destroy(); + Assert.assertTrue(c1.isClosed()); + Assert.assertTrue(c2.isClosed()); + } + +} diff --git a/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/BetweenTest.java b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/BetweenTest.java new file mode 100644 index 0000000000..41db88b881 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/BetweenTest.java @@ -0,0 +1,182 @@ +package com.vaadin.data.util.sqlcontainer.filters; + +import org.easymock.EasyMock; +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.data.Item; +import com.vaadin.data.Property; +import com.vaadin.data.util.filter.Between; + +public class BetweenTest { + + private Item itemWithPropertyValue(Object propertyId, Object value) { + Property<?> property = EasyMock.createMock(Property.class); + property.getValue(); + EasyMock.expectLastCall().andReturn(value).anyTimes(); + EasyMock.replay(property); + + Item item = EasyMock.createMock(Item.class); + item.getItemProperty(propertyId); + EasyMock.expectLastCall().andReturn(property).anyTimes(); + EasyMock.replay(item); + return item; + } + + @Test + public void passesFilter_valueIsInRange_shouldBeTrue() { + Item item = itemWithPropertyValue("foo", 15); + Between between = new Between("foo", 1, 30); + Assert.assertTrue(between.passesFilter("foo", item)); + } + + @Test + public void passesFilter_valueIsOutOfRange_shouldBeFalse() { + Item item = itemWithPropertyValue("foo", 15); + Between between = new Between("foo", 0, 2); + Assert.assertFalse(between.passesFilter("foo", item)); + } + + @Test + public void passesFilter_valueNotComparable_shouldBeFalse() { + Item item = itemWithPropertyValue("foo", new Object()); + Between between = new Between("foo", 0, 2); + Assert.assertFalse(between.passesFilter("foo", item)); + } + + @Test + public void appliesToProperty_differentProperties_shoudlBeFalse() { + Between between = new Between("foo", 0, 2); + Assert.assertFalse(between.appliesToProperty("bar")); + } + + @Test + public void appliesToProperty_sameProperties_shouldBeTrue() { + Between between = new Between("foo", 0, 2); + Assert.assertTrue(between.appliesToProperty("foo")); + } + + @Test + public void hashCode_equalInstances_shouldBeEqual() { + Between b1 = new Between("foo", 0, 2); + Between b2 = new Between("foo", 0, 2); + Assert.assertEquals(b1.hashCode(), b2.hashCode()); + } + + @Test + public void equals_differentObjects_shouldBeFalse() { + Between b1 = new Between("foo", 0, 2); + Object obj = new Object(); + Assert.assertFalse(b1.equals(obj)); + } + + @Test + public void equals_sameInstance_shouldBeTrue() { + Between b1 = new Between("foo", 0, 2); + Between b2 = b1; + Assert.assertTrue(b1.equals(b2)); + } + + @Test + public void equals_equalInstances_shouldBeTrue() { + Between b1 = new Between("foo", 0, 2); + Between b2 = new Between("foo", 0, 2); + Assert.assertTrue(b1.equals(b2)); + } + + @Test + public void equals_equalInstances2_shouldBeTrue() { + Between b1 = new Between(null, null, null); + Between b2 = new Between(null, null, null); + Assert.assertTrue(b1.equals(b2)); + } + + @Test + public void equals_secondValueDiffers_shouldBeFalse() { + Between b1 = new Between("foo", 0, 1); + Between b2 = new Between("foo", 0, 2); + Assert.assertFalse(b1.equals(b2)); + } + + @Test + public void equals_firstAndSecondValueDiffers_shouldBeFalse() { + Between b1 = new Between("foo", 0, null); + Between b2 = new Between("foo", 1, 2); + Assert.assertFalse(b1.equals(b2)); + } + + @Test + public void equals_propertyAndFirstAndSecondValueDiffers_shouldBeFalse() { + Between b1 = new Between("foo", null, 1); + Between b2 = new Between("bar", 1, 2); + Assert.assertFalse(b1.equals(b2)); + } + + @Test + public void equals_propertiesDiffer_shouldBeFalse() { + Between b1 = new Between(null, 0, 1); + Between b2 = new Between("bar", 0, 1); + Assert.assertFalse(b1.equals(b2)); + } + + @Test + public void hashCode_nullStartValue_shouldBeEqual() { + Between b1 = new Between("foo", null, 2); + Between b2 = new Between("foo", null, 2); + Assert.assertEquals(b1.hashCode(), b2.hashCode()); + } + + @Test + public void hashCode_nullEndValue_shouldBeEqual() { + Between b1 = new Between("foo", 0, null); + Between b2 = new Between("foo", 0, null); + Assert.assertEquals(b1.hashCode(), b2.hashCode()); + } + + @Test + public void hashCode_nullPropertyId_shouldBeEqual() { + Between b1 = new Between(null, 0, 2); + Between b2 = new Between(null, 0, 2); + Assert.assertEquals(b1.hashCode(), b2.hashCode()); + } + + @Test + public void passesFilter_nullValue_filterIsPassed() { + String id = "id"; + Between between = new Between(id, null, null); + Assert.assertTrue( + between.passesFilter(id, itemWithPropertyValue(id, null))); + } + + @Test + public void passesFilter_nullStartValue_filterIsPassed() { + String id = "id"; + Between between = new Between(id, null, 2); + Assert.assertTrue( + between.passesFilter(id, itemWithPropertyValue(id, 1))); + } + + @Test + public void passesFilter_nullEndValue_filterIsPassed() { + String id = "id"; + Between between = new Between(id, 0, null); + Assert.assertTrue( + between.passesFilter(id, itemWithPropertyValue(id, 1))); + } + + @Test + public void passesFilter_nullStartValueAndEndValue_filterIsPassed() { + String id = "id"; + Between between = new Between(id, null, null); + Assert.assertTrue( + between.passesFilter(id, itemWithPropertyValue(id, 1))); + } + + @Test + public void passesFilter_nullStartValueAndEndValueAndValueIsNotComparable_filterIsNotPassed() { + String id = "id"; + Between between = new Between(id, null, null); + Assert.assertFalse(between.passesFilter(id, + itemWithPropertyValue(id, new Object()))); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/CompareTest.java b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/CompareTest.java new file mode 100644 index 0000000000..a6b6f4b55c --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/CompareTest.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.data.util.sqlcontainer.filters; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.data.util.filter.Compare; + +public class CompareTest { + + @Test + public void testEquals() { + Compare c1 = new Compare.Equal("prop1", "val1"); + Compare c2 = new Compare.Equal("prop1", "val1"); + Assert.assertTrue(c1.equals(c2)); + } + + @Test + public void testDifferentTypeEquals() { + Compare c1 = new Compare.Equal("prop1", "val1"); + Compare c2 = new Compare.Greater("prop1", "val1"); + Assert.assertFalse(c1.equals(c2)); + } + + @Test + public void testEqualsNull() { + Compare c1 = new Compare.Equal("prop1", "val1"); + Assert.assertFalse(c1.equals(null)); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/LikeTest.java b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/LikeTest.java new file mode 100644 index 0000000000..f1130aad80 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/LikeTest.java @@ -0,0 +1,229 @@ +package com.vaadin.data.util.sqlcontainer.filters; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.data.Item; +import com.vaadin.data.util.ObjectProperty; +import com.vaadin.data.util.PropertysetItem; +import com.vaadin.data.util.filter.Like; + +public class LikeTest { + + @Test + public void passesFilter_valueIsNotStringType_shouldFail() { + Like like = new Like("test", "%foo%"); + + Item item = new PropertysetItem(); + item.addItemProperty("test", new ObjectProperty<Integer>(5)); + + Assert.assertFalse(like.passesFilter("id", item)); + } + + @Test + public void passesFilter_containsLikeQueryOnStringContainingValue_shouldSucceed() { + Like like = new Like("test", "%foo%"); + + Item item = new PropertysetItem(); + item.addItemProperty("test", new ObjectProperty<String>("asdfooghij")); + + Assert.assertTrue(like.passesFilter("id", item)); + } + + @Test + public void passesFilter_containsLikeQueryOnStringContainingValueCaseInsensitive_shouldSucceed() { + Like like = new Like("test", "%foo%"); + like.setCaseSensitive(false); + + Item item = new PropertysetItem(); + item.addItemProperty("test", new ObjectProperty<String>("asdfOOghij")); + + Assert.assertTrue(like.passesFilter("id", item)); + } + + @Test + public void passesFilter_containsLikeQueryOnStringContainingValueConstructedCaseInsensitive_shouldSucceed() { + Like like = new Like("test", "%foo%", false); + + Item item = new PropertysetItem(); + item.addItemProperty("test", new ObjectProperty<String>("asdfOOghij")); + + Assert.assertTrue(like.passesFilter("id", item)); + } + + @Test + public void passesFilter_containsLikeQueryOnStringNotContainingValue_shouldFail() { + Like like = new Like("test", "%foo%"); + + Item item = new PropertysetItem(); + item.addItemProperty("test", new ObjectProperty<String>("asdbarghij")); + + Assert.assertFalse(like.passesFilter("id", item)); + } + + @Test + public void passesFilter_containsLikeQueryOnStringExactlyEqualToValue_shouldSucceed() { + Like like = new Like("test", "%foo%"); + + Item item = new PropertysetItem(); + item.addItemProperty("test", new ObjectProperty<String>("foo")); + + Assert.assertTrue(like.passesFilter("id", item)); + } + + @Test + public void passesFilter_containsLikeQueryOnStringEqualToValueMinusOneCharAtTheEnd_shouldFail() { + Like like = new Like("test", "%foo%"); + + Item item = new PropertysetItem(); + item.addItemProperty("test", new ObjectProperty<String>("fo")); + + Assert.assertFalse(like.passesFilter("id", item)); + } + + @Test + public void passesFilter_beginsWithLikeQueryOnStringBeginningWithValue_shouldSucceed() { + Like like = new Like("test", "foo%"); + + Item item = new PropertysetItem(); + item.addItemProperty("test", new ObjectProperty<String>("foobar")); + + Assert.assertTrue(like.passesFilter("id", item)); + } + + @Test + public void passesFilter_beginsWithLikeQueryOnStringNotBeginningWithValue_shouldFail() { + Like like = new Like("test", "foo%"); + + Item item = new PropertysetItem(); + item.addItemProperty("test", new ObjectProperty<String>("barfoo")); + + Assert.assertFalse(like.passesFilter("id", item)); + } + + @Test + public void passesFilter_endsWithLikeQueryOnStringEndingWithValue_shouldSucceed() { + Like like = new Like("test", "%foo"); + + Item item = new PropertysetItem(); + item.addItemProperty("test", new ObjectProperty<String>("barfoo")); + + Assert.assertTrue(like.passesFilter("id", item)); + } + + @Test + public void passesFilter_endsWithLikeQueryOnStringNotEndingWithValue_shouldFail() { + Like like = new Like("test", "%foo"); + + Item item = new PropertysetItem(); + item.addItemProperty("test", new ObjectProperty<String>("foobar")); + + Assert.assertFalse(like.passesFilter("id", item)); + } + + @Test + public void passesFilter_startsWithAndEndsWithOnMatchingValue_shouldSucceed() { + Like like = new Like("test", "foo%bar"); + + Item item = new PropertysetItem(); + item.addItemProperty("test", new ObjectProperty<String>("fooASDFbar")); + + Assert.assertTrue(like.passesFilter("id", item)); + } + + @Test + public void appliesToProperty_valueIsProperty_shouldBeTrue() { + Like like = new Like("test", "%foo"); + Assert.assertTrue(like.appliesToProperty("test")); + } + + @Test + public void appliesToProperty_valueIsNotProperty_shouldBeFalse() { + Like like = new Like("test", "%foo"); + Assert.assertFalse(like.appliesToProperty("bar")); + } + + @Test + public void equals_sameInstances_shouldBeTrue() { + Like like1 = new Like("test", "%foo"); + Like like2 = like1; + Assert.assertTrue(like1.equals(like2)); + } + + @Test + public void equals_twoEqualInstances_shouldBeTrue() { + Like like1 = new Like("test", "foo"); + Like like2 = new Like("test", "foo"); + Assert.assertTrue(like1.equals(like2)); + } + + @Test + public void equals_differentValues_shouldBeFalse() { + Like like1 = new Like("test", "foo"); + Like like2 = new Like("test", "bar"); + Assert.assertFalse(like1.equals(like2)); + } + + @Test + public void equals_differentProperties_shouldBeFalse() { + Like like1 = new Like("foo", "test"); + Like like2 = new Like("bar", "test"); + Assert.assertFalse(like1.equals(like2)); + } + + @Test + public void equals_differentPropertiesAndValues_shouldBeFalse() { + Like like1 = new Like("foo", "bar"); + Like like2 = new Like("baz", "zomg"); + Assert.assertFalse(like1.equals(like2)); + } + + @Test + public void equals_differentClasses_shouldBeFalse() { + Like like1 = new Like("foo", "bar"); + Object obj = new Object(); + Assert.assertFalse(like1.equals(obj)); + } + + @Test + public void equals_bothHaveNullProperties_shouldBeTrue() { + Like like1 = new Like(null, "foo"); + Like like2 = new Like(null, "foo"); + Assert.assertTrue(like1.equals(like2)); + } + + @Test + public void equals_bothHaveNullValues_shouldBeTrue() { + Like like1 = new Like("foo", null); + Like like2 = new Like("foo", null); + Assert.assertTrue(like1.equals(like2)); + } + + @Test + public void equals_onePropertyIsNull_shouldBeFalse() { + Like like1 = new Like(null, "bar"); + Like like2 = new Like("foo", "baz"); + Assert.assertFalse(like1.equals(like2)); + } + + @Test + public void equals_oneValueIsNull_shouldBeFalse() { + Like like1 = new Like("foo", null); + Like like2 = new Like("baz", "bar"); + Assert.assertFalse(like1.equals(like2)); + } + + @Test + public void hashCode_equalInstances_shouldBeEqual() { + Like like1 = new Like("test", "foo"); + Like like2 = new Like("test", "foo"); + Assert.assertEquals(like1.hashCode(), like2.hashCode()); + } + + @Test + public void hashCode_differentPropertiesAndValues_shouldNotEqual() { + Like like1 = new Like("foo", "bar"); + Like like2 = new Like("baz", "zomg"); + Assert.assertTrue(like1.hashCode() != like2.hashCode()); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/generator/SQLGeneratorsTest.java b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/generator/SQLGeneratorsTest.java new file mode 100644 index 0000000000..dd1db30b72 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/generator/SQLGeneratorsTest.java @@ -0,0 +1,239 @@ +package com.vaadin.data.util.sqlcontainer.generator; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.data.Container.Filter; +import com.vaadin.data.util.filter.Like; +import com.vaadin.data.util.filter.Or; +import com.vaadin.data.util.sqlcontainer.DataGenerator; +import com.vaadin.data.util.sqlcontainer.RowItem; +import com.vaadin.data.util.sqlcontainer.SQLContainer; +import com.vaadin.data.util.sqlcontainer.SQLTestsConstants; +import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool; +import com.vaadin.data.util.sqlcontainer.query.OrderBy; +import com.vaadin.data.util.sqlcontainer.query.TableQuery; +import com.vaadin.data.util.sqlcontainer.query.ValidatingSimpleJDBCConnectionPool; +import com.vaadin.data.util.sqlcontainer.query.generator.DefaultSQLGenerator; +import com.vaadin.data.util.sqlcontainer.query.generator.MSSQLGenerator; +import com.vaadin.data.util.sqlcontainer.query.generator.OracleGenerator; +import com.vaadin.data.util.sqlcontainer.query.generator.SQLGenerator; +import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; + +public class SQLGeneratorsTest { + private JDBCConnectionPool connectionPool; + + @Before + public void setUp() throws SQLException { + + try { + connectionPool = new ValidatingSimpleJDBCConnectionPool( + SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL, + SQLTestsConstants.dbUser, SQLTestsConstants.dbPwd, 2, 2); + } catch (SQLException e) { + e.printStackTrace(); + Assert.fail(e.getMessage()); + } + + DataGenerator.addPeopleToDatabase(connectionPool); + } + + @After + public void tearDown() { + if (connectionPool != null) { + connectionPool.destroy(); + } + } + + @Test + public void generateSelectQuery_basicQuery_shouldSucceed() { + SQLGenerator sg = new DefaultSQLGenerator(); + StatementHelper sh = sg.generateSelectQuery("TABLE", null, null, 0, 0, + null); + Assert.assertEquals(sh.getQueryString(), "SELECT * FROM TABLE"); + } + + @Test + public void generateSelectQuery_pagingAndColumnsSet_shouldSucceed() { + SQLGenerator sg = new DefaultSQLGenerator(); + StatementHelper sh = sg.generateSelectQuery("TABLE", null, null, 4, 8, + "COL1, COL2, COL3"); + Assert.assertEquals(sh.getQueryString(), + "SELECT COL1, COL2, COL3 FROM TABLE LIMIT 8 OFFSET 4"); + } + + /** + * Note: Only tests one kind of filter and ordering. + */ + @Test + public void generateSelectQuery_filtersAndOrderingSet_shouldSucceed() { + SQLGenerator sg = new DefaultSQLGenerator(); + List<com.vaadin.data.Container.Filter> f = new ArrayList<Filter>(); + f.add(new Like("name", "%lle")); + List<OrderBy> ob = Arrays.asList(new OrderBy("name", true)); + StatementHelper sh = sg.generateSelectQuery("TABLE", f, ob, 0, 0, null); + Assert.assertEquals(sh.getQueryString(), + "SELECT * FROM TABLE WHERE \"name\" LIKE ? ORDER BY \"name\" ASC"); + } + + @Test + public void generateSelectQuery_filtersAndOrderingSet_exclusiveFilteringMode_shouldSucceed() { + SQLGenerator sg = new DefaultSQLGenerator(); + List<Filter> f = new ArrayList<Filter>(); + f.add(new Or(new Like("name", "%lle"), new Like("name", "vi%"))); + List<OrderBy> ob = Arrays.asList(new OrderBy("name", true)); + StatementHelper sh = sg.generateSelectQuery("TABLE", f, ob, 0, 0, null); + // TODO + Assert.assertEquals(sh.getQueryString(), + "SELECT * FROM TABLE WHERE (\"name\" LIKE ? " + + "OR \"name\" LIKE ?) ORDER BY \"name\" ASC"); + } + + @Test + public void generateDeleteQuery_basicQuery_shouldSucceed() + throws SQLException { + /* + * No need to run this for Oracle/MSSQL generators since the + * DefaultSQLGenerator method would be called anyway. + */ + if (SQLTestsConstants.sqlGen instanceof MSSQLGenerator + || SQLTestsConstants.sqlGen instanceof OracleGenerator) { + return; + } + SQLGenerator sg = SQLTestsConstants.sqlGen; + TableQuery query = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + SQLContainer container = new SQLContainer(query); + + StatementHelper sh = sg.generateDeleteQuery("people", + query.getPrimaryKeyColumns(), null, (RowItem) container + .getItem(container.getItemIds().iterator().next())); + Assert.assertEquals("DELETE FROM people WHERE \"ID\" = ?", + sh.getQueryString()); + } + + @Test + public void generateUpdateQuery_basicQuery_shouldSucceed() + throws SQLException { + /* + * No need to run this for Oracle/MSSQL generators since the + * DefaultSQLGenerator method would be called anyway. + */ + if (SQLTestsConstants.sqlGen instanceof MSSQLGenerator + || SQLTestsConstants.sqlGen instanceof OracleGenerator) { + return; + } + SQLGenerator sg = new DefaultSQLGenerator(); + TableQuery query = new TableQuery("people", connectionPool); + SQLContainer container = new SQLContainer(query); + + RowItem ri = (RowItem) container + .getItem(container.getItemIds().iterator().next()); + ri.getItemProperty("NAME").setValue("Viljami"); + + StatementHelper sh = sg.generateUpdateQuery("people", ri); + Assert.assertTrue( + "UPDATE people SET \"NAME\" = ?, \"AGE\" = ? WHERE \"ID\" = ?" + .equals(sh.getQueryString()) + || "UPDATE people SET \"AGE\" = ?, \"NAME\" = ? WHERE \"ID\" = ?" + .equals(sh.getQueryString())); + } + + @Test + public void generateInsertQuery_basicQuery_shouldSucceed() + throws SQLException { + /* + * No need to run this for Oracle/MSSQL generators since the + * DefaultSQLGenerator method would be called anyway. + */ + if (SQLTestsConstants.sqlGen instanceof MSSQLGenerator + || SQLTestsConstants.sqlGen instanceof OracleGenerator) { + return; + } + SQLGenerator sg = new DefaultSQLGenerator(); + TableQuery query = new TableQuery("people", connectionPool); + SQLContainer container = new SQLContainer(query); + + RowItem ri = (RowItem) container.getItem(container.addItem()); + ri.getItemProperty("NAME").setValue("Viljami"); + + StatementHelper sh = sg.generateInsertQuery("people", ri); + + Assert.assertTrue("INSERT INTO people (\"NAME\", \"AGE\") VALUES (?, ?)" + .equals(sh.getQueryString()) + || "INSERT INTO people (\"AGE\", \"NAME\") VALUES (?, ?)" + .equals(sh.getQueryString())); + } + + @Test + public void generateComplexSelectQuery_forOracle_shouldSucceed() + throws SQLException { + SQLGenerator sg = new OracleGenerator(); + List<Filter> f = new ArrayList<Filter>(); + f.add(new Like("name", "%lle")); + List<OrderBy> ob = Arrays.asList(new OrderBy("name", true)); + StatementHelper sh = sg.generateSelectQuery("TABLE", f, ob, 4, 8, + "NAME, ID"); + Assert.assertEquals( + "SELECT * FROM (SELECT x.*, ROWNUM AS \"rownum\" FROM" + + " (SELECT NAME, ID FROM TABLE WHERE \"name\" LIKE ?" + + " ORDER BY \"name\" ASC) x) WHERE \"rownum\" BETWEEN 5 AND 12", + sh.getQueryString()); + } + + @Test + public void generateComplexSelectQuery_forMSSQL_shouldSucceed() + throws SQLException { + SQLGenerator sg = new MSSQLGenerator(); + List<Filter> f = new ArrayList<Filter>(); + f.add(new Like("name", "%lle")); + List<OrderBy> ob = Arrays.asList(new OrderBy("name", true)); + StatementHelper sh = sg.generateSelectQuery("TABLE", f, ob, 4, 8, + "NAME, ID"); + Assert.assertEquals(sh.getQueryString(), + "SELECT * FROM (SELECT row_number() OVER " + + "( ORDER BY \"name\" ASC) AS rownum, NAME, ID " + + "FROM TABLE WHERE \"name\" LIKE ?) " + + "AS a WHERE a.rownum BETWEEN 5 AND 12"); + } + + @Test + public void generateComplexSelectQuery_forOracle_exclusiveFilteringMode_shouldSucceed() + throws SQLException { + SQLGenerator sg = new OracleGenerator(); + List<Filter> f = new ArrayList<Filter>(); + f.add(new Or(new Like("name", "%lle"), new Like("name", "vi%"))); + List<OrderBy> ob = Arrays.asList(new OrderBy("name", true)); + StatementHelper sh = sg.generateSelectQuery("TABLE", f, ob, 4, 8, + "NAME, ID"); + Assert.assertEquals(sh.getQueryString(), + "SELECT * FROM (SELECT x.*, ROWNUM AS \"rownum\" FROM" + + " (SELECT NAME, ID FROM TABLE WHERE (\"name\" LIKE ?" + + " OR \"name\" LIKE ?) " + + "ORDER BY \"name\" ASC) x) WHERE \"rownum\" BETWEEN 5 AND 12"); + } + + @Test + public void generateComplexSelectQuery_forMSSQL_exclusiveFilteringMode_shouldSucceed() + throws SQLException { + SQLGenerator sg = new MSSQLGenerator(); + List<Filter> f = new ArrayList<Filter>(); + f.add(new Or(new Like("name", "%lle"), new Like("name", "vi%"))); + List<OrderBy> ob = Arrays.asList(new OrderBy("name", true)); + StatementHelper sh = sg.generateSelectQuery("TABLE", f, ob, 4, 8, + "NAME, ID"); + Assert.assertEquals(sh.getQueryString(), + "SELECT * FROM (SELECT row_number() OVER " + + "( ORDER BY \"name\" ASC) AS rownum, NAME, ID " + + "FROM TABLE WHERE (\"name\" LIKE ? " + + "OR \"name\" LIKE ?)) " + + "AS a WHERE a.rownum BETWEEN 5 AND 12"); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/generator/StatementHelperTest.java b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/generator/StatementHelperTest.java new file mode 100644 index 0000000000..7201ec7ad8 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/generator/StatementHelperTest.java @@ -0,0 +1,64 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.data.util.sqlcontainer.generator; + +import java.sql.PreparedStatement; +import java.sql.SQLException; + +import org.easymock.EasyMock; +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; + +/** + * + * @author Vaadin Ltd + */ +public class StatementHelperTest { + + @Test + public void testSetValueNullParameter() throws SQLException { + StatementHelper helper = new StatementHelper(); + helper.addParameterValue(null, StatementHelper.class); + PreparedStatement statement = EasyMock + .createMock(PreparedStatement.class); + // should throw SQLException, not NPE + try { + helper.setParameterValuesToStatement(statement); + Assert.fail("Expected SQLExecption for unsupported type"); + } catch (SQLException e) { + // Exception should contain info about which parameter and the type + // which was unsupported + Assert.assertTrue(e.getMessage().contains("parameter 0")); + Assert.assertTrue( + e.getMessage().contains(StatementHelper.class.getName())); + } + } + + @Test + public void testSetByteArrayValue() throws SQLException { + StatementHelper helper = new StatementHelper(); + helper.addParameterValue(null, byte[].class); + PreparedStatement statement = EasyMock + .createMock(PreparedStatement.class); + // should not throw SQLException + helper.setParameterValuesToStatement(statement); + + EasyMock.replay(statement); + statement.setBytes(1, null); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/query/FreeformQueryTest.java b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/query/FreeformQueryTest.java new file mode 100644 index 0000000000..1b9e14b0d8 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/query/FreeformQueryTest.java @@ -0,0 +1,1005 @@ +package com.vaadin.data.util.sqlcontainer.query; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.easymock.EasyMock; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.data.Container.Filter; +import com.vaadin.data.util.filter.Like; +import com.vaadin.data.util.sqlcontainer.DataGenerator; +import com.vaadin.data.util.sqlcontainer.RowId; +import com.vaadin.data.util.sqlcontainer.RowItem; +import com.vaadin.data.util.sqlcontainer.SQLContainer; +import com.vaadin.data.util.sqlcontainer.SQLTestsConstants; +import com.vaadin.data.util.sqlcontainer.SQLTestsConstants.DB; +import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool; +import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; + +public class FreeformQueryTest { + + private static final int offset = SQLTestsConstants.offset; + private JDBCConnectionPool connectionPool; + + @Before + public void setUp() throws SQLException { + + try { + connectionPool = new ValidatingSimpleJDBCConnectionPool( + SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL, + SQLTestsConstants.dbUser, SQLTestsConstants.dbPwd, 2, 2); + } catch (SQLException e) { + e.printStackTrace(); + Assert.fail(e.getMessage()); + } + + DataGenerator.addPeopleToDatabase(connectionPool); + } + + @After + public void tearDown() { + if (connectionPool != null) { + connectionPool.destroy(); + } + } + + @Test + public void construction_legalParameters_shouldSucceed() { + FreeformQuery ffQuery = new FreeformQuery("SELECT * FROM foo", + Arrays.asList("ID"), connectionPool); + Assert.assertArrayEquals(new Object[] { "ID" }, + ffQuery.getPrimaryKeyColumns().toArray()); + + Assert.assertEquals("SELECT * FROM foo", ffQuery.getQueryString()); + } + + @Test(expected = IllegalArgumentException.class) + public void construction_emptyQueryString_shouldFail() { + new FreeformQuery("", Arrays.asList("ID"), connectionPool); + } + + @Test + public void construction_nullPrimaryKeys_shouldSucceed() { + new FreeformQuery("SELECT * FROM foo", null, connectionPool); + } + + @Test + public void construction_nullPrimaryKeys2_shouldSucceed() { + new FreeformQuery("SELECT * FROM foo", connectionPool); + } + + @Test + public void construction_emptyPrimaryKeys_shouldSucceed() { + new FreeformQuery("SELECT * FROM foo", connectionPool); + } + + @Test(expected = IllegalArgumentException.class) + public void construction_emptyStringsInPrimaryKeys_shouldFail() { + new FreeformQuery("SELECT * FROM foo", Arrays.asList(""), + connectionPool); + } + + @Test(expected = IllegalArgumentException.class) + public void construction_nullConnectionPool_shouldFail() { + new FreeformQuery("SELECT * FROM foo", Arrays.asList("ID"), null); + } + + @Test + public void getCount_simpleQuery_returnsFour() throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + Assert.assertEquals(4, query.getCount()); + } + + @Test(expected = SQLException.class) + public void getCount_illegalQuery_shouldThrowSQLException() + throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM asdf", + Arrays.asList("ID"), connectionPool); + query.getResults(0, 50); + } + + @Test + public void getCount_simpleQueryTwoMorePeopleAdded_returnsSix() + throws SQLException { + // Add some people + Connection conn = connectionPool.reserveConnection(); + Statement statement = conn.createStatement(); + if (SQLTestsConstants.db == DB.MSSQL) { + statement.executeUpdate("insert into people values('Bengt', 30)"); + statement.executeUpdate("insert into people values('Ingvar', 50)"); + } else { + statement.executeUpdate( + "insert into people values(default, 'Bengt', 30)"); + statement.executeUpdate( + "insert into people values(default, 'Ingvar', 50)"); + } + statement.close(); + conn.commit(); + connectionPool.releaseConnection(conn); + + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + + Assert.assertEquals(6, query.getCount()); + } + + @Test + public void getCount_moreComplexQuery_returnsThree() throws SQLException { + FreeformQuery query = new FreeformQuery( + "SELECT * FROM people WHERE \"NAME\" LIKE '%lle'", + connectionPool, new String[] { "ID" }); + Assert.assertEquals(3, query.getCount()); + } + + @Test + public void getCount_normalState_releasesConnection() throws SQLException { + FreeformQuery query = new FreeformQuery( + "SELECT * FROM people WHERE \"NAME\" LIKE '%lle'", + connectionPool, "ID"); + query.getCount(); + query.getCount(); + Connection c = connectionPool.reserveConnection(); + Assert.assertNotNull(c); + // Cleanup to make test connection pool happy + connectionPool.releaseConnection(c); + } + + @Test + public void getCount_delegateRegistered_shouldUseDelegate() + throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + EasyMock.expect(delegate.getCountQuery()).andReturn( + "SELECT COUNT(*) FROM people WHERE \"NAME\" LIKE '%lle'"); + EasyMock.replay(delegate); + query.setDelegate(delegate); + Assert.assertEquals(3, query.getCount()); + EasyMock.verify(delegate); + } + + @Test + public void getCount_delegateRegisteredZeroRows_returnsZero() + throws SQLException { + DataGenerator.createGarbage(connectionPool); + FreeformQuery query = new FreeformQuery("SELECT * FROM GARBAGE", + Arrays.asList("ID"), connectionPool); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + EasyMock.expect(delegate.getCountQuery()) + .andReturn("SELECT COUNT(*) FROM GARBAGE"); + EasyMock.replay(delegate); + query.setDelegate(delegate); + Assert.assertEquals(0, query.getCount()); + EasyMock.verify(delegate); + } + + @Test + public void getResults_simpleQuery_returnsFourRecords() + throws SQLException { + FreeformQuery query = new FreeformQuery( + "SELECT \"ID\",\"NAME\" FROM people", Arrays.asList("ID"), + connectionPool); + query.beginTransaction(); + ResultSet rs = query.getResults(0, 0); + + Assert.assertTrue(rs.next()); + Assert.assertEquals(0 + offset, rs.getInt(1)); + Assert.assertEquals("Ville", rs.getString(2)); + + Assert.assertTrue(rs.next()); + Assert.assertEquals(1 + offset, rs.getInt(1)); + Assert.assertEquals("Kalle", rs.getString(2)); + + Assert.assertTrue(rs.next()); + Assert.assertEquals(2 + offset, rs.getInt(1)); + Assert.assertEquals("Pelle", rs.getString(2)); + + Assert.assertTrue(rs.next()); + Assert.assertEquals(3 + offset, rs.getInt(1)); + Assert.assertEquals("Börje", rs.getString(2)); + + Assert.assertFalse(rs.next()); + query.commit(); + } + + @Test + public void getResults_moreComplexQuery_returnsThreeRecords() + throws SQLException { + FreeformQuery query = new FreeformQuery( + "SELECT * FROM people WHERE \"NAME\" LIKE '%lle'", + Arrays.asList("ID"), connectionPool); + query.beginTransaction(); + ResultSet rs = query.getResults(0, 0); + + Assert.assertTrue(rs.next()); + Assert.assertEquals(0 + offset, rs.getInt(1)); + Assert.assertEquals("Ville", rs.getString(2)); + + Assert.assertTrue(rs.next()); + Assert.assertEquals(1 + offset, rs.getInt(1)); + Assert.assertEquals("Kalle", rs.getString(2)); + + Assert.assertTrue(rs.next()); + Assert.assertEquals(2 + offset, rs.getInt(1)); + Assert.assertEquals("Pelle", rs.getString(2)); + + Assert.assertFalse(rs.next()); + query.commit(); + } + + @Test + public void getResults_noDelegate5000Rows_returns5000rows() + throws SQLException { + DataGenerator.addFiveThousandPeople(connectionPool); + + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + query.beginTransaction(); + ResultSet rs = query.getResults(0, 0); + for (int i = 0; i < 5000; i++) { + Assert.assertTrue(rs.next()); + } + Assert.assertFalse(rs.next()); + query.commit(); + } + + @Test(expected = UnsupportedOperationException.class) + public void setFilters_noDelegate_shouldFail() { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + ArrayList<Filter> filters = new ArrayList<Filter>(); + filters.add(new Like("name", "%lle")); + query.setFilters(filters); + } + + @Test(expected = UnsupportedOperationException.class) + public void setOrderBy_noDelegate_shouldFail() { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + query.setOrderBy(Arrays.asList(new OrderBy("name", true))); + } + + @Test(expected = IllegalStateException.class) + public void storeRow_noDelegateNoTransactionActive_shouldFail() + throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + query.storeRow(new RowItem(new SQLContainer(query), + new RowId(new Object[] { 1 }), null)); + } + + @Test + public void storeRow_noDelegate_shouldFail() throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + SQLContainer container = EasyMock.createNiceMock(SQLContainer.class); + EasyMock.replay(container); + query.beginTransaction(); + try { + query.storeRow(new RowItem(container, new RowId(new Object[] { 1 }), + null)); + Assert.fail("storeRow should fail when there is no delegate"); + } catch (UnsupportedOperationException e) { + // Cleanup to make test connection pool happy + query.rollback(); + } + } + + @Test + public void removeRow_noDelegate_shouldFail() throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + SQLContainer container = EasyMock.createNiceMock(SQLContainer.class); + EasyMock.replay(container); + query.beginTransaction(); + try { + query.removeRow(new RowItem(container, + new RowId(new Object[] { 1 }), null)); + Assert.fail("removeRow should fail when there is no delgate"); + } catch (UnsupportedOperationException e) { + // Cleanup to make test connection pool happy + query.rollback(); + } + } + + @Test + public void commit_readOnly_shouldSucceed() throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + query.beginTransaction(); + query.commit(); + } + + @Test + public void rollback_readOnly_shouldSucceed() throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + query.beginTransaction(); + query.rollback(); + } + + @Test(expected = SQLException.class) + public void commit_noActiveTransaction_shouldFail() throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + query.commit(); + } + + @Test(expected = SQLException.class) + public void rollback_noActiveTransaction_shouldFail() throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + query.rollback(); + } + + @Test + public void containsRowWithKeys_simpleQueryWithExistingKeys_returnsTrue() + throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + Assert.assertTrue(query.containsRowWithKey(1)); + } + + @Test + public void containsRowWithKeys_simpleQueryWithNonexistingKeys_returnsTrue() + throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + Assert.assertFalse(query.containsRowWithKey(1337)); + } + + // (expected = SQLException.class) + @Test + public void containsRowWithKeys_simpleQueryWithInvalidKeys_shouldFail() + throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + Assert.assertFalse(query.containsRowWithKey(38796)); + } + + @Test + public void containsRowWithKeys_queryContainingWhereClauseAndExistingKeys_returnsTrue() + throws SQLException { + FreeformQuery query = new FreeformQuery( + "SELECT * FROM people WHERE \"NAME\" LIKE '%lle'", + Arrays.asList("ID"), connectionPool); + Assert.assertTrue(query.containsRowWithKey(1)); + } + + @Test + public void containsRowWithKeys_queryContainingLowercaseWhereClauseAndExistingKeys_returnsTrue() + throws SQLException { + FreeformQuery query = new FreeformQuery( + "select * from people where \"NAME\" like '%lle'", + Arrays.asList("ID"), connectionPool); + Assert.assertTrue(query.containsRowWithKey(1)); + } + + @Test + public void containsRowWithKeys_nullKeys_shouldFailAndReleaseConnections() + throws SQLException { + FreeformQuery query = new FreeformQuery( + "select * from people where \"NAME\" like '%lle'", + Arrays.asList("ID"), connectionPool); + try { + query.containsRowWithKey(new Object[] { null }); + } catch (SQLException e) { + // We should now be able to reserve two connections + connectionPool.reserveConnection(); + connectionPool.reserveConnection(); + } + } + + /* + * -------- Tests with a delegate --------- + */ + + @Test + public void setDelegate_noExistingDelegate_shouldRegisterNewDelegate() { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + query.setDelegate(delegate); + Assert.assertEquals(delegate, query.getDelegate()); + } + + @Test + public void getResults_hasDelegate_shouldCallDelegate() + throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + if (SQLTestsConstants.db == DB.MSSQL) { + EasyMock.expect(delegate.getQueryString(0, 2)) + .andReturn("SELECT * FROM (SELECT row_number()" + + "OVER (ORDER BY id ASC) AS rownum, * FROM people)" + + " AS a WHERE a.rownum BETWEEN 0 AND 2"); + } else if (SQLTestsConstants.db == DB.ORACLE) { + EasyMock.expect(delegate.getQueryString(0, 2)) + .andReturn("SELECT * FROM (SELECT x.*, ROWNUM AS r FROM" + + " (SELECT * FROM people) x) WHERE r BETWEEN 1 AND 2"); + } else { + EasyMock.expect(delegate.getQueryString(0, 2)) + .andReturn("SELECT * FROM people LIMIT 2 OFFSET 0"); + } + EasyMock.replay(delegate); + + query.setDelegate(delegate); + query.beginTransaction(); + query.getResults(0, 2); + EasyMock.verify(delegate); + query.commit(); + } + + @Test + public void getResults_delegateImplementsGetQueryString_shouldHonorOffsetAndPagelength() + throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + if (SQLTestsConstants.db == DB.MSSQL) { + EasyMock.expect(delegate.getQueryString(0, 2)) + .andReturn("SELECT * FROM (SELECT row_number()" + + "OVER (ORDER BY id ASC) AS rownum, * FROM people)" + + " AS a WHERE a.rownum BETWEEN 0 AND 2"); + } else if (SQLTestsConstants.db == DB.ORACLE) { + EasyMock.expect(delegate.getQueryString(0, 2)) + .andReturn("SELECT * FROM (SELECT x.*, ROWNUM AS r FROM" + + " (SELECT * FROM people) x) WHERE r BETWEEN 1 AND 2"); + } else { + EasyMock.expect(delegate.getQueryString(0, 2)) + .andReturn("SELECT * FROM people LIMIT 2 OFFSET 0"); + } + EasyMock.replay(delegate); + query.setDelegate(delegate); + + query.beginTransaction(); + ResultSet rs = query.getResults(0, 2); + int rsoffset = 0; + if (SQLTestsConstants.db == DB.MSSQL) { + rsoffset++; + } + Assert.assertTrue(rs.next()); + Assert.assertEquals(0 + offset, rs.getInt(1 + rsoffset)); + Assert.assertEquals("Ville", rs.getString(2 + rsoffset)); + + Assert.assertTrue(rs.next()); + Assert.assertEquals(1 + offset, rs.getInt(1 + rsoffset)); + Assert.assertEquals("Kalle", rs.getString(2 + rsoffset)); + + Assert.assertFalse(rs.next()); + + EasyMock.verify(delegate); + query.commit(); + } + + @Test + public void getResults_delegateRegistered5000Rows_returns100rows() + throws SQLException { + DataGenerator.addFiveThousandPeople(connectionPool); + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + if (SQLTestsConstants.db == DB.MSSQL) { + EasyMock.expect(delegate.getQueryString(200, 100)) + .andReturn("SELECT * FROM (SELECT row_number()" + + "OVER (ORDER BY id ASC) AS rownum, * FROM people)" + + " AS a WHERE a.rownum BETWEEN 201 AND 300"); + } else if (SQLTestsConstants.db == DB.ORACLE) { + EasyMock.expect(delegate.getQueryString(200, 100)) + .andReturn("SELECT * FROM (SELECT x.*, ROWNUM AS r FROM" + + " (SELECT * FROM people ORDER BY ID ASC) x) WHERE r BETWEEN 201 AND 300"); + } else { + EasyMock.expect(delegate.getQueryString(200, 100)) + .andReturn("SELECT * FROM people LIMIT 100 OFFSET 200"); + } + EasyMock.replay(delegate); + query.setDelegate(delegate); + + query.beginTransaction(); + ResultSet rs = query.getResults(200, 100); + for (int i = 0; i < 100; i++) { + Assert.assertTrue(rs.next()); + Assert.assertEquals(200 + i + offset, rs.getInt("ID")); + } + Assert.assertFalse(rs.next()); + query.commit(); + } + + @Test + public void setFilters_delegateImplementsSetFilters_shouldPassFiltersToDelegate() { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + List<Filter> filters = new ArrayList<Filter>(); + filters.add(new Like("name", "%lle")); + delegate.setFilters(filters); + + EasyMock.replay(delegate); + query.setDelegate(delegate); + + query.setFilters(filters); + + EasyMock.verify(delegate); + } + + @Test(expected = UnsupportedOperationException.class) + public void setFilters_delegateDoesNotImplementSetFilters_shouldFail() { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + List<Filter> filters = new ArrayList<Filter>(); + filters.add(new Like("name", "%lle")); + delegate.setFilters(filters); + EasyMock.expectLastCall().andThrow(new UnsupportedOperationException()); + EasyMock.replay(delegate); + query.setDelegate(delegate); + + query.setFilters(filters); + + EasyMock.verify(delegate); + } + + @Test + public void setOrderBy_delegateImplementsSetOrderBy_shouldPassArgumentsToDelegate() { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + List<OrderBy> orderBys = Arrays.asList(new OrderBy("name", false)); + delegate.setOrderBy(orderBys); + EasyMock.replay(delegate); + query.setDelegate(delegate); + + query.setOrderBy(orderBys); + + EasyMock.verify(delegate); + } + + @Test(expected = UnsupportedOperationException.class) + public void setOrderBy_delegateDoesNotImplementSetOrderBy_shouldFail() { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + List<OrderBy> orderBys = Arrays.asList(new OrderBy("name", false)); + delegate.setOrderBy(orderBys); + EasyMock.expectLastCall().andThrow(new UnsupportedOperationException()); + EasyMock.replay(delegate); + query.setDelegate(delegate); + + query.setOrderBy(orderBys); + + EasyMock.verify(delegate); + } + + @Test + public void setFilters_noDelegateAndNullParameter_shouldSucceed() { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + query.setFilters(null); + } + + @Test + public void setOrderBy_noDelegateAndNullParameter_shouldSucceed() { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + query.setOrderBy(null); + } + + @Test + public void storeRow_delegateImplementsStoreRow_shouldPassToDelegate() + throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + EasyMock.expect(delegate.storeRow(EasyMock.isA(Connection.class), + EasyMock.isA(RowItem.class))).andReturn(1); + SQLContainer container = EasyMock.createNiceMock(SQLContainer.class); + EasyMock.replay(delegate, container); + query.setDelegate(delegate); + + query.beginTransaction(); + RowItem row = new RowItem(container, new RowId(new Object[] { 1 }), + null); + query.storeRow(row); + query.commit(); + + EasyMock.verify(delegate, container); + } + + @Test + public void storeRow_delegateDoesNotImplementStoreRow_shouldFail() + throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + EasyMock.expect(delegate.storeRow(EasyMock.isA(Connection.class), + EasyMock.isA(RowItem.class))) + .andThrow(new UnsupportedOperationException()); + SQLContainer container = EasyMock.createNiceMock(SQLContainer.class); + EasyMock.replay(delegate, container); + query.setDelegate(delegate); + + query.beginTransaction(); + RowItem row = new RowItem(container, new RowId(new Object[] { 1 }), + null); + try { + query.storeRow(row); + Assert.fail( + "storeRow should fail when delgate does not implement storeRow"); + } catch (UnsupportedOperationException e) { + // Cleanup to make test connection pool happy + query.rollback(); + } + } + + @Test + public void removeRow_delegateImplementsRemoveRow_shouldPassToDelegate() + throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + EasyMock.expect(delegate.removeRow(EasyMock.isA(Connection.class), + EasyMock.isA(RowItem.class))).andReturn(true); + SQLContainer container = EasyMock.createNiceMock(SQLContainer.class); + EasyMock.replay(delegate, container); + query.setDelegate(delegate); + + query.beginTransaction(); + RowItem row = new RowItem(container, new RowId(new Object[] { 1 }), + null); + query.removeRow(row); + query.commit(); + + EasyMock.verify(delegate, container); + } + + @Test + public void removeRow_delegateDoesNotImplementRemoveRow_shouldFail() + throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + EasyMock.expect(delegate.removeRow(EasyMock.isA(Connection.class), + EasyMock.isA(RowItem.class))) + .andThrow(new UnsupportedOperationException()); + SQLContainer container = EasyMock.createNiceMock(SQLContainer.class); + EasyMock.replay(delegate, container); + query.setDelegate(delegate); + + query.beginTransaction(); + RowItem row = new RowItem(container, new RowId(new Object[] { 1 }), + null); + try { + query.removeRow(row); + Assert.fail( + "removeRow should fail when delegate does not implement removeRow"); + } catch (UnsupportedOperationException e) { + // Cleanup to make test connection pool happy + query.rollback(); + } + } + + @Test + public void beginTransaction_delegateRegistered_shouldSucceed() + throws UnsupportedOperationException, SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + EasyMock.replay(delegate); + query.setDelegate(delegate); + + query.beginTransaction(); + // Cleanup to make test connection pool happy + query.rollback(); + } + + @Test + public void beginTransaction_transactionAlreadyActive_shouldFail() + throws SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + + query.beginTransaction(); + try { + query.beginTransaction(); + Assert.fail( + "Should throw exception when starting a transaction while already in a transaction"); + } catch (IllegalStateException e) { + // Cleanup to make test connection pool happy + query.rollback(); + } + } + + @Test(expected = SQLException.class) + public void commit_delegateRegisteredNoActiveTransaction_shouldFail() + throws UnsupportedOperationException, SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + EasyMock.replay(delegate); + query.setDelegate(delegate); + + query.commit(); + } + + @Test + public void commit_delegateRegisteredActiveTransaction_shouldSucceed() + throws UnsupportedOperationException, SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + EasyMock.replay(delegate); + query.setDelegate(delegate); + + query.beginTransaction(); + query.commit(); + } + + @Test(expected = SQLException.class) + public void commit_delegateRegisteredActiveTransactionDoubleCommit_shouldFail() + throws UnsupportedOperationException, SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + EasyMock.replay(delegate); + query.setDelegate(delegate); + + query.beginTransaction(); + query.commit(); + query.commit(); + } + + @Test(expected = SQLException.class) + public void rollback_delegateRegisteredNoActiveTransaction_shouldFail() + throws UnsupportedOperationException, SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + EasyMock.replay(delegate); + query.setDelegate(delegate); + + query.rollback(); + } + + @Test + public void rollback_delegateRegisteredActiveTransaction_shouldSucceed() + throws UnsupportedOperationException, SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + EasyMock.replay(delegate); + query.setDelegate(delegate); + + query.beginTransaction(); + query.rollback(); + } + + @Test(expected = SQLException.class) + public void rollback_delegateRegisteredActiveTransactionDoubleRollback_shouldFail() + throws UnsupportedOperationException, SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + EasyMock.replay(delegate); + query.setDelegate(delegate); + + query.beginTransaction(); + query.rollback(); + query.rollback(); + } + + @Test(expected = SQLException.class) + public void rollback_delegateRegisteredCommittedTransaction_shouldFail() + throws UnsupportedOperationException, SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + EasyMock.replay(delegate); + query.setDelegate(delegate); + + query.beginTransaction(); + query.commit(); + query.rollback(); + } + + @Test(expected = SQLException.class) + public void commit_delegateRegisteredRollbackedTransaction_shouldFail() + throws UnsupportedOperationException, SQLException { + FreeformQuery query = new FreeformQuery("SELECT * FROM people", + Arrays.asList("ID"), connectionPool); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + EasyMock.replay(delegate); + query.setDelegate(delegate); + + query.beginTransaction(); + query.rollback(); + query.commit(); + } + + @Test(expected = SQLException.class) + public void containsRowWithKeys_delegateRegistered_shouldCallGetContainsRowQueryString() + throws SQLException { + FreeformQuery query = new FreeformQuery( + "SELECT * FROM people WHERE name LIKE '%lle'", + Arrays.asList("ID"), connectionPool); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + EasyMock.expect(delegate.getContainsRowQueryString(1)).andReturn(""); + EasyMock.replay(delegate); + query.setDelegate(delegate); + + query.containsRowWithKey(1); + + EasyMock.verify(delegate); + } + + @Test + public void containsRowWithKeys_delegateRegistered_shouldUseResultFromGetContainsRowQueryString() + throws SQLException { + FreeformQuery query = new FreeformQuery( + "SELECT * FROM people WHERE \"NAME\" LIKE '%lle'", + Arrays.asList("ID"), connectionPool); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + // In order to test that this is the query that is actually used, we use + // a non-existing id in place of the existing one. + EasyMock.expect(delegate.getContainsRowQueryString(1)).andReturn( + "SELECT * FROM people WHERE \"NAME\" LIKE '%lle' AND \"ID\" = 1337"); + EasyMock.replay(delegate); + query.setDelegate(delegate); + + // The id (key) used should be 1337 as above, for the call with key = 1 + Assert.assertFalse(query.containsRowWithKey(1)); + + EasyMock.verify(delegate); + } + + public static class NonMatchingDelegateWithGroupBy + implements FreeformQueryDelegate { + + private String fromWhere = "FROM people p1 LEFT JOIN people p2 ON p2.id = p1.id WHERE p1.\"NAME\" LIKE 'notfound' GROUP BY p1.ID"; + + @Override + public int storeRow(Connection conn, RowItem row) + throws UnsupportedOperationException, SQLException { + // Not used in this test + return 0; + } + + @Override + public void setOrderBy(List<OrderBy> orderBys) + throws UnsupportedOperationException { + // Not used in this test + } + + @Override + public void setFilters(List<Filter> filters) + throws UnsupportedOperationException { + // Not used in this test + } + + @Override + public boolean removeRow(Connection conn, RowItem row) + throws UnsupportedOperationException, SQLException { + // Not used in this test + return false; + } + + @Override + public String getQueryString(int offset, int limit) + throws UnsupportedOperationException { + return "SELECT * " + fromWhere; + } + + @Override + public String getCountQuery() throws UnsupportedOperationException { + return "SELECT COUNT(*) " + fromWhere; + } + + @Override + public String getContainsRowQueryString(Object... keys) + throws UnsupportedOperationException { + // Not used in this test + return null; + } + } + + public static class NonMatchingStatementDelegateWithGroupBy + extends NonMatchingDelegateWithGroupBy + implements FreeformStatementDelegate { + + @Override + public StatementHelper getQueryStatement(int offset, int limit) + throws UnsupportedOperationException { + StatementHelper sh = new StatementHelper(); + sh.setQueryString(getQueryString(offset, limit)); + return sh; + } + + @Override + public StatementHelper getCountStatement() + throws UnsupportedOperationException { + StatementHelper sh = new StatementHelper(); + sh.setQueryString(getCountQuery()); + return sh; + } + + @Override + public StatementHelper getContainsRowQueryStatement(Object... keys) + throws UnsupportedOperationException { + // Not used in this test + return null; + } + } + + @Test + public void containsRowWithKeys_delegateRegisteredGetContainsRowQueryStringNotImplemented_shouldBuildQueryString() + throws SQLException { + FreeformQuery query = new FreeformQuery( + "SELECT * FROM people WHERE \"NAME\" LIKE '%lle'", + Arrays.asList("ID"), connectionPool); + FreeformQueryDelegate delegate = EasyMock + .createMock(FreeformQueryDelegate.class); + EasyMock.expect(delegate.getContainsRowQueryString(1)) + .andThrow(new UnsupportedOperationException()); + EasyMock.replay(delegate); + query.setDelegate(delegate); + + Assert.assertTrue(query.containsRowWithKey(1)); + + EasyMock.verify(delegate); + } + + @Test + public void delegateStatementCountWithGroupBy() throws SQLException { + String dummyNotUsed = "foo"; + FreeformQuery query = new FreeformQuery(dummyNotUsed, connectionPool, + "p1.ID"); + query.setDelegate(new NonMatchingStatementDelegateWithGroupBy()); + + Assert.assertEquals(0, query.getCount()); + } + + @Test + public void delegateCountWithGroupBy() throws SQLException { + String dummyNotUsed = "foo"; + FreeformQuery query = new FreeformQuery(dummyNotUsed, connectionPool, + "p1.ID"); + query.setDelegate(new NonMatchingDelegateWithGroupBy()); + + Assert.assertEquals(0, query.getCount()); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/query/QueryBuilderTest.java b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/query/QueryBuilderTest.java new file mode 100644 index 0000000000..7974582147 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/query/QueryBuilderTest.java @@ -0,0 +1,315 @@ +package com.vaadin.data.util.sqlcontainer.query; + +import java.util.ArrayList; + +import org.easymock.EasyMock; +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.data.Container.Filter; +import com.vaadin.data.util.filter.And; +import com.vaadin.data.util.filter.Between; +import com.vaadin.data.util.filter.Compare.Equal; +import com.vaadin.data.util.filter.Compare.Greater; +import com.vaadin.data.util.filter.Compare.GreaterOrEqual; +import com.vaadin.data.util.filter.Compare.Less; +import com.vaadin.data.util.filter.Compare.LessOrEqual; +import com.vaadin.data.util.filter.IsNull; +import com.vaadin.data.util.filter.Like; +import com.vaadin.data.util.filter.Not; +import com.vaadin.data.util.filter.Or; +import com.vaadin.data.util.filter.SimpleStringFilter; +import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; +import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder; +import com.vaadin.data.util.sqlcontainer.query.generator.filter.StringDecorator; + +public class QueryBuilderTest { + + private StatementHelper mockedStatementHelper(Object... values) { + StatementHelper sh = EasyMock.createMock(StatementHelper.class); + for (Object val : values) { + sh.addParameterValue(val); + EasyMock.expectLastCall(); + } + EasyMock.replay(sh); + return sh; + } + + // escape bad characters and wildcards + + @Test + public void getWhereStringForFilter_equals() { + StatementHelper sh = mockedStatementHelper("Fido"); + Equal f = new Equal("NAME", "Fido"); + Assert.assertEquals("\"NAME\" = ?", + QueryBuilder.getWhereStringForFilter(f, sh)); + EasyMock.verify(sh); + } + + @Test + public void getWhereStringForFilter_greater() { + StatementHelper sh = mockedStatementHelper(18); + Greater f = new Greater("AGE", 18); + Assert.assertEquals("\"AGE\" > ?", + QueryBuilder.getWhereStringForFilter(f, sh)); + EasyMock.verify(sh); + } + + @Test + public void getWhereStringForFilter_less() { + StatementHelper sh = mockedStatementHelper(65); + Less f = new Less("AGE", 65); + Assert.assertEquals("\"AGE\" < ?", + QueryBuilder.getWhereStringForFilter(f, sh)); + EasyMock.verify(sh); + } + + @Test + public void getWhereStringForFilter_greaterOrEqual() { + StatementHelper sh = mockedStatementHelper(18); + GreaterOrEqual f = new GreaterOrEqual("AGE", 18); + Assert.assertEquals("\"AGE\" >= ?", + QueryBuilder.getWhereStringForFilter(f, sh)); + EasyMock.verify(sh); + } + + @Test + public void getWhereStringForFilter_lessOrEqual() { + StatementHelper sh = mockedStatementHelper(65); + LessOrEqual f = new LessOrEqual("AGE", 65); + Assert.assertEquals("\"AGE\" <= ?", + QueryBuilder.getWhereStringForFilter(f, sh)); + EasyMock.verify(sh); + } + + @Test + public void getWhereStringForFilter_simpleStringFilter() { + StatementHelper sh = mockedStatementHelper("Vi%"); + SimpleStringFilter f = new SimpleStringFilter("NAME", "Vi", false, + true); + Assert.assertEquals("\"NAME\" LIKE ?", + QueryBuilder.getWhereStringForFilter(f, sh)); + EasyMock.verify(sh); + } + + @Test + public void getWhereStringForFilter_simpleStringFilterMatchAnywhere() { + StatementHelper sh = mockedStatementHelper("%Vi%"); + SimpleStringFilter f = new SimpleStringFilter("NAME", "Vi", false, + false); + Assert.assertEquals("\"NAME\" LIKE ?", + QueryBuilder.getWhereStringForFilter(f, sh)); + EasyMock.verify(sh); + } + + @Test + public void getWhereStringForFilter_simpleStringFilterMatchAnywhereIgnoreCase() { + StatementHelper sh = mockedStatementHelper("%VI%"); + SimpleStringFilter f = new SimpleStringFilter("NAME", "Vi", true, + false); + Assert.assertEquals("UPPER(\"NAME\") LIKE ?", + QueryBuilder.getWhereStringForFilter(f, sh)); + EasyMock.verify(sh); + } + + @Test + public void getWhereStringForFilter_startsWith() { + StatementHelper sh = mockedStatementHelper("Vi%"); + Like f = new Like("NAME", "Vi%"); + Assert.assertEquals("\"NAME\" LIKE ?", + QueryBuilder.getWhereStringForFilter(f, sh)); + EasyMock.verify(sh); + } + + @Test + public void getWhereStringForFilter_startsWithNumber() { + StatementHelper sh = mockedStatementHelper("1%"); + Like f = new Like("AGE", "1%"); + Assert.assertEquals("\"AGE\" LIKE ?", + QueryBuilder.getWhereStringForFilter(f, sh)); + EasyMock.verify(sh); + } + + @Test + public void getWhereStringForFilter_endsWith() { + StatementHelper sh = mockedStatementHelper("%lle"); + Like f = new Like("NAME", "%lle"); + Assert.assertEquals("\"NAME\" LIKE ?", + QueryBuilder.getWhereStringForFilter(f, sh)); + EasyMock.verify(sh); + } + + @Test + public void getWhereStringForFilter_contains() { + StatementHelper sh = mockedStatementHelper("%ill%"); + Like f = new Like("NAME", "%ill%"); + Assert.assertEquals("\"NAME\" LIKE ?", + QueryBuilder.getWhereStringForFilter(f, sh)); + EasyMock.verify(sh); + } + + @Test + public void getWhereStringForFilter_between() { + StatementHelper sh = mockedStatementHelper(18, 65); + Between f = new Between("AGE", 18, 65); + Assert.assertEquals("\"AGE\" BETWEEN ? AND ?", + QueryBuilder.getWhereStringForFilter(f, sh)); + EasyMock.verify(sh); + } + + @Test + public void getWhereStringForFilter_caseInsensitive_equals() { + StatementHelper sh = mockedStatementHelper("FIDO"); + Like f = new Like("NAME", "Fido"); + f.setCaseSensitive(false); + Assert.assertEquals("UPPER(\"NAME\") LIKE ?", + QueryBuilder.getWhereStringForFilter(f, sh)); + EasyMock.verify(sh); + } + + @Test + public void getWhereStringForFilter_caseInsensitive_startsWith() { + StatementHelper sh = mockedStatementHelper("VI%"); + Like f = new Like("NAME", "Vi%"); + f.setCaseSensitive(false); + Assert.assertEquals("UPPER(\"NAME\") LIKE ?", + QueryBuilder.getWhereStringForFilter(f, sh)); + EasyMock.verify(sh); + } + + @Test + public void getWhereStringForFilter_caseInsensitive_endsWith() { + StatementHelper sh = mockedStatementHelper("%LLE"); + Like f = new Like("NAME", "%lle"); + f.setCaseSensitive(false); + Assert.assertEquals("UPPER(\"NAME\") LIKE ?", + QueryBuilder.getWhereStringForFilter(f, sh)); + EasyMock.verify(sh); + } + + @Test + public void getWhereStringForFilter_caseInsensitive_contains() { + StatementHelper sh = mockedStatementHelper("%ILL%"); + Like f = new Like("NAME", "%ill%"); + f.setCaseSensitive(false); + Assert.assertEquals("UPPER(\"NAME\") LIKE ?", + QueryBuilder.getWhereStringForFilter(f, sh)); + EasyMock.verify(sh); + } + + @Test + public void getWhereStringForFilters_listOfFilters() { + StatementHelper sh = mockedStatementHelper("%lle", 18); + ArrayList<Filter> filters = new ArrayList<Filter>(); + filters.add(new Like("NAME", "%lle")); + filters.add(new Greater("AGE", 18)); + Assert.assertEquals(" WHERE \"NAME\" LIKE ? AND \"AGE\" > ?", + QueryBuilder.getWhereStringForFilters(filters, sh)); + EasyMock.verify(sh); + } + + @Test + public void getWhereStringForFilters_oneAndFilter() { + StatementHelper sh = mockedStatementHelper("%lle", 18); + ArrayList<Filter> filters = new ArrayList<Filter>(); + filters.add(new And(new Like("NAME", "%lle"), new Greater("AGE", 18))); + Assert.assertEquals(" WHERE (\"NAME\" LIKE ? AND \"AGE\" > ?)", + QueryBuilder.getWhereStringForFilters(filters, sh)); + EasyMock.verify(sh); + } + + @Test + public void getWhereStringForFilters_oneOrFilter() { + StatementHelper sh = mockedStatementHelper("%lle", 18); + ArrayList<Filter> filters = new ArrayList<Filter>(); + filters.add(new Or(new Like("NAME", "%lle"), new Greater("AGE", 18))); + Assert.assertEquals(" WHERE (\"NAME\" LIKE ? OR \"AGE\" > ?)", + QueryBuilder.getWhereStringForFilters(filters, sh)); + EasyMock.verify(sh); + } + + @Test + public void getWhereStringForFilters_complexCompoundFilters() { + StatementHelper sh = mockedStatementHelper("%lle", 18, 65, "Pelle"); + ArrayList<Filter> filters = new ArrayList<Filter>(); + filters.add(new Or( + new And(new Like("NAME", "%lle"), + new Or(new Less("AGE", 18), new Greater("AGE", 65))), + new Equal("NAME", "Pelle"))); + Assert.assertEquals( + " WHERE ((\"NAME\" LIKE ? AND (\"AGE\" < ? OR \"AGE\" > ?)) OR \"NAME\" = ?)", + QueryBuilder.getWhereStringForFilters(filters, sh)); + EasyMock.verify(sh); + } + + @Test + public void getWhereStringForFilters_complexCompoundFiltersAndSingleFilter() { + StatementHelper sh = mockedStatementHelper("%lle", 18, 65, "Pelle", + "Virtanen"); + ArrayList<Filter> filters = new ArrayList<Filter>(); + filters.add(new Or( + new And(new Like("NAME", "%lle"), + new Or(new Less("AGE", 18), new Greater("AGE", 65))), + new Equal("NAME", "Pelle"))); + filters.add(new Equal("LASTNAME", "Virtanen")); + Assert.assertEquals( + " WHERE ((\"NAME\" LIKE ? AND (\"AGE\" < ? OR \"AGE\" > ?)) OR \"NAME\" = ?) AND \"LASTNAME\" = ?", + QueryBuilder.getWhereStringForFilters(filters, sh)); + EasyMock.verify(sh); + } + + @Test + public void getWhereStringForFilters_emptyList_shouldReturnEmptyString() { + ArrayList<Filter> filters = new ArrayList<Filter>(); + Assert.assertEquals("", QueryBuilder.getWhereStringForFilters(filters, + new StatementHelper())); + } + + @Test + public void getWhereStringForFilters_NotFilter() { + StatementHelper sh = mockedStatementHelper(18); + ArrayList<Filter> filters = new ArrayList<Filter>(); + filters.add(new Not(new Equal("AGE", 18))); + Assert.assertEquals(" WHERE NOT \"AGE\" = ?", + QueryBuilder.getWhereStringForFilters(filters, sh)); + EasyMock.verify(sh); + } + + @Test + public void getWhereStringForFilters_complexNegatedFilter() { + StatementHelper sh = mockedStatementHelper(65, 18); + ArrayList<Filter> filters = new ArrayList<Filter>(); + filters.add( + new Not(new Or(new Equal("AGE", 65), new Equal("AGE", 18)))); + Assert.assertEquals(" WHERE NOT (\"AGE\" = ? OR \"AGE\" = ?)", + QueryBuilder.getWhereStringForFilters(filters, sh)); + EasyMock.verify(sh); + } + + @Test + public void getWhereStringForFilters_isNull() { + ArrayList<Filter> filters = new ArrayList<Filter>(); + filters.add(new IsNull("NAME")); + Assert.assertEquals(" WHERE \"NAME\" IS NULL", QueryBuilder + .getWhereStringForFilters(filters, new StatementHelper())); + } + + @Test + public void getWhereStringForFilters_isNotNull() { + ArrayList<Filter> filters = new ArrayList<Filter>(); + filters.add(new Not(new IsNull("NAME"))); + Assert.assertEquals(" WHERE \"NAME\" IS NOT NULL", QueryBuilder + .getWhereStringForFilters(filters, new StatementHelper())); + } + + @Test + public void getWhereStringForFilters_customStringDecorator() { + QueryBuilder.setStringDecorator(new StringDecorator("[", "]")); + ArrayList<Filter> filters = new ArrayList<Filter>(); + filters.add(new Not(new IsNull("NAME"))); + Assert.assertEquals(" WHERE [NAME] IS NOT NULL", QueryBuilder + .getWhereStringForFilters(filters, new StatementHelper())); + // Reset the default string decorator + QueryBuilder.setStringDecorator(new StringDecorator("\"", "\"")); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/query/TableQueryTest.java b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/query/TableQueryTest.java new file mode 100644 index 0000000000..d2067a85b4 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/query/TableQueryTest.java @@ -0,0 +1,746 @@ +package com.vaadin.data.util.sqlcontainer.query; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.data.Container.Filter; +import com.vaadin.data.util.filter.Compare.Equal; +import com.vaadin.data.util.filter.Like; +import com.vaadin.data.util.sqlcontainer.DataGenerator; +import com.vaadin.data.util.sqlcontainer.OptimisticLockException; +import com.vaadin.data.util.sqlcontainer.RowItem; +import com.vaadin.data.util.sqlcontainer.SQLContainer; +import com.vaadin.data.util.sqlcontainer.SQLTestsConstants; +import com.vaadin.data.util.sqlcontainer.SQLTestsConstants.DB; +import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool; +import com.vaadin.data.util.sqlcontainer.query.generator.DefaultSQLGenerator; + +public class TableQueryTest { + private static final int offset = SQLTestsConstants.offset; + private JDBCConnectionPool connectionPool; + + @Before + public void setUp() throws SQLException { + try { + connectionPool = new ValidatingSimpleJDBCConnectionPool( + SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL, + SQLTestsConstants.dbUser, SQLTestsConstants.dbPwd, 2, 2); + } catch (SQLException e) { + e.printStackTrace(); + Assert.fail(e.getMessage()); + } + DataGenerator.addPeopleToDatabase(connectionPool); + } + + @After + public void tearDown() { + if (connectionPool != null) { + connectionPool.destroy(); + } + } + + /********************************************************************** + * TableQuery construction tests + **********************************************************************/ + @Test + public void construction_legalParameters_shouldSucceed() { + TableQuery tQuery = new TableQuery("people", connectionPool, + new DefaultSQLGenerator()); + Assert.assertArrayEquals(new Object[] { "ID" }, + tQuery.getPrimaryKeyColumns().toArray()); + boolean correctTableName = "people" + .equalsIgnoreCase(tQuery.getTableName()); + Assert.assertTrue(correctTableName); + } + + @Test + public void construction_legalParameters_defaultGenerator_shouldSucceed() { + TableQuery tQuery = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + Assert.assertArrayEquals(new Object[] { "ID" }, + tQuery.getPrimaryKeyColumns().toArray()); + boolean correctTableName = "people" + .equalsIgnoreCase(tQuery.getTableName()); + Assert.assertTrue(correctTableName); + } + + @Test(expected = IllegalArgumentException.class) + public void construction_nonExistingTableName_shouldFail() { + new TableQuery("skgwaguhsd", connectionPool, new DefaultSQLGenerator()); + } + + @Test(expected = IllegalArgumentException.class) + public void construction_emptyTableName_shouldFail() { + new TableQuery("", connectionPool, new DefaultSQLGenerator()); + } + + @Test(expected = IllegalArgumentException.class) + public void construction_nullSqlGenerator_shouldFail() { + new TableQuery("people", connectionPool, null); + } + + @Test(expected = IllegalArgumentException.class) + public void construction_nullConnectionPool_shouldFail() { + new TableQuery("people", null, new DefaultSQLGenerator()); + } + + /********************************************************************** + * TableQuery row count tests + **********************************************************************/ + @Test + public void getCount_simpleQuery_returnsFour() throws SQLException { + TableQuery tQuery = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + Assert.assertEquals(4, tQuery.getCount()); + } + + @Test + public void getCount_simpleQueryTwoMorePeopleAdded_returnsSix() + throws SQLException { + // Add some people + Connection conn = connectionPool.reserveConnection(); + Statement statement = conn.createStatement(); + if (SQLTestsConstants.db == DB.MSSQL) { + statement.executeUpdate("insert into people values('Bengt', 30)"); + statement.executeUpdate("insert into people values('Ingvar', 50)"); + } else { + statement.executeUpdate( + "insert into people values(default, 'Bengt', 30)"); + statement.executeUpdate( + "insert into people values(default, 'Ingvar', 50)"); + } + statement.close(); + conn.commit(); + connectionPool.releaseConnection(conn); + + TableQuery tQuery = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + + Assert.assertEquals(6, tQuery.getCount()); + } + + @Test + public void getCount_normalState_releasesConnection() throws SQLException { + TableQuery tQuery = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + tQuery.getCount(); + tQuery.getCount(); + Connection c = connectionPool.reserveConnection(); + Assert.assertNotNull(c); + connectionPool.releaseConnection(c); + } + + /********************************************************************** + * TableQuery get results tests + **********************************************************************/ + @Test + public void getResults_simpleQuery_returnsFourRecords() + throws SQLException { + TableQuery tQuery = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + tQuery.beginTransaction(); + ResultSet rs = tQuery.getResults(0, 0); + + Assert.assertTrue(rs.next()); + Assert.assertEquals(0 + offset, rs.getInt(1)); + Assert.assertEquals("Ville", rs.getString(2)); + + Assert.assertTrue(rs.next()); + Assert.assertEquals(1 + offset, rs.getInt(1)); + Assert.assertEquals("Kalle", rs.getString(2)); + + Assert.assertTrue(rs.next()); + Assert.assertEquals(2 + offset, rs.getInt(1)); + Assert.assertEquals("Pelle", rs.getString(2)); + + Assert.assertTrue(rs.next()); + Assert.assertEquals(3 + offset, rs.getInt(1)); + Assert.assertEquals("Börje", rs.getString(2)); + + Assert.assertFalse(rs.next()); + tQuery.commit(); + } + + @Test + public void getResults_noDelegate5000Rows_returns5000rows() + throws SQLException { + DataGenerator.addFiveThousandPeople(connectionPool); + + TableQuery tQuery = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + + tQuery.beginTransaction(); + ResultSet rs = tQuery.getResults(0, 0); + for (int i = 0; i < 5000; i++) { + Assert.assertTrue(rs.next()); + } + Assert.assertFalse(rs.next()); + tQuery.commit(); + } + + /********************************************************************** + * TableQuery transaction management tests + **********************************************************************/ + @Test + public void beginTransaction_transactionAlreadyActive_shouldFail() + throws SQLException { + TableQuery tQuery = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + + tQuery.beginTransaction(); + try { + tQuery.beginTransaction(); + Assert.fail( + "Should throw exception when starting a transaction while already in a transaction"); + } catch (IllegalStateException e) { + // Cleanup to make test connection pool happy + tQuery.rollback(); + } + } + + @Test + public void commit_readOnly_shouldSucceed() throws SQLException { + TableQuery tQuery = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + tQuery.beginTransaction(); + tQuery.commit(); + } + + @Test + public void rollback_readOnly_shouldSucceed() throws SQLException { + TableQuery tQuery = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + tQuery.beginTransaction(); + tQuery.rollback(); + } + + @Test(expected = SQLException.class) + public void commit_noActiveTransaction_shouldFail() throws SQLException { + TableQuery tQuery = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + tQuery.commit(); + } + + @Test(expected = SQLException.class) + public void rollback_noActiveTransaction_shouldFail() throws SQLException { + TableQuery tQuery = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + tQuery.rollback(); + } + + /********************************************************************** + * TableQuery row query with given keys tests + **********************************************************************/ + @Test + public void containsRowWithKeys_existingKeys_returnsTrue() + throws SQLException { + TableQuery tQuery = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + Assert.assertTrue(tQuery.containsRowWithKey(1)); + } + + @Test + public void containsRowWithKeys_nonexistingKeys_returnsTrue() + throws SQLException { + TableQuery tQuery = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + + Assert.assertFalse(tQuery.containsRowWithKey(1337)); + } + + @Test + public void containsRowWithKeys_invalidKeys_shouldFail() + throws SQLException { + TableQuery tQuery = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + boolean b = true; + try { + b = tQuery.containsRowWithKey("foo"); + } catch (SQLException se) { + return; + } + Assert.assertFalse(b); + } + + @Test + public void containsRowWithKeys_nullKeys_shouldFailAndReleaseConnections() + throws SQLException { + TableQuery tQuery = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + try { + tQuery.containsRowWithKey(new Object[] { null }); + org.junit.Assert.fail( + "null should throw an IllegalArgumentException from StatementHelper"); + } catch (IllegalArgumentException e) { + // We should now be able to reserve two connections + Connection c1 = connectionPool.reserveConnection(); + Connection c2 = connectionPool.reserveConnection(); + + // Cleanup to make test connection pool happy + connectionPool.releaseConnection(c1); + connectionPool.releaseConnection(c2); + + } + } + + /********************************************************************** + * TableQuery filtering and ordering tests + **********************************************************************/ + @Test + public void setFilters_shouldReturnCorrectCount() throws SQLException { + TableQuery tQuery = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + List<Filter> filters = new ArrayList<Filter>(); + filters.add(new Like("NAME", "%lle")); + tQuery.setFilters(filters); + Assert.assertEquals(3, tQuery.getCount()); + } + + @Test + public void setOrderByNameAscending_shouldReturnCorrectOrder() + throws SQLException { + TableQuery tQuery = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + + List<OrderBy> orderBys = Arrays.asList(new OrderBy("NAME", true)); + tQuery.setOrderBy(orderBys); + + tQuery.beginTransaction(); + ResultSet rs; + rs = tQuery.getResults(0, 0); + + Assert.assertTrue(rs.next()); + Assert.assertEquals(3 + offset, rs.getInt(1)); + Assert.assertEquals("Börje", rs.getString(2)); + + Assert.assertTrue(rs.next()); + Assert.assertEquals(1 + offset, rs.getInt(1)); + Assert.assertEquals("Kalle", rs.getString(2)); + + Assert.assertTrue(rs.next()); + Assert.assertEquals(2 + offset, rs.getInt(1)); + Assert.assertEquals("Pelle", rs.getString(2)); + + Assert.assertTrue(rs.next()); + Assert.assertEquals(0 + offset, rs.getInt(1)); + Assert.assertEquals("Ville", rs.getString(2)); + + Assert.assertFalse(rs.next()); + tQuery.commit(); + } + + @Test + public void setOrderByNameDescending_shouldReturnCorrectOrder() + throws SQLException { + TableQuery tQuery = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + + List<OrderBy> orderBys = Arrays.asList(new OrderBy("NAME", false)); + tQuery.setOrderBy(orderBys); + + tQuery.beginTransaction(); + ResultSet rs; + rs = tQuery.getResults(0, 0); + + Assert.assertTrue(rs.next()); + Assert.assertEquals(0 + offset, rs.getInt(1)); + Assert.assertEquals("Ville", rs.getString(2)); + + Assert.assertTrue(rs.next()); + Assert.assertEquals(2 + offset, rs.getInt(1)); + Assert.assertEquals("Pelle", rs.getString(2)); + + Assert.assertTrue(rs.next()); + Assert.assertEquals(1 + offset, rs.getInt(1)); + Assert.assertEquals("Kalle", rs.getString(2)); + + Assert.assertTrue(rs.next()); + Assert.assertEquals(3 + offset, rs.getInt(1)); + Assert.assertEquals("Börje", rs.getString(2)); + + Assert.assertFalse(rs.next()); + tQuery.commit(); + } + + @Test + public void setFilters_nullParameter_shouldSucceed() { + TableQuery tQuery = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + tQuery.setFilters(null); + } + + @Test + public void setOrderBy_nullParameter_shouldSucceed() { + TableQuery tQuery = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + tQuery.setOrderBy(null); + } + + /********************************************************************** + * TableQuery row removal tests + **********************************************************************/ + @Test + public void removeRowThroughContainer_legalRowItem_shouldSucceed() + throws SQLException { + TableQuery tQuery = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + SQLContainer container = new SQLContainer(tQuery); + container.setAutoCommit(false); + Assert.assertTrue( + container.removeItem(container.getItemIds().iterator().next())); + + Assert.assertEquals(4, tQuery.getCount()); + Assert.assertEquals(3, container.size()); + container.commit(); + + Assert.assertEquals(3, tQuery.getCount()); + Assert.assertEquals(3, container.size()); + } + + @Test + public void removeRowThroughContainer_nonexistingRowId_shouldFail() + throws SQLException { + TableQuery tQuery = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + + SQLContainer container = new SQLContainer(tQuery); + container.setAutoCommit(true); + Assert.assertFalse(container.removeItem("foo")); + } + + /********************************************************************** + * TableQuery row adding / modification tests + **********************************************************************/ + @Test + public void insertRowThroughContainer_shouldSucceed() throws SQLException { + TableQuery tQuery = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + tQuery.setVersionColumn("ID"); + + SQLContainer container = new SQLContainer(tQuery); + container.setAutoCommit(false); + + Object item = container.addItem(); + Assert.assertNotNull(item); + + Assert.assertEquals(4, tQuery.getCount()); + Assert.assertEquals(5, container.size()); + container.commit(); + + Assert.assertEquals(5, tQuery.getCount()); + Assert.assertEquals(5, container.size()); + } + + @Test + public void modifyRowThroughContainer_shouldSucceed() throws SQLException { + TableQuery tQuery = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + + // In this test the primary key is used as a version column + tQuery.setVersionColumn("ID"); + SQLContainer container = new SQLContainer(tQuery); + container.setAutoCommit(false); + + /* Check that the container size is correct and there is no 'Viljami' */ + Assert.assertEquals(4, container.size()); + List<Filter> filters = new ArrayList<Filter>(); + filters.add(new Equal("NAME", "Viljami")); + tQuery.setFilters(filters); + Assert.assertEquals(0, tQuery.getCount()); + tQuery.setFilters(null); + + /* Fetch first item, modify and commit */ + Object item = container + .getItem(container.getItemIds().iterator().next()); + Assert.assertNotNull(item); + + RowItem ri = (RowItem) item; + Assert.assertNotNull(ri.getItemProperty("NAME")); + ri.getItemProperty("NAME").setValue("Viljami"); + + container.commit(); + + // Check that the size is still correct and only 1 'Viljami' is found + Assert.assertEquals(4, tQuery.getCount()); + Assert.assertEquals(4, container.size()); + tQuery.setFilters(filters); + Assert.assertEquals(1, tQuery.getCount()); + } + + @Test + public void storeRow_noVersionColumn_shouldSucceed() + throws UnsupportedOperationException, SQLException { + TableQuery tQuery = new TableQuery("people", connectionPool, + SQLTestsConstants.sqlGen); + SQLContainer container = new SQLContainer(tQuery); + Object id = container.addItem(); + RowItem row = (RowItem) container.getItem(id); + row.getItemProperty("NAME").setValue("R2D2"); + row.getItemProperty("AGE").setValue(123); + tQuery.beginTransaction(); + tQuery.storeRow(row); + tQuery.commit(); + + Connection conn = connectionPool.reserveConnection(); + PreparedStatement stmt = conn + .prepareStatement("SELECT * FROM PEOPLE WHERE \"NAME\" = ?"); + stmt.setString(1, "R2D2"); + ResultSet rs = stmt.executeQuery(); + Assert.assertTrue(rs.next()); + rs.close(); + stmt.close(); + connectionPool.releaseConnection(conn); + } + + @Test + public void storeRow_versionSetAndEqualToDBValue_shouldSucceed() + throws SQLException { + DataGenerator.addVersionedData(connectionPool); + + TableQuery tQuery = new TableQuery("versioned", connectionPool, + SQLTestsConstants.sqlGen); + tQuery.setVersionColumn("VERSION"); + SQLContainer container = new SQLContainer(tQuery); + RowItem row = (RowItem) container.getItem(container.firstItemId()); + Assert.assertEquals("Junk", row.getItemProperty("TEXT").getValue()); + + row.getItemProperty("TEXT").setValue("asdf"); + container.commit(); + + Connection conn = connectionPool.reserveConnection(); + PreparedStatement stmt = conn + .prepareStatement("SELECT * FROM VERSIONED WHERE \"TEXT\" = ?"); + stmt.setString(1, "asdf"); + ResultSet rs = stmt.executeQuery(); + Assert.assertTrue(rs.next()); + rs.close(); + stmt.close(); + conn.commit(); + connectionPool.releaseConnection(conn); + } + + @Test(expected = OptimisticLockException.class) + public void storeRow_versionSetAndLessThanDBValue_shouldThrowException() + throws SQLException { + if (SQLTestsConstants.db == DB.HSQLDB) { + throw new OptimisticLockException( + "HSQLDB doesn't support row versioning for optimistic locking - don't run this test.", + null); + } + DataGenerator.addVersionedData(connectionPool); + + TableQuery tQuery = new TableQuery("versioned", connectionPool, + SQLTestsConstants.sqlGen); + tQuery.setVersionColumn("VERSION"); + SQLContainer container = new SQLContainer(tQuery); + RowItem row = (RowItem) container.getItem(container.firstItemId()); + Assert.assertEquals("Junk", row.getItemProperty("TEXT").getValue()); + + row.getItemProperty("TEXT").setValue("asdf"); + + // Update the version using another connection. + Connection conn = connectionPool.reserveConnection(); + PreparedStatement stmt = conn.prepareStatement( + "UPDATE VERSIONED SET \"TEXT\" = ? WHERE \"ID\" = ?"); + stmt.setString(1, "foo"); + stmt.setObject(2, row.getItemProperty("ID").getValue()); + stmt.executeUpdate(); + stmt.close(); + conn.commit(); + connectionPool.releaseConnection(conn); + + container.commit(); + } + + @Test + public void removeRow_versionSetAndEqualToDBValue_shouldSucceed() + throws SQLException { + DataGenerator.addVersionedData(connectionPool); + + TableQuery tQuery = new TableQuery("versioned", connectionPool, + SQLTestsConstants.sqlGen); + tQuery.setVersionColumn("VERSION"); + SQLContainer container = new SQLContainer(tQuery); + RowItem row = (RowItem) container.getItem(container.firstItemId()); + Assert.assertEquals("Junk", row.getItemProperty("TEXT").getValue()); + + container.removeItem(container.firstItemId()); + container.commit(); + + Connection conn = connectionPool.reserveConnection(); + PreparedStatement stmt = conn + .prepareStatement("SELECT * FROM VERSIONED WHERE \"TEXT\" = ?"); + stmt.setString(1, "Junk"); + ResultSet rs = stmt.executeQuery(); + Assert.assertFalse(rs.next()); + rs.close(); + stmt.close(); + conn.commit(); + connectionPool.releaseConnection(conn); + } + + @Test(expected = OptimisticLockException.class) + public void removeRow_versionSetAndLessThanDBValue_shouldThrowException() + throws SQLException { + if (SQLTestsConstants.db == SQLTestsConstants.DB.HSQLDB) { + // HSQLDB doesn't support versioning, so this is to make the test + // green. + throw new OptimisticLockException(null); + } + DataGenerator.addVersionedData(connectionPool); + + TableQuery tQuery = new TableQuery("versioned", connectionPool, + SQLTestsConstants.sqlGen); + tQuery.setVersionColumn("VERSION"); + SQLContainer container = new SQLContainer(tQuery); + RowItem row = (RowItem) container.getItem(container.firstItemId()); + Assert.assertEquals("Junk", row.getItemProperty("TEXT").getValue()); + + // Update the version using another connection. + Connection conn = connectionPool.reserveConnection(); + PreparedStatement stmt = conn.prepareStatement( + "UPDATE VERSIONED SET \"TEXT\" = ? WHERE \"ID\" = ?"); + stmt.setString(1, "asdf"); + stmt.setObject(2, row.getItemProperty("ID").getValue()); + stmt.executeUpdate(); + stmt.close(); + conn.commit(); + connectionPool.releaseConnection(conn); + + container.removeItem(container.firstItemId()); + container.commit(); + } + + @Test + public void removeRow_throwsOptimisticLockException_shouldStillWork() + throws SQLException { + if (SQLTestsConstants.db == SQLTestsConstants.DB.HSQLDB) { + // HSQLDB doesn't support versioning, so this is to make the test + // green. + return; + } + DataGenerator.addVersionedData(connectionPool); + + TableQuery tQuery = new TableQuery("versioned", connectionPool, + SQLTestsConstants.sqlGen); + tQuery.setVersionColumn("VERSION"); + SQLContainer container = new SQLContainer(tQuery); + RowItem row = (RowItem) container.getItem(container.firstItemId()); + Assert.assertEquals("Junk", row.getItemProperty("TEXT").getValue()); + + // Update the version using another connection. + Connection conn = connectionPool.reserveConnection(); + PreparedStatement stmt = conn.prepareStatement( + "UPDATE VERSIONED SET \"TEXT\" = ? WHERE \"ID\" = ?"); + stmt.setString(1, "asdf"); + stmt.setObject(2, row.getItemProperty("ID").getValue()); + stmt.executeUpdate(); + stmt.close(); + conn.commit(); + connectionPool.releaseConnection(conn); + + Object itemToRemove = container.firstItemId(); + try { + container.removeItem(itemToRemove); + container.commit(); + } catch (OptimisticLockException e) { + // This is expected, refresh and try again. + container.rollback(); + container.removeItem(itemToRemove); + container.commit(); + } + Object id = container.addItem(); + RowItem item = (RowItem) container.getItem(id); + item.getItemProperty("TEXT").setValue("foo"); + container.commit(); + } + + @Test + public void construction_explicitSchema_shouldSucceed() + throws SQLException { + if (SQLTestsConstants.createSchema == null + || SQLTestsConstants.createProductTable == null + || SQLTestsConstants.dropSchema == null) { + // only perform the test on the databases for which the setup and + // cleanup statements are available + return; + } + + // create schema "oaas" and table "product" in it + Connection conn = connectionPool.reserveConnection(); + Statement statement = conn.createStatement(); + try { + statement.execute(SQLTestsConstants.dropSchema); + } catch (SQLException e) { + // May fail if schema doesn't exist, which is OK. + conn.rollback(); + } + statement.execute(SQLTestsConstants.createSchema); + statement.execute(SQLTestsConstants.createProductTable); + conn.commit(); + + try { + // metadata scanning at query creation time should not fail + TableQuery tq1 = new TableQuery(null, "oaas", "product", + connectionPool, SQLTestsConstants.sqlGen); + Assert.assertNotNull(tq1); + } finally { + // cleanup - might not be an in-memory DB + statement.execute(SQLTestsConstants.dropSchema); + } + + // Cleanup to make test connection pool happy + connectionPool.releaseConnection(conn); + } + + @Test + public void construction_explicitCatalogAndSchema_shouldSucceed() + throws SQLException { + // not all databases support explicit catalogs, test with PostgreSQL + // using database name as catalog + if (SQLTestsConstants.db != SQLTestsConstants.DB.POSTGRESQL + || SQLTestsConstants.createSchema == null + || SQLTestsConstants.createProductTable == null + || SQLTestsConstants.dropSchema == null) { + // only perform the test on the databases for which the setup and + // cleanup statements are available + return; + } + + // create schema "oaas" and table "product" in it + Connection conn = connectionPool.reserveConnection(); + Statement statement = conn.createStatement(); + try { + statement.execute(SQLTestsConstants.dropSchema); + } catch (SQLException e) { + // May fail if schema doesn't exist, which is OK. + conn.rollback(); + } + statement.execute(SQLTestsConstants.createSchema); + statement.execute(SQLTestsConstants.createProductTable); + conn.commit(); + + try { + // metadata scanning at query creation time should not fail + // note that for most DBMS, catalog is just an optional database + // name + TableQuery tq1 = new TableQuery("sqlcontainer", "oaas", "product", + connectionPool, SQLTestsConstants.sqlGen); + Assert.assertNotNull(tq1); + } finally { + // cleanup - might not be an in-memory DB + statement.execute(SQLTestsConstants.dropSchema); + } + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/query/ValidatingSimpleJDBCConnectionPool.java b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/query/ValidatingSimpleJDBCConnectionPool.java new file mode 100644 index 0000000000..8a6ee0aa45 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/data/util/sqlcontainer/query/ValidatingSimpleJDBCConnectionPool.java @@ -0,0 +1,88 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.data.util.sqlcontainer.query; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.HashSet; +import java.util.Set; +import java.util.logging.Logger; + +import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool; +import com.vaadin.data.util.sqlcontainer.connection.SimpleJDBCConnectionPool; + +/** + * Connection pool for testing SQLContainer. Ensures that only reserved + * connections are released and that all connections are released before the + * pool is destroyed. + * + * @author Vaadin Ltd + */ +public class ValidatingSimpleJDBCConnectionPool implements JDBCConnectionPool { + + private JDBCConnectionPool realPool; + private Set<Connection> reserved = new HashSet<Connection>(); + private Set<Connection> alreadyReleased = new HashSet<Connection>(); + + public ValidatingSimpleJDBCConnectionPool(String driverName, + String connectionUri, String userName, String password, + int initialConnections, int maxConnections) throws SQLException { + realPool = new SimpleJDBCConnectionPool(driverName, connectionUri, + userName, password, initialConnections, maxConnections); + } + + @Deprecated + public JDBCConnectionPool getRealPool() { + return realPool; + } + + @Override + public Connection reserveConnection() throws SQLException { + Connection c = realPool.reserveConnection(); + reserved.add(c); + return c; + } + + @Override + public void releaseConnection(Connection conn) { + if (conn != null && !reserved.remove(conn)) { + if (alreadyReleased.contains(conn)) { + getLogger().severe("Tried to release connection (" + conn + + ") which has already been released"); + } else { + throw new RuntimeException("Tried to release connection (" + + conn + ") not reserved using reserveConnection"); + } + } + realPool.releaseConnection(conn); + alreadyReleased.add(conn); + + } + + @Override + public void destroy() { + realPool.destroy(); + if (!reserved.isEmpty()) { + throw new RuntimeException( + reserved.size() + " connections never released"); + } + } + + private static Logger getLogger() { + return Logger + .getLogger(ValidatingSimpleJDBCConnectionPool.class.getName()); + } +}
\ No newline at end of file diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/component/abstractfield/LegacyAbstractFieldListenersTest.java b/compatibility-server/src/test/java/com/vaadin/tests/server/component/abstractfield/LegacyAbstractFieldListenersTest.java new file mode 100644 index 0000000000..5843bd901f --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/component/abstractfield/LegacyAbstractFieldListenersTest.java @@ -0,0 +1,27 @@ +package com.vaadin.tests.server.component.abstractfield; + +import org.junit.Test; + +import com.vaadin.data.Property.ReadOnlyStatusChangeEvent; +import com.vaadin.data.Property.ReadOnlyStatusChangeListener; +import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.tests.server.component.AbstractListenerMethodsTestBase; +import com.vaadin.ui.Table; + +public class LegacyAbstractFieldListenersTest + extends AbstractListenerMethodsTestBase { + + @Test + public void testReadOnlyStatusChangeListenerAddGetRemove() + throws Exception { + testListenerAddGetRemove(Table.class, ReadOnlyStatusChangeEvent.class, + ReadOnlyStatusChangeListener.class); + } + + @Test + public void testValueChangeListenerAddGetRemove() throws Exception { + testListenerAddGetRemove(Table.class, ValueChangeEvent.class, + ValueChangeListener.class); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/CacheUpdateExceptionCausesTest.java b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/CacheUpdateExceptionCausesTest.java new file mode 100644 index 0000000000..86bb34145f --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/CacheUpdateExceptionCausesTest.java @@ -0,0 +1,55 @@ +/* + * Copyright 2012 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.tests.server.component.table; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.ui.Table; +import com.vaadin.ui.Table.CacheUpdateException; + +public class CacheUpdateExceptionCausesTest { + @Test + public void testSingleCauseException() { + Table table = new Table(); + Throwable[] causes = new Throwable[] { + new RuntimeException("Broken in one way.") }; + + CacheUpdateException exception = new CacheUpdateException(table, + "Error during Table cache update.", causes); + + Assert.assertSame(causes[0], exception.getCause()); + Assert.assertEquals("Error during Table cache update.", + exception.getMessage()); + } + + @Test + public void testMultipleCauseException() { + Table table = new Table(); + Throwable[] causes = new Throwable[] { + new RuntimeException("Broken in the first way."), + new RuntimeException("Broken in the second way.") }; + + CacheUpdateException exception = new CacheUpdateException(table, + "Error during Table cache update.", causes); + + Assert.assertSame(causes[0], exception.getCause()); + Assert.assertEquals( + "Error during Table cache update. Additional causes not shown.", + exception.getMessage()); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/FooterTest.java b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/FooterTest.java new file mode 100644 index 0000000000..3df2b8fbcb --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/FooterTest.java @@ -0,0 +1,103 @@ +package com.vaadin.tests.server.component.table; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.vaadin.data.Container; +import com.vaadin.data.Item; +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.ui.Table; + +/** + * Test case for testing the footer API + * + */ +public class FooterTest { + + /** + * Tests if setting the footer visibility works properly + */ + @Test + public void testFooterVisibility() { + Table table = new Table("Test table", createContainer()); + + // The footer should by default be hidden + assertFalse(table.isFooterVisible()); + + // Set footer visibility to tru should be reflected in the + // isFooterVisible() method + table.setFooterVisible(true); + assertTrue(table.isFooterVisible()); + } + + /** + * Tests adding footers to the columns + */ + @Test + public void testAddingFooters() { + Table table = new Table("Test table", createContainer()); + + // Table should not contain any footers at initialization + assertNull(table.getColumnFooter("col1")); + assertNull(table.getColumnFooter("col2")); + assertNull(table.getColumnFooter("col3")); + + // Adding column footer + table.setColumnFooter("col1", "Footer1"); + assertEquals("Footer1", table.getColumnFooter("col1")); + + // Add another footer + table.setColumnFooter("col2", "Footer2"); + assertEquals("Footer2", table.getColumnFooter("col2")); + + // Add footer for a non-existing column + table.setColumnFooter("fail", "FooterFail"); + } + + /** + * Test removing footers + */ + @Test + public void testRemovingFooters() { + Table table = new Table("Test table", createContainer()); + table.setColumnFooter("col1", "Footer1"); + table.setColumnFooter("col2", "Footer2"); + + // Test removing footer + assertNotNull(table.getColumnFooter("col1")); + table.setColumnFooter("col1", null); + assertNull(table.getColumnFooter("col1")); + + // The other footer should still be there + assertNotNull(table.getColumnFooter("col2")); + + // Remove non-existing footer + table.setColumnFooter("fail", null); + } + + /** + * Creates a container with three properties "col1,col2,col3" with 100 items + * + * @return Returns the created table + */ + private static Container createContainer() { + IndexedContainer container = new IndexedContainer(); + container.addContainerProperty("col1", String.class, ""); + container.addContainerProperty("col2", String.class, ""); + container.addContainerProperty("col3", String.class, ""); + + for (int i = 0; i < 100; i++) { + Item item = container.addItem("item " + i); + item.getItemProperty("col1").setValue("first" + i); + item.getItemProperty("col2").setValue("middle" + i); + item.getItemProperty("col3").setValue("last" + i); + } + + return container; + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/MultipleSelectionTest.java b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/MultipleSelectionTest.java new file mode 100644 index 0000000000..b29357ea6a --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/MultipleSelectionTest.java @@ -0,0 +1,62 @@ +package com.vaadin.tests.server.component.table; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Set; + +import org.junit.Test; + +import com.vaadin.data.Container; +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.shared.ui.MultiSelectMode; +import com.vaadin.ui.Table; + +public class MultipleSelectionTest { + + /** + * Tests weather the multiple select mode is set when using Table.set + */ + @Test + @SuppressWarnings("unchecked") + public void testSetMultipleItems() { + Table table = new Table("", createTestContainer()); + + // Tests if multiple selection is set + table.setMultiSelect(true); + assertTrue(table.isMultiSelect()); + + // Test multiselect by setting several items at once + + table.setValue(Arrays.asList("1", new String[] { "3" })); + assertEquals(2, ((Set<String>) table.getValue()).size()); + } + + /** + * Tests setting the multiselect mode of the Table. The multiselect mode + * affects how mouse selection is made in the table by the user. + */ + @Test + public void testSetMultiSelectMode() { + Table table = new Table("", createTestContainer()); + + // Default multiselect mode should be MultiSelectMode.DEFAULT + assertEquals(MultiSelectMode.DEFAULT, table.getMultiSelectMode()); + + // Tests if multiselectmode is set + table.setMultiSelectMode(MultiSelectMode.SIMPLE); + assertEquals(MultiSelectMode.SIMPLE, table.getMultiSelectMode()); + } + + /** + * Creates a testing container for the tests + * + * @return A new container with test items + */ + private Container createTestContainer() { + IndexedContainer container = new IndexedContainer( + Arrays.asList("1", new String[] { "2", "3", "4" })); + return container; + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableColumnAlignmentsTest.java b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableColumnAlignmentsTest.java new file mode 100644 index 0000000000..ff4c8336fb --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableColumnAlignmentsTest.java @@ -0,0 +1,143 @@ +package com.vaadin.tests.server.component.table; + +import static org.junit.Assert.assertArrayEquals; + +import org.junit.Test; + +import com.vaadin.ui.Table; +import com.vaadin.ui.Table.Align; + +public class TableColumnAlignmentsTest { + + @Test + public void defaultColumnAlignments() { + for (int properties = 0; properties < 10; properties++) { + Table t = TableGeneratorTest + .createTableWithDefaultContainer(properties, 10); + Object[] expected = new Object[properties]; + for (int i = 0; i < properties; i++) { + expected[i] = Align.LEFT; + } + org.junit.Assert.assertArrayEquals("getColumnAlignments", expected, + t.getColumnAlignments()); + } + } + + @Test + public void explicitColumnAlignments() { + int properties = 5; + Table t = TableGeneratorTest.createTableWithDefaultContainer(properties, + 10); + Align[] explicitAlignments = new Align[] { Align.CENTER, Align.LEFT, + Align.RIGHT, Align.RIGHT, Align.LEFT }; + + t.setColumnAlignments(explicitAlignments); + + assertArrayEquals("Explicit visible columns, 5 properties", + explicitAlignments, t.getColumnAlignments()); + } + + @Test + public void invalidColumnAlignmentStrings() { + Table t = TableGeneratorTest.createTableWithDefaultContainer(3, 7); + Align[] defaultAlignments = new Align[] { Align.LEFT, Align.LEFT, + Align.LEFT }; + try { + t.setColumnAlignments(new Align[] { Align.RIGHT, Align.RIGHT }); + junit.framework.Assert + .fail("No exception thrown for invalid array length"); + } catch (IllegalArgumentException e) { + // Ok, expected + } + + assertArrayEquals("Invalid change affected alignments", + defaultAlignments, t.getColumnAlignments()); + + } + + @Test + public void columnAlignmentForPropertyNotInContainer() { + Table t = TableGeneratorTest.createTableWithDefaultContainer(3, 7); + Align[] defaultAlignments = new Align[] { Align.LEFT, Align.LEFT, + Align.LEFT }; + try { + t.setColumnAlignment("Property 1200", Align.LEFT); + // FIXME: Uncomment as there should be an exception (#6475) + // junit.framework.Assert + // .fail("No exception thrown for property not in container"); + } catch (IllegalArgumentException e) { + // Ok, expected + } + + assertArrayEquals("Invalid change affected alignments", + defaultAlignments, t.getColumnAlignments()); + + // FIXME: Uncomment as null should be returned (#6474) + // junit.framework.Assert.assertEquals( + // "Column alignment for property not in container returned", + // null, t.getColumnAlignment("Property 1200")); + + } + + @Test + public void invalidColumnAlignmentsLength() { + Table t = TableGeneratorTest.createTableWithDefaultContainer(7, 7); + Align[] defaultAlignments = new Align[] { Align.LEFT, Align.LEFT, + Align.LEFT, Align.LEFT, Align.LEFT, Align.LEFT, Align.LEFT }; + + try { + t.setColumnAlignments(new Align[] { Align.LEFT }); + junit.framework.Assert + .fail("No exception thrown for invalid array length"); + } catch (IllegalArgumentException e) { + // Ok, expected + } + assertArrayEquals("Invalid change affected alignments", + defaultAlignments, t.getColumnAlignments()); + + try { + t.setColumnAlignments(new Align[] {}); + junit.framework.Assert + .fail("No exception thrown for invalid array length"); + } catch (IllegalArgumentException e) { + // Ok, expected + } + assertArrayEquals("Invalid change affected alignments", + defaultAlignments, t.getColumnAlignments()); + + try { + t.setColumnAlignments(new Align[] { Align.LEFT, Align.LEFT, + Align.LEFT, Align.LEFT, Align.LEFT, Align.LEFT, Align.LEFT, + Align.LEFT }); + junit.framework.Assert + .fail("No exception thrown for invalid array length"); + } catch (IllegalArgumentException e) { + // Ok, expected + } + assertArrayEquals("Invalid change affected alignments", + defaultAlignments, t.getColumnAlignments()); + + } + + @Test + public void explicitColumnAlignmentOneByOne() { + int properties = 5; + Table t = TableGeneratorTest.createTableWithDefaultContainer(properties, + 10); + Align[] explicitAlignments = new Align[] { Align.CENTER, Align.LEFT, + Align.RIGHT, Align.RIGHT, Align.LEFT }; + + Align[] currentAlignments = new Align[] { Align.LEFT, Align.LEFT, + Align.LEFT, Align.LEFT, Align.LEFT }; + + for (int i = 0; i < properties; i++) { + t.setColumnAlignment("Property " + i, explicitAlignments[i]); + currentAlignments[i] = explicitAlignments[i]; + + assertArrayEquals( + "Explicit visible columns, " + i + " alignments set", + currentAlignments, t.getColumnAlignments()); + } + + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableContextClickTest.java b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableContextClickTest.java new file mode 100644 index 0000000000..3ee8b76d76 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableContextClickTest.java @@ -0,0 +1,57 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.server.component.table; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.event.ContextClickEvent; +import com.vaadin.event.ContextClickEvent.ContextClickListener; +import com.vaadin.shared.ui.table.TableConstants.Section; +import com.vaadin.ui.Table; + +public class TableContextClickTest extends Table { + + private String error = null; + private boolean handled = false; + + @Test + public void testContextClickListenerWithTableEvent() { + addContextClickListener(new ContextClickListener() { + + @Override + public void contextClick(ContextClickEvent event) { + if (!(event instanceof TableContextClickEvent)) { + return; + } + + TableContextClickEvent e = (TableContextClickEvent) event; + if (e.getSection() != Section.BODY) { + error = "Event section was not BODY."; + } + handled = true; + } + }); + fireEvent(new TableContextClickEvent(this, null, null, null, + Section.BODY)); + + if (error != null) { + Assert.fail(error); + } else if (!handled) { + Assert.fail("Event was not handled by the ContextClickListener"); + } + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableDeclarativeTest.java b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableDeclarativeTest.java new file mode 100644 index 0000000000..f3b9b1cece --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableDeclarativeTest.java @@ -0,0 +1,180 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.server.component.table; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.server.ExternalResource; +import com.vaadin.shared.ui.MultiSelectMode; +import com.vaadin.ui.Table; +import com.vaadin.ui.Table.Align; +import com.vaadin.ui.Table.ColumnHeaderMode; +import com.vaadin.ui.Table.RowHeaderMode; +import com.vaadin.ui.Table.TableDragMode; +import com.vaadin.ui.declarative.Design; + +/** + * Test declarative support for {@link Table}. + * + * @since + * @author Vaadin Ltd + */ +public class TableDeclarativeTest extends TableDeclarativeTestBase { + + @Test + public void testBasicAttributes() { + + String design = "<" + getTag() + + " page-length=30 cache-rate=3 selectable editable " + + "sortable=false sort-ascending=false sort-container-property-id=foo " + + "drag-mode=row multi-select-mode=simple column-header-mode=id row-header-mode=id " + + "column-reordering-allowed column-collapsing-allowed />"; + + Table table = getTable(); + table.setPageLength(30); + table.setCacheRate(3); + table.setSelectable(true); + table.setEditable(true); + + table.setSortEnabled(false); + table.setSortAscending(false); + table.setSortContainerPropertyId("foo"); + + table.setDragMode(TableDragMode.ROW); + table.setMultiSelectMode(MultiSelectMode.SIMPLE); + table.setColumnHeaderMode(ColumnHeaderMode.ID); + table.setRowHeaderMode(RowHeaderMode.ID); + + table.setColumnReorderingAllowed(true); + table.setColumnCollapsingAllowed(true); + + testRead(design, table); + testWrite(design, table); + } + + @Test + public void testColumns() { + String design = "<" + getTag() + " column-collapsing-allowed>" // + + " <table>" // + + " <colgroup>" + " <col property-id='foo' width=300>" + + " <col property-id='bar' center expand=1 collapsible=false>" + + " <col property-id='baz' right expand=2 collapsed>" + + " </colgroup>" // + + " </table>"; + + Table table = getTable(); + table.setColumnCollapsingAllowed(true); + + table.addContainerProperty("foo", String.class, null); + table.setColumnAlignment("foo", Align.LEFT); + table.setColumnWidth("foo", 300); + + table.addContainerProperty("bar", String.class, null); + table.setColumnAlignment("bar", Align.CENTER); + table.setColumnExpandRatio("bar", 1); + table.setColumnCollapsible("bar", false); + + table.addContainerProperty("baz", String.class, null); + table.setColumnAlignment("baz", Align.RIGHT); + table.setColumnExpandRatio("baz", 2); + table.setColumnCollapsed("baz", true); + + testRead(design, table); + testWrite(design, table); + } + + @Test + public void testHeadersFooters() { + String design = "<" + getTag() + ">" // + + " <table>" // + + " <colgroup><col property-id=foo><col property-id=bar></colgroup>" // + + " <thead>" // + + " <tr><th icon='http://example.com/icon.png'>FOO<th>BAR" // + + " </thead>" // + + " <tfoot>" // + + " <tr><td>foo<td>bar" // + + " </tfoot>" // + + " </table>"; + + Table table = getTable(); + table.setFooterVisible(true); + + table.addContainerProperty("foo", String.class, null); + table.setColumnHeader("foo", "FOO"); + table.setColumnIcon("foo", + new ExternalResource("http://example.com/icon.png")); + table.setColumnFooter("foo", "foo"); + + table.addContainerProperty("bar", String.class, null); + table.setColumnHeader("bar", "BAR"); + table.setColumnFooter("bar", "bar"); + + testRead(design, table); + testWrite(design, table); + } + + @Test + public void testInlineData() { + String design = "<" + getTag() + ">" // + + " <table>" // + + " <colgroup>" + " <col property-id='foo' />" + + " <col property-id='bar' />" + + " <col property-id='baz' />" // + + " </colgroup>" + " <thead>" + + " <tr><th>Description<th>Milestone<th>Status</tr>" + + " </thead>" + " <tbody>" + + " <tr item-id=1><td>r1c1</td><td>r1c2</td><td>r1c3</td>" // + + " <tr item-id=2><td>r2c1</td><td>r2c2</td><td>r2c3</td>" // + + " </tbody>" // + + " <tfoot>" // + + " <tr><td>F1<td>F2<td>F3</tr>" // + + " </tfoot>" // + + " </table>"; + + Table table = getTable(); + table.addContainerProperty("foo", String.class, null); + table.addContainerProperty("bar", String.class, null); + table.addContainerProperty("baz", String.class, null); + table.setColumnHeaders("Description", "Milestone", "Status"); + table.setColumnFooter("foo", "F1"); + table.setColumnFooter("bar", "F2"); + table.setColumnFooter("baz", "F3"); + table.addItem(new Object[] { "r1c1", "r1c2", "r1c3" }, "1"); + table.addItem(new Object[] { "r2c1", "r2c2", "r2c3" }, "2"); + table.setFooterVisible(true); + + testRead(design, table); + testWrite(design, table, true); + } + + @Test + public void testHtmlEntities() { + String design = "<v-table>" + "<table>" + " <colgroup>" + + " <col property-id=\"test\"" + " </colgroup>" + + " <thead>" + " <tr><th>& Test</th></tr>" + + " </thead>" + " <tbody>" + + " <tr item-id=\"test\"><td>& Test</tr>" + " </tbody>" + + " <tfoot>" + " <tr><td>& Test</td></tr>" + + " </tfoot>" + "</table>" + "</v-table>"; + Table read = read(design); + + Assert.assertEquals("& Test", + read.getContainerProperty("test", "test").getValue()); + Assert.assertEquals("& Test", read.getColumnHeader("test")); + Assert.assertEquals("& Test", read.getColumnFooter("test")); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableDeclarativeTestBase.java b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableDeclarativeTestBase.java new file mode 100644 index 0000000000..7a7b13e933 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableDeclarativeTestBase.java @@ -0,0 +1,74 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.server.component.table; + +import static org.junit.Assert.assertTrue; + +import com.vaadin.tests.design.DeclarativeTestBase; +import com.vaadin.ui.Table; + +public abstract class TableDeclarativeTestBase + extends DeclarativeTestBase<Table> { + + @Override + public Table testRead(String design, Table expected) { + Table read = super.testRead(design, expected); + compareColumns(read, expected); + compareBody(read, expected); + return read; + } + + protected Table getTable() { + return new Table(); + } + + protected String getTag() { + return "vaadin-table"; + } + + protected void compareBody(Table read, Table expected) { + assertEquals("number of items", expected.getItemIds().size(), + read.getItemIds().size()); + for (Object rowId : expected.getItemIds()) { + assertTrue(read.containsId(rowId)); + for (Object propertyId : read.getVisibleColumns()) { + Object expectedItem = expected.getContainerProperty(rowId, + propertyId); + Object readItem = read.getContainerProperty(rowId, propertyId); + assertEquals("property '" + propertyId + "'", expectedItem, + readItem); + } + } + } + + protected void compareColumns(Table read, Table expected) { + for (Object pid : expected.getVisibleColumns()) { + String col = "column '" + pid + "'"; + assertEquals(col + " width", expected.getColumnWidth(pid), + read.getColumnWidth(pid)); + assertEquals(col + " expand ratio", + expected.getColumnExpandRatio(pid), + read.getColumnExpandRatio(pid)); + assertEquals(col + " collapsible", + expected.isColumnCollapsible(pid), + read.isColumnCollapsible(pid)); + assertEquals(col + " collapsed", expected.isColumnCollapsed(pid), + read.isColumnCollapsed(pid)); + assertEquals(col + " footer", expected.getColumnFooter(pid), + read.getColumnFooter(pid)); + } + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableGeneratorTest.java b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableGeneratorTest.java new file mode 100644 index 0000000000..6fbe5557f8 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableGeneratorTest.java @@ -0,0 +1,42 @@ +package com.vaadin.tests.server.component.table; + +import org.junit.Test; + +import com.vaadin.data.Item; +import com.vaadin.ui.Table; + +public class TableGeneratorTest { + public static Table createTableWithDefaultContainer(int properties, + int items) { + Table t = new Table(); + + for (int i = 0; i < properties; i++) { + t.addContainerProperty("Property " + i, String.class, null); + } + + for (int j = 0; j < items; j++) { + Item item = t.addItem("Item " + j); + for (int i = 0; i < properties; i++) { + item.getItemProperty("Property " + i) + .setValue("Item " + j + "/Property " + i); + } + } + + return t; + } + + @Test + public void testTableGenerator() { + Table t = createTableWithDefaultContainer(1, 1); + junit.framework.Assert.assertEquals(t.size(), 1); + junit.framework.Assert.assertEquals(t.getContainerPropertyIds().size(), + 1); + + t = createTableWithDefaultContainer(100, 50); + junit.framework.Assert.assertEquals(t.size(), 50); + junit.framework.Assert.assertEquals(t.getContainerPropertyIds().size(), + 100); + + } + +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableListenersTest.java b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableListenersTest.java new file mode 100644 index 0000000000..ac6fb171e3 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableListenersTest.java @@ -0,0 +1,49 @@ +package com.vaadin.tests.server.component.table; + +import org.junit.Test; + +import com.vaadin.event.ItemClickEvent; +import com.vaadin.event.ItemClickEvent.ItemClickListener; +import com.vaadin.tests.server.component.AbstractListenerMethodsTestBase; +import com.vaadin.ui.Table; +import com.vaadin.ui.Table.ColumnReorderEvent; +import com.vaadin.ui.Table.ColumnReorderListener; +import com.vaadin.ui.Table.ColumnResizeEvent; +import com.vaadin.ui.Table.ColumnResizeListener; +import com.vaadin.ui.Table.FooterClickEvent; +import com.vaadin.ui.Table.FooterClickListener; +import com.vaadin.ui.Table.HeaderClickEvent; +import com.vaadin.ui.Table.HeaderClickListener; + +public class TableListenersTest extends AbstractListenerMethodsTestBase { + + @Test + public void testColumnResizeListenerAddGetRemove() throws Exception { + testListenerAddGetRemove(Table.class, ColumnResizeEvent.class, + ColumnResizeListener.class); + } + + @Test + public void testItemClickListenerAddGetRemove() throws Exception { + testListenerAddGetRemove(Table.class, ItemClickEvent.class, + ItemClickListener.class); + } + + @Test + public void testFooterClickListenerAddGetRemove() throws Exception { + testListenerAddGetRemove(Table.class, FooterClickEvent.class, + FooterClickListener.class); + } + + @Test + public void testHeaderClickListenerAddGetRemove() throws Exception { + testListenerAddGetRemove(Table.class, HeaderClickEvent.class, + HeaderClickListener.class); + } + + @Test + public void testColumnReorderListenerAddGetRemove() throws Exception { + testListenerAddGetRemove(Table.class, ColumnReorderEvent.class, + ColumnReorderListener.class); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TablePropertyValueConverterTest.java b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TablePropertyValueConverterTest.java new file mode 100644 index 0000000000..5a9297014c --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TablePropertyValueConverterTest.java @@ -0,0 +1,384 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.server.component.table; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.lang.reflect.Field; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Locale; +import java.util.Map.Entry; +import java.util.Set; + +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.data.Container; +import com.vaadin.data.Item; +import com.vaadin.data.Property; +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.ui.Table; +import com.vaadin.v7.data.util.converter.LegacyConverter; + +public class TablePropertyValueConverterTest { + protected TestableTable table; + protected Collection<?> initialProperties; + + @Test + public void testRemovePropertyId() { + Collection<Object> converters = table.getCurrentConverters(); + assertTrue("Set of converters was empty at the start.", + converters.size() > 0); + + Object firstId = converters.iterator().next(); + + table.removeContainerProperty(firstId); + + Collection<Object> converters2 = table.getCurrentConverters(); + assertTrue("FirstId was not removed", !converters2.contains(firstId)); + + assertTrue("The number of removed converters was not one.", + converters.size() - converters2.size() == 1); + + for (Object originalId : converters) { + if (!originalId.equals(firstId)) { + assertTrue("The wrong converter was removed.", + converters2.contains(originalId)); + } + } + + } + + @Test + public void testSetContainer() { + table.setContainerDataSource(createContainer( + new String[] { "col1", "col3", "col4", "col5" })); + Collection<Object> converters = table.getCurrentConverters(); + assertTrue("There should only have been one converter left.", + converters.size() == 1); + Object onlyKey = converters.iterator().next(); + assertTrue("The incorrect key was left.", onlyKey.equals("col1")); + + } + + @Test + public void testSetContainerWithInexactButCompatibleTypes() { + TestableTable customTable = new TestableTable("Test table", + createContainer(new String[] { "col1", "col2", "col3" }, + new Class[] { String.class, BaseClass.class, + DerivedClass.class })); + customTable.setConverter("col1", new LegacyConverter<String, String>() { + private static final long serialVersionUID = 1L; + + @Override + public String convertToModel(String value, + Class<? extends String> targetType, Locale locale) + throws com.vaadin.v7.data.util.converter.LegacyConverter.ConversionException { + return "model"; + } + + @Override + public String convertToPresentation(String value, + Class<? extends String> targetType, Locale locale) + throws com.vaadin.v7.data.util.converter.LegacyConverter.ConversionException { + return "presentation"; + } + + @Override + public Class<String> getModelType() { + return String.class; + } + + @Override + public Class<String> getPresentationType() { + return String.class; + } + + }); + customTable.setConverter("col2", + new LegacyConverter<String, BaseClass>() { + private static final long serialVersionUID = 1L; + + @Override + public BaseClass convertToModel(String value, + Class<? extends BaseClass> targetType, + Locale locale) + throws com.vaadin.v7.data.util.converter.LegacyConverter.ConversionException { + return new BaseClass("model"); + } + + @Override + public Class<BaseClass> getModelType() { + return BaseClass.class; + } + + @Override + public Class<String> getPresentationType() { + return String.class; + } + + @Override + public String convertToPresentation(BaseClass value, + Class<? extends String> targetType, Locale locale) + throws com.vaadin.v7.data.util.converter.LegacyConverter.ConversionException { + return null; + } + }); + customTable.setConverter("col3", + new LegacyConverter<String, DerivedClass>() { + private static final long serialVersionUID = 1L; + + @Override + public DerivedClass convertToModel(String value, + Class<? extends DerivedClass> targetType, + Locale locale) + throws com.vaadin.v7.data.util.converter.LegacyConverter.ConversionException { + return new DerivedClass("derived" + 1001); + } + + @Override + public Class<DerivedClass> getModelType() { + return DerivedClass.class; + } + + @Override + public Class<String> getPresentationType() { + return String.class; + } + + @Override + public String convertToPresentation(DerivedClass value, + Class<? extends String> targetType, Locale locale) + throws com.vaadin.v7.data.util.converter.LegacyConverter.ConversionException { + return null; + } + }); + customTable.setContainerDataSource( + createContainer(new String[] { "col1", "col2", "col3" }, + new Class[] { DerivedClass.class, DerivedClass.class, + BaseClass.class })); + Set<Object> converters = customTable.getCurrentConverters(); + // TODO Test temporarily disabled as this feature + // is not yet implemented in Table + /* + * assertTrue("Incompatible types were not removed.", converters.size() + * <= 1); assertTrue("Even compatible types were removed", + * converters.size() == 1); assertTrue("Compatible type was missing.", + * converters.contains("col2")); + */ + } + + @Test + public void testPrimitiveTypeConverters() { + TestableTable customTable = new TestableTable("Test table", + createContainer(new String[] { "col1", "col2", "col3" }, + new Class[] { int.class, BaseClass.class, + DerivedClass.class })); + customTable.setConverter("col1", + new LegacyConverter<String, Integer>() { + private static final long serialVersionUID = 1L; + + @Override + public Integer convertToModel(String value, + Class<? extends Integer> targetType, Locale locale) + throws com.vaadin.v7.data.util.converter.LegacyConverter.ConversionException { + return 11; + } + + @Override + public String convertToPresentation(Integer value, + Class<? extends String> targetType, Locale locale) + throws com.vaadin.v7.data.util.converter.LegacyConverter.ConversionException { + return "presentation"; + } + + @Override + public Class<Integer> getModelType() { + return Integer.class; + } + + @Override + public Class<String> getPresentationType() { + return String.class; + } + }); + Set<Object> converters = customTable.getCurrentConverters(); + assertTrue("Converter was not set.", converters.size() > 0); + } + + @Test + public void testInheritance() { + assertTrue("BaseClass isn't assignable from DerivedClass", + BaseClass.class.isAssignableFrom(DerivedClass.class)); + assertFalse("DerivedClass is assignable from BaseClass", + DerivedClass.class.isAssignableFrom(BaseClass.class)); + } + + @Before + public void setUp() { + table = new TestableTable("Test table", + createContainer(new String[] { "col1", "col2", "col3" })); + table.setConverter("col1", new LegacyConverter<String, String>() { + private static final long serialVersionUID = 1L; + + @Override + public String convertToModel(String value, + Class<? extends String> targetType, Locale locale) + throws com.vaadin.v7.data.util.converter.LegacyConverter.ConversionException { + return "model"; + } + + @Override + public String convertToPresentation(String value, + Class<? extends String> targetType, Locale locale) + throws com.vaadin.v7.data.util.converter.LegacyConverter.ConversionException { + return "presentation"; + } + + @Override + public Class<String> getModelType() { + return String.class; + } + + @Override + public Class<String> getPresentationType() { + return String.class; + } + + }); + + table.setConverter("col2", new LegacyConverter<String, String>() { + private static final long serialVersionUID = 1L; + + @Override + public String convertToModel(String value, + Class<? extends String> targetType, Locale locale) + throws com.vaadin.v7.data.util.converter.LegacyConverter.ConversionException { + return "model2"; + } + + @Override + public String convertToPresentation(String value, + Class<? extends String> targetType, Locale locale) + throws com.vaadin.v7.data.util.converter.LegacyConverter.ConversionException { + return "presentation2"; + } + + @Override + public Class<String> getModelType() { + return String.class; + } + + @Override + public Class<String> getPresentationType() { + return String.class; + } + + }); + + initialProperties = table.getContainerPropertyIds(); + } + + private static Container createContainer(Object[] ids) { + Class[] types = new Class[ids.length]; + for (int i = 0; i < types.length; ++i) { + types[i] = String.class; + } + return createContainer(ids, types); + } + + private static Container createContainer(Object[] ids, Class[] types) { + IndexedContainer container = new IndexedContainer(); + if (ids.length > types.length) { + throw new IllegalArgumentException("Too few defined types"); + } + for (int i = 0; i < ids.length; ++i) { + container.addContainerProperty(ids[i], types[i], ""); + } + + for (int i = 0; i < 100; i++) { + Item item = container.addItem("item " + i); + for (int j = 0; j < ids.length; ++j) { + Property itemProperty = item.getItemProperty(ids[j]); + if (types[j] == String.class) { + itemProperty.setValue(ids[j].toString() + i); + } else if (types[j] == BaseClass.class) { + itemProperty.setValue(new BaseClass("base" + i)); + } else if (types[j] == DerivedClass.class) { + itemProperty.setValue(new DerivedClass("derived" + i)); + } else if (types[j] == int.class) { + // FIXME can't set values because the int is autoboxed into + // an Integer and not unboxed prior to set + + // itemProperty.setValue(i); + } else { + throw new IllegalArgumentException( + "Unhandled type in createContainer: " + types[j]); + } + } + } + + return container; + } + + private class TestableTable extends Table { + /** + * @param string + * @param createContainer + */ + public TestableTable(String string, Container container) { + super(string, container); + } + + Set<Object> getCurrentConverters() { + try { + Field f = Table.class + .getDeclaredField("propertyValueConverters"); + f.setAccessible(true); + HashMap<Object, LegacyConverter<String, Object>> pvc = (HashMap<Object, LegacyConverter<String, Object>>) f + .get(this); + Set<Object> currentConverters = new HashSet<Object>(); + for (Entry<Object, LegacyConverter<String, Object>> entry : pvc + .entrySet()) { + currentConverters.add(entry.getKey()); + } + return currentConverters; + + } catch (Exception e) { + fail("Unable to retrieve propertyValueConverters"); + return null; + } + } + } + + private static class BaseClass { + private String title; + + public BaseClass(String title) { + this.title = title; + } + } + + private static class DerivedClass extends BaseClass { + public DerivedClass(String title) { + super(title); + } + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableSelectableTest.java b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableSelectableTest.java new file mode 100644 index 0000000000..906827958f --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableSelectableTest.java @@ -0,0 +1,75 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.server.component.table; + +import org.easymock.EasyMock; +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.ui.Table; + +/** + * Tests for 'selectable' property of {@link Table} class. + * + * @author Vaadin Ltd + */ +public class TableSelectableTest { + + @Test + public void setSelectable_explicitSelectable_tableIsSelectable() { + Table table = new Table(); + table.setSelectable(true); + + Assert.assertTrue(table.isSelectable()); + } + + @Test + public void addValueChangeListener_explicitSelectable_tableIsSelectable() { + TestTable table = new TestTable(); + table.addValueChangeListener( + EasyMock.createMock(ValueChangeListener.class)); + + Assert.assertTrue(table.isSelectable()); + Assert.assertTrue(table.markAsDirtyCalled); + } + + @Test + public void tableIsNotSelectableByDefult() { + Table table = new Table(); + + Assert.assertFalse(table.isSelectable()); + } + + @Test + public void setSelectable_explicitNotSelectable_tableIsNotSelectable() { + Table table = new Table(); + table.setSelectable(false); + table.addValueChangeListener( + EasyMock.createMock(ValueChangeListener.class)); + + Assert.assertFalse(table.isSelectable()); + } + + private static final class TestTable extends Table { + @Override + public void markAsDirty() { + markAsDirtyCalled = true; + } + + private boolean markAsDirtyCalled; + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableSerializationTest.java b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableSerializationTest.java new file mode 100644 index 0000000000..22f2381980 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableSerializationTest.java @@ -0,0 +1,26 @@ +package com.vaadin.tests.server.component.table; + +import org.apache.commons.lang.SerializationUtils; +import org.junit.Test; + +import com.vaadin.ui.Table; + +public class TableSerializationTest { + + @Test + public void testSerialization() { + Table t = new Table(); + byte[] ser = SerializationUtils.serialize(t); + Table t2 = (Table) SerializationUtils.deserialize(ser); + + } + + @Test + public void testSerializationWithRowHeaders() { + Table t = new Table(); + t.setRowHeaderMode(Table.ROW_HEADER_MODE_EXPLICIT); + t.setColumnWidth(null, 100); + byte[] ser = SerializationUtils.serialize(t); + Table t2 = (Table) SerializationUtils.deserialize(ser); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableStateTest.java b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableStateTest.java new file mode 100644 index 0000000000..43b03c41e8 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableStateTest.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.server.component.table; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.shared.ui.table.TableState; +import com.vaadin.ui.Table; + +/** + * Tests for Table State. + * + */ +public class TableStateTest { + + @Test + public void getState_tableHasCustomState() { + TestTable table = new TestTable(); + TableState state = table.getState(); + Assert.assertEquals("Unexpected state class", TableState.class, + state.getClass()); + } + + @Test + public void getPrimaryStyleName_tableHasCustomPrimaryStyleName() { + Table table = new Table(); + TableState state = new TableState(); + Assert.assertEquals("Unexpected primary style name", + state.primaryStyleName, table.getPrimaryStyleName()); + } + + @Test + public void tableStateHasCustomPrimaryStyleName() { + TableState state = new TableState(); + Assert.assertEquals("Unexpected primary style name", "v-table", + state.primaryStyleName); + } + + private static class TestTable extends Table { + + @Override + public TableState getState() { + return super.getState(); + } + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableVisibleColumnsTest.java b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableVisibleColumnsTest.java new file mode 100644 index 0000000000..f9f6e7f979 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/component/table/TableVisibleColumnsTest.java @@ -0,0 +1,72 @@ +package com.vaadin.tests.server.component.table; + +import static org.junit.Assert.assertArrayEquals; + +import org.junit.Test; + +import com.vaadin.ui.Table; + +public class TableVisibleColumnsTest { + + String[] defaultColumns3 = new String[] { "Property 0", "Property 1", + "Property 2" }; + + @Test + public void defaultVisibleColumns() { + for (int properties = 0; properties < 10; properties++) { + Table t = TableGeneratorTest + .createTableWithDefaultContainer(properties, 10); + Object[] expected = new Object[properties]; + for (int i = 0; i < properties; i++) { + expected[i] = "Property " + i; + } + org.junit.Assert.assertArrayEquals("getVisibleColumns", expected, + t.getVisibleColumns()); + } + } + + @Test + public void explicitVisibleColumns() { + Table t = TableGeneratorTest.createTableWithDefaultContainer(5, 10); + Object[] newVisibleColumns = new Object[] { "Property 1", + "Property 2" }; + t.setVisibleColumns(newVisibleColumns); + assertArrayEquals("Explicit visible columns, 5 properties", + newVisibleColumns, t.getVisibleColumns()); + + } + + @Test + public void invalidVisibleColumnIds() { + Table t = TableGeneratorTest.createTableWithDefaultContainer(3, 10); + + try { + t.setVisibleColumns( + new Object[] { "a", "Property 2", "Property 3" }); + junit.framework.Assert.fail("IllegalArgumentException expected"); + } catch (IllegalArgumentException e) { + // OK, expected + } + assertArrayEquals(defaultColumns3, t.getVisibleColumns()); + } + + @Test + public void duplicateVisibleColumnIds() { + Table t = TableGeneratorTest.createTableWithDefaultContainer(3, 10); + try { + t.setVisibleColumns(new Object[] { "Property 0", "Property 1", + "Property 2", "Property 1" }); + } catch (IllegalArgumentException e) { + // OK, expected + } + assertArrayEquals(defaultColumns3, t.getVisibleColumns()); + } + + @Test + public void noVisibleColumns() { + Table t = TableGeneratorTest.createTableWithDefaultContainer(3, 10); + t.setVisibleColumns(new Object[] {}); + assertArrayEquals(new Object[] {}, t.getVisibleColumns()); + + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/component/treetable/EmptyTreeTableTest.java b/compatibility-server/src/test/java/com/vaadin/tests/server/component/treetable/EmptyTreeTableTest.java new file mode 100644 index 0000000000..2a667bea72 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/component/treetable/EmptyTreeTableTest.java @@ -0,0 +1,17 @@ +package com.vaadin.tests.server.component.treetable; + +import static org.junit.Assert.assertFalse; + +import org.junit.Test; + +import com.vaadin.ui.TreeTable; + +public class EmptyTreeTableTest { + + @Test + public void testLastId() { + TreeTable treeTable = new TreeTable(); + + assertFalse(treeTable.isLastId(treeTable.getValue())); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableDeclarativeTest.java b/compatibility-server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableDeclarativeTest.java new file mode 100644 index 0000000000..eb25bcb0aa --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableDeclarativeTest.java @@ -0,0 +1,156 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.server.component.treetable; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.tests.server.component.table.TableDeclarativeTest; +import com.vaadin.ui.Table; +import com.vaadin.ui.TreeTable; +import com.vaadin.ui.declarative.DesignException; + +/** + * Test declarative support for {@link TreeTable}. + * + * @since + * @author Vaadin Ltd + */ +public class TreeTableDeclarativeTest extends TableDeclarativeTest { + + @Test + public void testAttributes() { + String design = "<vaadin-tree-table animations-enabled>"; + TreeTable table = getTable(); + table.setAnimationsEnabled(true); + + testRead(design, table); + testWrite(design, table); + } + + @Test + public void testHierarchy() { + String design = "<vaadin-tree-table>" // + + "<table>" // + + "<colgroup><col property-id=''></colgroup>" // + + "<tbody>" // + + " <tr item-id='1'><td></tr>" // + + " <tr depth=1 item-id='1.1'><td></tr>" // + + " <tr depth=1 item-id='1.2'><td></tr>" // + + " <tr depth=2 item-id='1.2.1'><td></tr>" // + + " <tr depth=3 item-id='1.2.1.1'><td></tr>" // + + " <tr depth=2 item-id='1.2.2'><td></tr>" // + + " <tr item-id='2'><td></tr>" // + + " <tr depth=1 item-id='2.1'><td></tr>" // + + "</tbody>" // + + "</table>" // + + "</vaadin-tree-table>"; + + TreeTable table = getTable(); + table.addContainerProperty("", String.class, ""); + + table.addItem("1"); + table.addItem("1.1"); + table.setParent("1.1", "1"); + table.addItem("1.2"); + table.setParent("1.2", "1"); + table.addItem("1.2.1"); + table.setParent("1.2.1", "1.2"); + table.addItem("1.2.1.1"); + table.setParent("1.2.1.1", "1.2.1"); + table.addItem("1.2.2"); + table.setParent("1.2.2", "1.2"); + table.addItem("2"); + table.addItem("2.1"); + table.setParent("2.1", "2"); + + testRead(design, table); + testWrite(design, table, true); + } + + @Test + public void testCollapsed() { + String design = "<vaadin-tree-table>" // + + " <table>" // + + " <colgroup><col property-id=''></colgroup>" // + + " <tbody>" // + + " <tr item-id='1' collapsed=false><td></tr>" // + + " <tr depth=1 item-id='1.1'><td></tr>" // + + " <tr depth=2 item-id='1.1.1'><td></tr>" // + + " </tbody>" // + + " </table>" // + + "</vaadin-tree-table>"; + + TreeTable table = getTable(); + table.addContainerProperty("", String.class, ""); + + table.addItem("1"); + table.setCollapsed("1", false); + table.addItem("1.1"); + table.setParent("1.1", "1"); + table.addItem("1.1.1"); + table.setParent("1.1.1", "1.1"); + + testRead(design, table); + testWrite(design, table, true); + } + + @Test + public void testMalformedHierarchy() { + assertMalformed("<tr depth=-4><td>"); + assertMalformed("<tr depth=1><td>"); + assertMalformed("<tr><td><tr depth=3><td>"); + } + + protected void assertMalformed(String hierarchy) { + String design = "<vaadin-tree-table>" // + + " <table>" // + + " <colgroup><col property-id=''></colgroup>" // + + " <tbody>" + hierarchy + "</tbody>" // + + " </table>" // + + "</vaadin-tree-table>"; + + try { + read(design); + Assert.fail("Malformed hierarchy should fail: " + hierarchy); + } catch (DesignException expected) { + } + } + + @Override + protected void compareBody(Table read, Table expected) { + super.compareBody(read, expected); + + for (Object itemId : read.getItemIds()) { + Assert.assertEquals("parent of item " + itemId, + ((TreeTable) expected).getParent(itemId), + ((TreeTable) read).getParent(itemId)); + Assert.assertEquals("collapsed status of item " + itemId, + ((TreeTable) expected).isCollapsed(itemId), + ((TreeTable) read).isCollapsed(itemId)); + } + } + + @Override + protected TreeTable getTable() { + return new TreeTable(); + } + + @Override + protected String getTag() { + return "vaadin-tree-table"; + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableSetContainerNullTest.java b/compatibility-server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableSetContainerNullTest.java new file mode 100644 index 0000000000..9718d24f8c --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableSetContainerNullTest.java @@ -0,0 +1,16 @@ +package com.vaadin.tests.server.component.treetable; + +import org.junit.Test; + +import com.vaadin.ui.TreeTable; + +public class TreeTableSetContainerNullTest { + + @Test + public void testNullContainer() { + TreeTable treeTable = new TreeTable(); + + // should not cause an exception + treeTable.setContainerDataSource(null); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableTest.java b/compatibility-server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableTest.java new file mode 100644 index 0000000000..4706ec1413 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableTest.java @@ -0,0 +1,102 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.server.component.treetable; + +import java.util.EnumSet; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.shared.ui.treetable.TreeTableState; +import com.vaadin.ui.Table.RowHeaderMode; +import com.vaadin.ui.TreeTable; + +/** + * Tests for {@link TreeTable} + * + * @author Vaadin Ltd + */ +public class TreeTableTest { + + @Test + public void rowHeadersAreEnabled_iconRowHeaderMode_rowHeadersAreDisabled() { + TestTreeTable tree = new TestTreeTable(); + tree.setRowHeaderMode(RowHeaderMode.ICON_ONLY); + + Assert.assertFalse("Row headers are enabled for Icon header mode", + tree.rowHeadersAreEnabled()); + } + + @Test + public void rowHeadersAreEnabled_hiddenRowHeaderMode_rowHeadersAreDisabled() { + TestTreeTable tree = new TestTreeTable(); + tree.setRowHeaderMode(RowHeaderMode.HIDDEN); + + Assert.assertFalse("Row headers are enabled for Hidden header mode", + tree.rowHeadersAreEnabled()); + } + + @Test + public void rowHeadersAreEnabled_otherRowHeaderModes_rowHeadersAreEnabled() { + TestTreeTable tree = new TestTreeTable(); + EnumSet<RowHeaderMode> modes = EnumSet.allOf(RowHeaderMode.class); + modes.remove(RowHeaderMode.ICON_ONLY); + modes.remove(RowHeaderMode.HIDDEN); + + for (RowHeaderMode mode : modes) { + tree.setRowHeaderMode(mode); + Assert.assertTrue( + "Row headers are disabled for " + mode + " header mode", + tree.rowHeadersAreEnabled()); + } + } + + @Test + public void getState_treeTableHasCustomState() { + TestTreeTable table = new TestTreeTable(); + TreeTableState state = table.getState(); + Assert.assertEquals("Unexpected state class", TreeTableState.class, + state.getClass()); + } + + @Test + public void getPrimaryStyleName_treeTableHasCustomPrimaryStyleName() { + TreeTable table = new TreeTable(); + TreeTableState state = new TreeTableState(); + Assert.assertEquals("Unexpected primary style name", + state.primaryStyleName, table.getPrimaryStyleName()); + } + + @Test + public void treeTableStateHasCustomPrimaryStyleName() { + TreeTableState state = new TreeTableState(); + Assert.assertEquals("Unexpected primary style name", "v-table", + state.primaryStyleName); + } + + private static class TestTreeTable extends TreeTable { + + @Override + protected boolean rowHeadersAreEnabled() { + return super.rowHeadersAreEnabled(); + } + + @Override + public TreeTableState getState() { + return super.getState(); + } + } +} |