summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorArtur Signell <artur@vaadin.com>2012-08-30 15:27:50 +0300
committerArtur Signell <artur@vaadin.com>2012-08-30 16:08:05 +0300
commit876182aaa34682503338a4dcdd119b3ebc256f97 (patch)
tree8e54b81cfcbecb5c54b725ca3a612b6e18e228cd /server
parent691220a5b24370d56f7c15d5a05c57a6c76dcb83 (diff)
downloadvaadin-framework-876182aaa34682503338a4dcdd119b3ebc256f97.tar.gz
vaadin-framework-876182aaa34682503338a4dcdd119b3ebc256f97.zip
Moved server tests from tests/server-side to server/tests/src (#9299)
Diffstat (limited to 'server')
-rw-r--r--server/tests/src/com/vaadin/data/util/AbstractBeanContainerTest.java81
-rw-r--r--server/tests/src/com/vaadin/data/util/AbstractContainerTest.java649
-rw-r--r--server/tests/src/com/vaadin/data/util/AbstractHierarchicalContainerTest.java256
-rw-r--r--server/tests/src/com/vaadin/data/util/AbstractInMemoryContainerTest.java6
-rw-r--r--server/tests/src/com/vaadin/data/util/BeanContainerTest.java460
-rw-r--r--server/tests/src/com/vaadin/data/util/BeanItemContainerSortTest.java170
-rw-r--r--server/tests/src/com/vaadin/data/util/BeanItemContainerTest.java718
-rw-r--r--server/tests/src/com/vaadin/data/util/BeanItemTest.java333
-rw-r--r--server/tests/src/com/vaadin/data/util/FileSystemContainerTest.java16
-rw-r--r--server/tests/src/com/vaadin/data/util/NestedMethodPropertyTest.java327
-rw-r--r--server/tests/src/com/vaadin/data/util/ObjectPropertyTest.java97
-rw-r--r--server/tests/src/com/vaadin/data/util/PerformanceTestIndexedContainer.java117
-rw-r--r--server/tests/src/com/vaadin/data/util/PropertyDescriptorTest.java55
-rw-r--r--server/tests/src/com/vaadin/data/util/PropertySetItemTest.java405
-rw-r--r--server/tests/src/com/vaadin/data/util/TestContainerHierarchicalWrapper.java42
-rw-r--r--server/tests/src/com/vaadin/data/util/TestContainerSorting.java224
-rw-r--r--server/tests/src/com/vaadin/data/util/TestHierarchicalContainer.java263
-rw-r--r--server/tests/src/com/vaadin/data/util/TestIndexedContainer.java271
-rw-r--r--server/tests/src/com/vaadin/data/util/filter/AbstractFilterTest.java97
-rw-r--r--server/tests/src/com/vaadin/data/util/filter/AndOrFilterTest.java232
-rw-r--r--server/tests/src/com/vaadin/data/util/filter/CompareFilterTest.java260
-rw-r--r--server/tests/src/com/vaadin/data/util/filter/IsNullFilterTest.java57
-rw-r--r--server/tests/src/com/vaadin/data/util/filter/NotFilterTest.java50
-rw-r--r--server/tests/src/com/vaadin/data/util/filter/SimpleStringFilterTest.java130
-rw-r--r--server/tests/src/com/vaadin/data/util/sqlcontainer/AllTests.java145
-rw-r--r--server/tests/src/com/vaadin/data/util/sqlcontainer/ColumnPropertyTest.java315
-rw-r--r--server/tests/src/com/vaadin/data/util/sqlcontainer/DataGenerator.java139
-rw-r--r--server/tests/src/com/vaadin/data/util/sqlcontainer/FreeformQueryUtil.java71
-rw-r--r--server/tests/src/com/vaadin/data/util/sqlcontainer/ReadOnlyRowIdTest.java50
-rw-r--r--server/tests/src/com/vaadin/data/util/sqlcontainer/RowIdTest.java55
-rw-r--r--server/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java1519
-rw-r--r--server/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTest.java2458
-rw-r--r--server/tests/src/com/vaadin/data/util/sqlcontainer/TicketTests.java186
-rw-r--r--server/tests/src/com/vaadin/data/util/sqlcontainer/UtilTest.java53
-rw-r--r--server/tests/src/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPoolTest.java108
-rw-r--r--server/tests/src/com/vaadin/data/util/sqlcontainer/connection/MockInitialContextFactory.java33
-rw-r--r--server/tests/src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPoolTest.java172
-rw-r--r--server/tests/src/com/vaadin/data/util/sqlcontainer/filters/BetweenTest.java122
-rw-r--r--server/tests/src/com/vaadin/data/util/sqlcontainer/filters/LikeTest.java229
-rw-r--r--server/tests/src/com/vaadin/data/util/sqlcontainer/generator/SQLGeneratorsTest.java241
-rw-r--r--server/tests/src/com/vaadin/data/util/sqlcontainer/query/FreeformQueryTest.java897
-rw-r--r--server/tests/src/com/vaadin/data/util/sqlcontainer/query/QueryBuilderTest.java311
-rw-r--r--server/tests/src/com/vaadin/data/util/sqlcontainer/query/TableQueryTest.java663
-rw-r--r--server/tests/src/com/vaadin/server/JSONSerializerTest.java140
-rw-r--r--server/tests/src/com/vaadin/server/TestAbstractApplicationServletStaticFilesLocation.java205
-rw-r--r--server/tests/src/com/vaadin/tests/VaadinClasses.java257
-rw-r--r--server/tests/src/com/vaadin/tests/data/bean/Address.java63
-rw-r--r--server/tests/src/com/vaadin/tests/data/bean/BeanToValidate.java56
-rw-r--r--server/tests/src/com/vaadin/tests/data/bean/Country.java18
-rw-r--r--server/tests/src/com/vaadin/tests/data/bean/Person.java143
-rw-r--r--server/tests/src/com/vaadin/tests/data/bean/PersonWithBeanValidationAnnotations.java156
-rw-r--r--server/tests/src/com/vaadin/tests/data/bean/Sex.java20
-rw-r--r--server/tests/src/com/vaadin/tests/data/converter/ConverterFactory.java116
-rw-r--r--server/tests/src/com/vaadin/tests/server/IndexedContainerListeners.java20
-rw-r--r--server/tests/src/com/vaadin/tests/server/PropertysetItemListeners.java13
-rw-r--r--server/tests/src/com/vaadin/tests/server/SourceFileChecker.java217
-rw-r--r--server/tests/src/com/vaadin/tests/server/TestAbstractBeanContainerListeners.java16
-rw-r--r--server/tests/src/com/vaadin/tests/server/TestAbstractContainerListeners.java21
-rw-r--r--server/tests/src/com/vaadin/tests/server/TestAbstractInMemoryContainerListeners.java14
-rw-r--r--server/tests/src/com/vaadin/tests/server/TestAbstractPropertyListeners.java24
-rw-r--r--server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java271
-rw-r--r--server/tests/src/com/vaadin/tests/server/TestEventRouter.java39
-rw-r--r--server/tests/src/com/vaadin/tests/server/TestFileTypeResolver.java79
-rw-r--r--server/tests/src/com/vaadin/tests/server/TestKeyMapper.java102
-rw-r--r--server/tests/src/com/vaadin/tests/server/TestMimeTypes.java26
-rw-r--r--server/tests/src/com/vaadin/tests/server/TestPropertyFormatter.java75
-rw-r--r--server/tests/src/com/vaadin/tests/server/TestSerialization.java126
-rw-r--r--server/tests/src/com/vaadin/tests/server/TestSimpleMultiPartInputStream.java138
-rw-r--r--server/tests/src/com/vaadin/tests/server/TestStreamVariableMapping.java77
-rw-r--r--server/tests/src/com/vaadin/tests/server/TestThemeNames.java38
-rw-r--r--server/tests/src/com/vaadin/tests/server/TransactionListenersConcurrency.java201
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/AbstractListenerMethodsTest.java173
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/FinalMethodTest.java68
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/absolutelayout/AbsoluteLayoutListeners.java13
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/absolutelayout/ComponentPosition.java204
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/abstractcomponent/TestAbstractComponentStyleNames.java61
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/abstractcomponentcontainer/TestAbstractComponentContainerListeners.java22
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/abstractfield/AbstractFieldValueConversions.java216
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/abstractfield/DefaultConverterFactory.java48
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/abstractfield/RemoveListenersOnDetach.java101
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/abstractfield/TestAbstractFieldListeners.java21
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/abstractorderedlayout/AddComponentsTest.java115
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/abstractorderedlayout/TestAbstractOrderedLayoutListeners.java14
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/abstractselect/TestAbstractSelectListeners.java20
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/abstractsplitpanel/TestAbstractSplitPanelListeners.java14
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/abstracttextfield/TestAbstractTextFieldListeners.java27
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/button/ButtonClick.java48
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/button/ButtonListeners.java27
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/csslayout/AddComponentsTest.java109
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/csslayout/CssLayoutListeners.java13
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/datefield/DateFieldListeners.java20
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/datefield/ResolutionTest.java61
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/embedded/EmbeddedListeners.java13
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/gridlayout/GridLayoutListeners.java13
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/label/LabelConverters.java71
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/label/LabelListeners.java13
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/loginform/LoginFormListeners.java13
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/menubar/MenuBarIds.java98
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/optiongroup/OptionGroupListeners.java20
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/orderedlayout/TestOrderedLayout.java49
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/panel/PanelListeners.java13
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/popupview/PopupViewListeners.java14
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/root/CustomUIClassLoader.java137
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/select/SelectListeners.java20
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/slider/SliderTest.java25
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/table/TableColumnAlignments.java143
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/table/TableGenerator.java42
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/table/TableListeners.java41
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/table/TableSerialization.java25
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/table/TableVisibleColumns.java75
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/table/TestFooter.java94
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/table/TestMultipleSelection.java57
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/tabsheet/TabSheetListeners.java13
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/tabsheet/TestTabSheet.java224
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/textfield/TextFieldWithPropertyFormatter.java108
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/tree/TestHasChildren.java25
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/tree/TestListeners.java137
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/tree/TreeListeners.java27
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/treetable/EmptyTreeTable.java13
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/upload/UploadListeners.java41
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/window/AddRemoveSubWindow.java79
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/window/AttachDetachWindow.java254
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/window/WindowListeners.java34
-rw-r--r--server/tests/src/com/vaadin/tests/server/componentcontainer/AbstractIndexedLayoutTest.java84
-rw-r--r--server/tests/src/com/vaadin/tests/server/componentcontainer/AddRemoveComponentTest.java40
-rw-r--r--server/tests/src/com/vaadin/tests/server/componentcontainer/CssLayoutTest.java34
-rw-r--r--server/tests/src/com/vaadin/tests/server/componentcontainer/FormLayoutTest.java34
-rw-r--r--server/tests/src/com/vaadin/tests/server/componentcontainer/VerticalLayoutTest.java34
-rw-r--r--server/tests/src/com/vaadin/tests/server/components/AbstractTestFieldValueChange.java129
-rw-r--r--server/tests/src/com/vaadin/tests/server/components/ComponentAttachDetachListenerTest.java345
-rw-r--r--server/tests/src/com/vaadin/tests/server/components/TestComboBoxValueChange.java31
-rw-r--r--server/tests/src/com/vaadin/tests/server/components/TestGridLayoutLastRowRemoval.java40
-rw-r--r--server/tests/src/com/vaadin/tests/server/components/TestTextFieldValueChange.java126
-rw-r--r--server/tests/src/com/vaadin/tests/server/components/TestWindow.java92
-rw-r--r--server/tests/src/com/vaadin/tests/server/navigator/ClassBasedViewProviderTest.java130
-rw-r--r--server/tests/src/com/vaadin/tests/server/navigator/NavigatorTest.java575
-rw-r--r--server/tests/src/com/vaadin/tests/server/navigator/UriFragmentManagerTest.java63
-rw-r--r--server/tests/src/com/vaadin/tests/server/validation/RangeValidatorTest.java52
-rw-r--r--server/tests/src/com/vaadin/tests/server/validation/TestBeanValidation.java57
-rw-r--r--server/tests/src/com/vaadin/tests/server/validation/TestReadOnlyValidation.java17
-rw-r--r--server/tests/src/com/vaadin/tests/util/GraphVizClassHierarchyCreator.java149
-rw-r--r--server/tests/src/com/vaadin/tests/util/TestUtil.java43
-rw-r--r--server/tests/src/com/vaadin/tests/util/UniqueSerializableTest.java45
143 files changed, 21200 insertions, 0 deletions
diff --git a/server/tests/src/com/vaadin/data/util/AbstractBeanContainerTest.java b/server/tests/src/com/vaadin/data/util/AbstractBeanContainerTest.java
new file mode 100644
index 0000000000..3c74a45bd7
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/AbstractBeanContainerTest.java
@@ -0,0 +1,81 @@
+package com.vaadin.data.util;
+
+import com.vaadin.data.util.AbstractBeanContainer;
+import com.vaadin.data.util.BeanContainer;
+import com.vaadin.data.util.BeanItemContainer;
+
+/**
+ * Automated test for {@link AbstractBeanContainer}.
+ *
+ * Only a limited subset of the functionality is tested here, the rest in tests
+ * of subclasses including {@link BeanItemContainer} and {@link BeanContainer}.
+ */
+public abstract class AbstractBeanContainerTest extends
+ AbstractInMemoryContainerTest {
+
+ public static class Person {
+ private String name;
+
+ public Person(String name) {
+ setName(name);
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+ }
+
+ public static class ClassName {
+ // field names match constants in parent test class
+ private String fullyQualifiedName;
+ private String simpleName;
+ private String reverseFullyQualifiedName;
+ private Integer idNumber;
+
+ public ClassName(String fullyQualifiedName, Integer idNumber) {
+ this.fullyQualifiedName = fullyQualifiedName;
+ simpleName = AbstractContainerTest
+ .getSimpleName(fullyQualifiedName);
+ reverseFullyQualifiedName = reverse(fullyQualifiedName);
+ this.idNumber = idNumber;
+ }
+
+ public String getFullyQualifiedName() {
+ return fullyQualifiedName;
+ }
+
+ public void setFullyQualifiedName(String fullyQualifiedName) {
+ this.fullyQualifiedName = fullyQualifiedName;
+ }
+
+ public String getSimpleName() {
+ return simpleName;
+ }
+
+ public void setSimpleName(String simpleName) {
+ this.simpleName = simpleName;
+ }
+
+ public String getReverseFullyQualifiedName() {
+ return reverseFullyQualifiedName;
+ }
+
+ public void setReverseFullyQualifiedName(
+ String reverseFullyQualifiedName) {
+ this.reverseFullyQualifiedName = reverseFullyQualifiedName;
+ }
+
+ public Integer getIdNumber() {
+ return idNumber;
+ }
+
+ public void setIdNumber(Integer idNumber) {
+ this.idNumber = idNumber;
+ }
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/data/util/AbstractContainerTest.java b/server/tests/src/com/vaadin/data/util/AbstractContainerTest.java
new file mode 100644
index 0000000000..b0151a6690
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/AbstractContainerTest.java
@@ -0,0 +1,649 @@
+package com.vaadin.data.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import com.vaadin.data.Container;
+import com.vaadin.data.Container.Filterable;
+import com.vaadin.data.Container.ItemSetChangeEvent;
+import com.vaadin.data.Container.ItemSetChangeListener;
+import com.vaadin.data.Container.Sortable;
+import com.vaadin.data.Item;
+import com.vaadin.data.util.filter.SimpleStringFilter;
+
+public abstract class AbstractContainerTest extends TestCase {
+
+ /**
+ * Helper class for testing e.g. listeners expecting events to be fired.
+ */
+ protected abstract static class AbstractEventCounter {
+ private int eventCount = 0;
+ private int lastAssertedEventCount = 0;
+
+ /**
+ * Increment the event count. To be called by subclasses e.g. from a
+ * listener method.
+ */
+ protected void increment() {
+ ++eventCount;
+ }
+
+ /**
+ * Check that no one event has occurred since the previous assert call.
+ */
+ public void assertNone() {
+ Assert.assertEquals(lastAssertedEventCount, eventCount);
+ }
+
+ /**
+ * Check that exactly one event has occurred since the previous assert
+ * call.
+ */
+ public void assertOnce() {
+ Assert.assertEquals(++lastAssertedEventCount, eventCount);
+ }
+
+ /**
+ * Reset the counter and the expected count.
+ */
+ public void reset() {
+ eventCount = 0;
+ lastAssertedEventCount = 0;
+ }
+ }
+
+ /**
+ * Test class for counting item set change events and verifying they have
+ * been received.
+ */
+ protected static class ItemSetChangeCounter extends AbstractEventCounter
+ implements ItemSetChangeListener {
+
+ @Override
+ public void containerItemSetChange(ItemSetChangeEvent event) {
+ increment();
+ }
+
+ }
+
+ // #6043: for items that have been filtered out, Container interface does
+ // not specify what to return from getItem() and getContainerProperty(), so
+ // need checkGetItemNull parameter for the test to be usable for most
+ // current containers
+ protected void validateContainer(Container container,
+ Object expectedFirstItemId, Object expectedLastItemId,
+ Object itemIdInSet, Object itemIdNotInSet,
+ boolean checkGetItemNull, int expectedSize) {
+ Container.Indexed indexed = null;
+ if (container instanceof Container.Indexed) {
+ indexed = (Container.Indexed) container;
+ }
+
+ List<Object> itemIdList = new ArrayList<Object>(container.getItemIds());
+
+ // size()
+ assertEquals(expectedSize, container.size());
+ assertEquals(expectedSize, itemIdList.size());
+
+ // first item, last item
+ Object first = itemIdList.get(0);
+ Object last = itemIdList.get(itemIdList.size() - 1);
+
+ assertEquals(expectedFirstItemId, first);
+ assertEquals(expectedLastItemId, last);
+
+ // containsId
+ assertFalse(container.containsId(itemIdNotInSet));
+ assertTrue(container.containsId(itemIdInSet));
+
+ // getItem
+ if (checkGetItemNull) {
+ assertNull(container.getItem(itemIdNotInSet));
+ }
+ assertNotNull(container.getItem(itemIdInSet));
+
+ // getContainerProperty
+ for (Object propId : container.getContainerPropertyIds()) {
+ if (checkGetItemNull) {
+ assertNull(container.getContainerProperty(itemIdNotInSet,
+ propId));
+ }
+ assertNotNull(container.getContainerProperty(itemIdInSet, propId));
+ }
+
+ if (indexed != null) {
+ // firstItemId
+ assertEquals(first, indexed.firstItemId());
+
+ // lastItemId
+ assertEquals(last, indexed.lastItemId());
+
+ // nextItemId
+ assertEquals(itemIdList.get(1), indexed.nextItemId(first));
+
+ // prevItemId
+ assertEquals(itemIdList.get(itemIdList.size() - 2),
+ indexed.prevItemId(last));
+
+ // isFirstId
+ assertTrue(indexed.isFirstId(first));
+ assertFalse(indexed.isFirstId(last));
+
+ // isLastId
+ assertTrue(indexed.isLastId(last));
+ assertFalse(indexed.isLastId(first));
+
+ // indexOfId
+ assertEquals(0, indexed.indexOfId(first));
+ assertEquals(expectedSize - 1, indexed.indexOfId(last));
+
+ // getIdByIndex
+ assertEquals(indexed.getIdByIndex(0), first);
+ assertEquals(indexed.getIdByIndex(expectedSize - 1), last);
+
+ }
+
+ }
+
+ protected static final Object FULLY_QUALIFIED_NAME = "fullyQualifiedName";
+ protected static final Object SIMPLE_NAME = "simpleName";
+ protected static final Object REVERSE_FULLY_QUALIFIED_NAME = "reverseFullyQualifiedName";
+ protected static final Object ID_NUMBER = "idNumber";
+
+ protected void testBasicContainerOperations(Container container) {
+ initializeContainer(container);
+
+ // Basic container
+ validateContainer(container, sampleData[0],
+ sampleData[sampleData.length - 1], sampleData[10], "abc", true,
+ sampleData.length);
+ }
+
+ protected void testContainerOrdered(Container.Ordered container) {
+ Object id = container.addItem();
+ assertNotNull(id);
+ Item item = container.getItem(id);
+ assertNotNull(item);
+
+ assertEquals(id, container.firstItemId());
+ assertEquals(id, container.lastItemId());
+
+ // isFirstId
+ assertTrue(container.isFirstId(id));
+ assertTrue(container.isFirstId(container.firstItemId()));
+ // isLastId
+ assertTrue(container.isLastId(id));
+ assertTrue(container.isLastId(container.lastItemId()));
+
+ // Add a new item before the first
+ // addItemAfter
+ Object newFirstId = container.addItemAfter(null);
+ assertNotNull(newFirstId);
+ assertNotNull(container.getItem(newFirstId));
+
+ // isFirstId
+ assertTrue(container.isFirstId(newFirstId));
+ assertTrue(container.isFirstId(container.firstItemId()));
+ // isLastId
+ assertTrue(container.isLastId(id));
+ assertTrue(container.isLastId(container.lastItemId()));
+
+ // nextItemId
+ assertEquals(id, container.nextItemId(newFirstId));
+ assertNull(container.nextItemId(id));
+ assertNull(container.nextItemId("not-in-container"));
+
+ // prevItemId
+ assertEquals(newFirstId, container.prevItemId(id));
+ assertNull(container.prevItemId(newFirstId));
+ assertNull(container.prevItemId("not-in-container"));
+
+ // addItemAfter(Object)
+ Object newSecondItemId = container.addItemAfter(newFirstId);
+ // order is now: newFirstId, newSecondItemId, id
+ assertNotNull(newSecondItemId);
+ assertNotNull(container.getItem(newSecondItemId));
+ assertEquals(id, container.nextItemId(newSecondItemId));
+ assertEquals(newFirstId, container.prevItemId(newSecondItemId));
+
+ // addItemAfter(Object,Object)
+ String fourthId = "id of the fourth item";
+ Item fourth = container.addItemAfter(newFirstId, fourthId);
+ // order is now: newFirstId, fourthId, newSecondItemId, id
+ assertNotNull(fourth);
+ assertEquals(fourth, container.getItem(fourthId));
+ assertEquals(newSecondItemId, container.nextItemId(fourthId));
+ assertEquals(newFirstId, container.prevItemId(fourthId));
+
+ // addItemAfter(Object,Object)
+ Object fifthId = new Object();
+ Item fifth = container.addItemAfter(null, fifthId);
+ // order is now: fifthId, newFirstId, fourthId, newSecondItemId, id
+ assertNotNull(fifth);
+ assertEquals(fifth, container.getItem(fifthId));
+ assertEquals(newFirstId, container.nextItemId(fifthId));
+ assertNull(container.prevItemId(fifthId));
+
+ }
+
+ protected void testContainerIndexed(Container.Indexed container,
+ Object itemId, int itemPosition, boolean testAddEmptyItemAt,
+ Object newItemId, boolean testAddItemAtWithId) {
+ initializeContainer(container);
+
+ // indexOfId
+ Assert.assertEquals(itemPosition, container.indexOfId(itemId));
+
+ // getIdByIndex
+ Assert.assertEquals(itemId, container.getIdByIndex(itemPosition));
+
+ // addItemAt
+ if (testAddEmptyItemAt) {
+ Object addedId = container.addItemAt(itemPosition);
+ Assert.assertEquals(itemPosition, container.indexOfId(addedId));
+ Assert.assertEquals(itemPosition + 1, container.indexOfId(itemId));
+ Assert.assertEquals(addedId, container.getIdByIndex(itemPosition));
+ Assert.assertEquals(itemId,
+ container.getIdByIndex(itemPosition + 1));
+
+ Object newFirstId = container.addItemAt(0);
+ Assert.assertEquals(0, container.indexOfId(newFirstId));
+ Assert.assertEquals(itemPosition + 2, container.indexOfId(itemId));
+ Assert.assertEquals(newFirstId, container.firstItemId());
+ Assert.assertEquals(newFirstId, container.getIdByIndex(0));
+ Assert.assertEquals(itemId,
+ container.getIdByIndex(itemPosition + 2));
+
+ Object newLastId = container.addItemAt(container.size());
+ Assert.assertEquals(container.size() - 1,
+ container.indexOfId(newLastId));
+ Assert.assertEquals(itemPosition + 2, container.indexOfId(itemId));
+ Assert.assertEquals(newLastId, container.lastItemId());
+ Assert.assertEquals(newLastId,
+ container.getIdByIndex(container.size() - 1));
+ Assert.assertEquals(itemId,
+ container.getIdByIndex(itemPosition + 2));
+
+ Assert.assertTrue(container.removeItem(addedId));
+ Assert.assertTrue(container.removeItem(newFirstId));
+ Assert.assertTrue(container.removeItem(newLastId));
+
+ Assert.assertFalse(
+ "Removing non-existing item should indicate failure",
+ container.removeItem(addedId));
+ }
+
+ // addItemAt
+ if (testAddItemAtWithId) {
+ container.addItemAt(itemPosition, newItemId);
+ Assert.assertEquals(itemPosition, container.indexOfId(newItemId));
+ Assert.assertEquals(itemPosition + 1, container.indexOfId(itemId));
+ Assert.assertEquals(newItemId, container.getIdByIndex(itemPosition));
+ Assert.assertEquals(itemId,
+ container.getIdByIndex(itemPosition + 1));
+ Assert.assertTrue(container.removeItem(newItemId));
+ Assert.assertFalse(container.containsId(newItemId));
+
+ container.addItemAt(0, newItemId);
+ Assert.assertEquals(0, container.indexOfId(newItemId));
+ Assert.assertEquals(itemPosition + 1, container.indexOfId(itemId));
+ Assert.assertEquals(newItemId, container.firstItemId());
+ Assert.assertEquals(newItemId, container.getIdByIndex(0));
+ Assert.assertEquals(itemId,
+ container.getIdByIndex(itemPosition + 1));
+ Assert.assertTrue(container.removeItem(newItemId));
+ Assert.assertFalse(container.containsId(newItemId));
+
+ container.addItemAt(container.size(), newItemId);
+ Assert.assertEquals(container.size() - 1,
+ container.indexOfId(newItemId));
+ Assert.assertEquals(itemPosition, container.indexOfId(itemId));
+ Assert.assertEquals(newItemId, container.lastItemId());
+ Assert.assertEquals(newItemId,
+ container.getIdByIndex(container.size() - 1));
+ Assert.assertEquals(itemId, container.getIdByIndex(itemPosition));
+ Assert.assertTrue(container.removeItem(newItemId));
+ Assert.assertFalse(container.containsId(newItemId));
+ }
+ }
+
+ protected void testContainerFiltering(Container.Filterable container) {
+ initializeContainer(container);
+
+ // Filter by "contains ab"
+ container.addContainerFilter(new SimpleStringFilter(
+ FULLY_QUALIFIED_NAME, "ab", false, false));
+
+ validateContainer(container, "com.vaadin.data.BufferedValidatable",
+ "com.vaadin.ui.TabSheet", "com.vaadin.client.Focusable",
+ "com.vaadin.data.Buffered", isFilteredOutItemNull(), 20);
+
+ // Filter by "contains da" (reversed as ad here)
+ container.removeAllContainerFilters();
+ container.addContainerFilter(new SimpleStringFilter(
+ REVERSE_FULLY_QUALIFIED_NAME, "ad", false, false));
+
+ validateContainer(container, "com.vaadin.data.Buffered",
+ "com.vaadin.server.ComponentSizeValidator",
+ "com.vaadin.data.util.IndexedContainer",
+ "com.vaadin.client.ui.VUriFragmentUtility",
+ isFilteredOutItemNull(), 37);
+ }
+
+ /**
+ * Override in subclasses to return false if the container getItem() method
+ * returns a non-null value for an item that has been filtered out.
+ *
+ * @return
+ */
+ protected boolean isFilteredOutItemNull() {
+ return true;
+ }
+
+ protected void testContainerSortingAndFiltering(Container.Sortable sortable) {
+ Filterable filterable = (Filterable) sortable;
+
+ initializeContainer(sortable);
+
+ // Filter by "contains ab"
+ filterable.addContainerFilter(new SimpleStringFilter(
+ FULLY_QUALIFIED_NAME, "ab", false, false));
+
+ // Must be able to sort based on PROP1 for this test
+ assertTrue(sortable.getSortableContainerPropertyIds().contains(
+ FULLY_QUALIFIED_NAME));
+
+ sortable.sort(new Object[] { FULLY_QUALIFIED_NAME },
+ new boolean[] { true });
+
+ validateContainer(sortable, "com.vaadin.data.BufferedValidatable",
+ "com.vaadin.ui.TableFieldFactory",
+ "com.vaadin.ui.TableFieldFactory",
+ "com.vaadin.data.util.BeanItem", isFilteredOutItemNull(), 20);
+ }
+
+ protected void testContainerSorting(Container.Filterable container) {
+ Container.Sortable sortable = (Sortable) container;
+
+ initializeContainer(container);
+
+ // Must be able to sort based on PROP1 for this test
+ assertTrue(sortable.getSortableContainerPropertyIds().contains(
+ FULLY_QUALIFIED_NAME));
+ assertTrue(sortable.getSortableContainerPropertyIds().contains(
+ REVERSE_FULLY_QUALIFIED_NAME));
+
+ sortable.sort(new Object[] { FULLY_QUALIFIED_NAME },
+ new boolean[] { true });
+
+ validateContainer(container, "com.vaadin.Application",
+ "org.vaadin.test.LastClass",
+ "com.vaadin.server.ApplicationResource", "blah", true,
+ sampleData.length);
+
+ sortable.sort(new Object[] { REVERSE_FULLY_QUALIFIED_NAME },
+ new boolean[] { true });
+
+ validateContainer(container, "com.vaadin.server.ApplicationPortlet2",
+ "com.vaadin.data.util.ObjectProperty",
+ "com.vaadin.ui.BaseFieldFactory", "blah", true,
+ sampleData.length);
+
+ }
+
+ protected void initializeContainer(Container container) {
+ Assert.assertTrue(container.removeAllItems());
+ Object[] propertyIds = container.getContainerPropertyIds().toArray();
+ for (Object propertyId : propertyIds) {
+ container.removeContainerProperty(propertyId);
+ }
+
+ container.addContainerProperty(FULLY_QUALIFIED_NAME, String.class, "");
+ container.addContainerProperty(SIMPLE_NAME, String.class, "");
+ container.addContainerProperty(REVERSE_FULLY_QUALIFIED_NAME,
+ String.class, null);
+ container.addContainerProperty(ID_NUMBER, Integer.class, null);
+
+ for (int i = 0; i < sampleData.length; i++) {
+ String id = sampleData[i];
+ Item item = container.addItem(id);
+
+ item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(sampleData[i]);
+ item.getItemProperty(SIMPLE_NAME).setValue(
+ getSimpleName(sampleData[i]));
+ item.getItemProperty(REVERSE_FULLY_QUALIFIED_NAME).setValue(
+ reverse(sampleData[i]));
+ item.getItemProperty(ID_NUMBER).setValue(i);
+ }
+ }
+
+ protected static String getSimpleName(String name) {
+ if (name.contains(".")) {
+ return name.substring(name.lastIndexOf('.') + 1);
+ } else {
+ return name;
+ }
+ }
+
+ protected static String reverse(String string) {
+ return new StringBuilder(string).reverse().toString();
+ }
+
+ protected final String[] sampleData = {
+ "com.vaadin.annotations.AutoGenerated", "com.vaadin.Application",
+ "com.vaadin.data.Buffered", "com.vaadin.data.BufferedValidatable",
+ "com.vaadin.data.Container", "com.vaadin.data.Item",
+ "com.vaadin.data.Property", "com.vaadin.data.util.BeanItem",
+ "com.vaadin.data.util.BeanItemContainer",
+ "com.vaadin.data.util.ContainerHierarchicalWrapper",
+ "com.vaadin.data.util.ContainerOrderedWrapper",
+ "com.vaadin.data.util.DefaultItemSorter",
+ "com.vaadin.data.util.FilesystemContainer",
+ "com.vaadin.data.util.Filter",
+ "com.vaadin.data.util.HierarchicalContainer",
+ "com.vaadin.data.util.IndexedContainer",
+ "com.vaadin.data.util.ItemSorter",
+ "com.vaadin.data.util.MethodProperty",
+ "com.vaadin.data.util.ObjectProperty",
+ "com.vaadin.data.util.PropertyFormatter",
+ "com.vaadin.data.util.PropertysetItem",
+ "com.vaadin.data.util.QueryContainer",
+ "com.vaadin.data.util.TextFileProperty",
+ "com.vaadin.data.Validatable",
+ "com.vaadin.data.validator.AbstractStringValidator",
+ "com.vaadin.data.validator.AbstractValidator",
+ "com.vaadin.data.validator.CompositeValidator",
+ "com.vaadin.data.validator.DoubleValidator",
+ "com.vaadin.data.validator.EmailValidator",
+ "com.vaadin.data.validator.IntegerValidator",
+ "com.vaadin.data.validator.NullValidator",
+ "com.vaadin.data.validator.RegexpValidator",
+ "com.vaadin.data.validator.StringLengthValidator",
+ "com.vaadin.data.Validator", "com.vaadin.event.Action",
+ "com.vaadin.event.ComponentEventListener",
+ "com.vaadin.event.EventRouter", "com.vaadin.event.FieldEvents",
+ "com.vaadin.event.ItemClickEvent", "com.vaadin.event.LayoutEvents",
+ "com.vaadin.event.ListenerMethod",
+ "com.vaadin.event.MethodEventSource",
+ "com.vaadin.event.MouseEvents", "com.vaadin.event.ShortcutAction",
+ "com.vaadin.launcher.DemoLauncher",
+ "com.vaadin.launcher.DevelopmentServerLauncher",
+ "com.vaadin.launcher.util.BrowserLauncher",
+ "com.vaadin.service.ApplicationContext",
+ "com.vaadin.service.FileTypeResolver",
+ "com.vaadin.server.ApplicationResource",
+ "com.vaadin.server.ClassResource",
+ "com.vaadin.server.CompositeErrorMessage",
+ "com.vaadin.server.DownloadStream",
+ "com.vaadin.server.ErrorMessage",
+ "com.vaadin.server.ExternalResource",
+ "com.vaadin.server.FileResource",
+ "com.vaadin.client.ApplicationConfiguration",
+ "com.vaadin.client.ApplicationConnection",
+ "com.vaadin.client.BrowserInfo",
+ "com.vaadin.client.ClientExceptionHandler",
+ "com.vaadin.client.ComponentDetail",
+ "com.vaadin.client.ComponentDetailMap",
+ "com.vaadin.client.ComponentLocator", "com.vaadin.client.Console",
+ "com.vaadin.client.Container",
+ "com.vaadin.client.ContainerResizedListener",
+ "com.vaadin.client.CSSRule", "com.vaadin.client.DateTimeService",
+ "com.vaadin.client.DefaultWidgetSet",
+ "com.vaadin.client.Focusable",
+ "com.vaadin.client.HistoryImplIEVaadin",
+ "com.vaadin.client.LocaleNotLoadedException",
+ "com.vaadin.client.LocaleService",
+ "com.vaadin.client.MouseEventDetails",
+ "com.vaadin.client.NullConsole", "com.vaadin.client.Paintable",
+ "com.vaadin.client.RenderInformation",
+ "com.vaadin.client.RenderSpace",
+ "com.vaadin.client.StyleConstants",
+ "com.vaadin.client.TooltipInfo", "com.vaadin.client.ui.Action",
+ "com.vaadin.client.ui.ActionOwner",
+ "com.vaadin.client.ui.AlignmentInfo",
+ "com.vaadin.client.ui.CalendarEntry",
+ "com.vaadin.client.ui.ClickEventHandler",
+ "com.vaadin.client.ui.Field", "com.vaadin.client.ui.Icon",
+ "com.vaadin.client.ui.layout.CellBasedLayout",
+ "com.vaadin.client.ui.layout.ChildComponentContainer",
+ "com.vaadin.client.ui.layout.Margins",
+ "com.vaadin.client.ui.LayoutClickEventHandler",
+ "com.vaadin.client.ui.MenuBar", "com.vaadin.client.ui.MenuItem",
+ "com.vaadin.client.ui.richtextarea.VRichTextArea",
+ "com.vaadin.client.ui.richtextarea.VRichTextToolbar",
+ "com.vaadin.client.ui.ShortcutActionHandler",
+ "com.vaadin.client.ui.SubPartAware", "com.vaadin.client.ui.Table",
+ "com.vaadin.client.ui.TreeAction",
+ "com.vaadin.client.ui.TreeImages",
+ "com.vaadin.client.ui.VAbsoluteLayout",
+ "com.vaadin.client.ui.VAccordion", "com.vaadin.client.ui.VButton",
+ "com.vaadin.client.ui.VCalendarPanel",
+ "com.vaadin.client.ui.VCheckBox",
+ "com.vaadin.client.ui.VContextMenu",
+ "com.vaadin.client.ui.VCssLayout",
+ "com.vaadin.client.ui.VCustomComponent",
+ "com.vaadin.client.ui.VCustomLayout",
+ "com.vaadin.client.ui.VDateField",
+ "com.vaadin.client.ui.VDateFieldCalendar",
+ "com.vaadin.client.ui.VEmbedded",
+ "com.vaadin.client.ui.VFilterSelect", "com.vaadin.client.ui.VForm",
+ "com.vaadin.client.ui.VFormLayout",
+ "com.vaadin.client.ui.VGridLayout",
+ "com.vaadin.client.ui.VHorizontalLayout",
+ "com.vaadin.client.ui.VLabel", "com.vaadin.client.ui.VLink",
+ "com.vaadin.client.ui.VListSelect",
+ "com.vaadin.client.ui.VMarginInfo",
+ "com.vaadin.client.ui.VMenuBar",
+ "com.vaadin.client.ui.VNativeButton",
+ "com.vaadin.client.ui.VNativeSelect",
+ "com.vaadin.client.ui.VNotification",
+ "com.vaadin.client.ui.VOptionGroup",
+ "com.vaadin.client.ui.VOptionGroupBase",
+ "com.vaadin.client.ui.VOrderedLayout",
+ "com.vaadin.client.ui.VOverlay", "com.vaadin.client.ui.VPanel",
+ "com.vaadin.client.ui.VPasswordField",
+ "com.vaadin.client.ui.VPopupCalendar",
+ "com.vaadin.client.ui.VPopupView",
+ "com.vaadin.client.ui.VProgressIndicator",
+ "com.vaadin.client.ui.VScrollTable",
+ "com.vaadin.client.ui.VSlider", "com.vaadin.client.ui.VSplitPanel",
+ "com.vaadin.client.ui.VSplitPanelHorizontal",
+ "com.vaadin.client.ui.VSplitPanelVertical",
+ "com.vaadin.client.ui.VTablePaging",
+ "com.vaadin.client.ui.VTabsheet",
+ "com.vaadin.client.ui.VTabsheetBase",
+ "com.vaadin.client.ui.VTabsheetPanel",
+ "com.vaadin.client.ui.VTextArea",
+ "com.vaadin.client.ui.VTextField",
+ "com.vaadin.client.ui.VTextualDate", "com.vaadin.client.ui.VTime",
+ "com.vaadin.client.ui.VTree",
+ "com.vaadin.client.ui.VTwinColSelect",
+ "com.vaadin.client.ui.VUnknownComponent",
+ "com.vaadin.client.ui.VUpload",
+ "com.vaadin.client.ui.VUriFragmentUtility",
+ "com.vaadin.client.ui.VVerticalLayout",
+ "com.vaadin.client.ui.VView", "com.vaadin.client.ui.VWindow",
+ "com.vaadin.client.UIDL", "com.vaadin.client.Util",
+ "com.vaadin.client.ValueMap", "com.vaadin.client.VCaption",
+ "com.vaadin.client.VCaptionWrapper",
+ "com.vaadin.client.VDebugConsole",
+ "com.vaadin.client.VErrorMessage", "com.vaadin.client.VTooltip",
+ "com.vaadin.client.VUIDLBrowser", "com.vaadin.client.WidgetMap",
+ "com.vaadin.client.WidgetSet",
+ "com.vaadin.server.AbstractApplicationPortlet",
+ "com.vaadin.server.AbstractApplicationServlet",
+ "com.vaadin.server.AbstractCommunicationManager",
+ "com.vaadin.server.AbstractWebApplicationContext",
+ "com.vaadin.server.ApplicationPortlet",
+ "com.vaadin.server.ApplicationPortlet2",
+ "com.vaadin.server.ApplicationRunnerServlet",
+ "com.vaadin.server.ApplicationServlet",
+ "com.vaadin.server.ChangeVariablesErrorEvent",
+ "com.vaadin.server.CommunicationManager",
+ "com.vaadin.server.ComponentSizeValidator",
+ "com.vaadin.server.Constants",
+ "com.vaadin.server.GAEApplicationServlet",
+ "com.vaadin.server.HttpServletRequestListener",
+ "com.vaadin.server.HttpUploadStream",
+ "com.vaadin.server.JsonPaintTarget",
+ "com.vaadin.server.PortletApplicationContext",
+ "com.vaadin.server.PortletApplicationContext2",
+ "com.vaadin.server.PortletCommunicationManager",
+ "com.vaadin.server.PortletRequestListener",
+ "com.vaadin.server.RestrictedRenderResponse",
+ "com.vaadin.server.SessionExpiredException",
+ "com.vaadin.server.SystemMessageException",
+ "com.vaadin.server.WebApplicationContext",
+ "com.vaadin.server.WebBrowser",
+ "com.vaadin.server.widgetsetutils.ClassPathExplorer",
+ "com.vaadin.server.widgetsetutils.WidgetMapGenerator",
+ "com.vaadin.server.widgetsetutils.WidgetSetBuilder",
+ "com.vaadin.server.KeyMapper", "com.vaadin.server.Paintable",
+ "com.vaadin.server.PaintException",
+ "com.vaadin.server.PaintTarget",
+ "com.vaadin.server.ParameterHandler", "com.vaadin.server.Resource",
+ "com.vaadin.server.Scrollable", "com.vaadin.server.Sizeable",
+ "com.vaadin.server.StreamResource",
+ "com.vaadin.server.SystemError", "com.vaadin.server.Terminal",
+ "com.vaadin.server.ThemeResource",
+ "com.vaadin.server.UploadStream", "com.vaadin.server.URIHandler",
+ "com.vaadin.server.UserError", "com.vaadin.server.VariableOwner",
+ "com.vaadin.tools.ReflectTools",
+ "com.vaadin.tools.WidgetsetCompiler",
+ "com.vaadin.ui.AbsoluteLayout", "com.vaadin.ui.AbstractComponent",
+ "com.vaadin.ui.AbstractComponentContainer",
+ "com.vaadin.ui.AbstractField", "com.vaadin.ui.AbstractLayout",
+ "com.vaadin.ui.AbstractOrderedLayout",
+ "com.vaadin.ui.AbstractSelect", "com.vaadin.ui.Accordion",
+ "com.vaadin.ui.Alignment", "com.vaadin.ui.AlignmentUtils",
+ "com.vaadin.ui.BaseFieldFactory", "com.vaadin.ui.Button",
+ "com.vaadin.ui.CheckBox", "com.vaadin.ui.ClientWidget",
+ "com.vaadin.ui.ComboBox", "com.vaadin.ui.Component",
+ "com.vaadin.ui.ComponentContainer", "com.vaadin.ui.CssLayout",
+ "com.vaadin.ui.CustomComponent", "com.vaadin.ui.CustomLayout",
+ "com.vaadin.ui.DateField", "com.vaadin.ui.DefaultFieldFactory",
+ "com.vaadin.ui.Embedded", "com.vaadin.ui.ExpandLayout",
+ "com.vaadin.ui.Field", "com.vaadin.ui.FieldFactory",
+ "com.vaadin.ui.Form", "com.vaadin.ui.FormFieldFactory",
+ "com.vaadin.ui.FormLayout", "com.vaadin.ui.GridLayout",
+ "com.vaadin.ui.HorizontalLayout", "com.vaadin.ui.InlineDateField",
+ "com.vaadin.ui.Label", "com.vaadin.ui.Layout",
+ "com.vaadin.ui.Link", "com.vaadin.ui.ListSelect",
+ "com.vaadin.ui.LoginForm", "com.vaadin.ui.MenuBar",
+ "com.vaadin.ui.NativeButton", "com.vaadin.ui.NativeSelect",
+ "com.vaadin.ui.OptionGroup", "com.vaadin.ui.OrderedLayout",
+ "com.vaadin.ui.Panel", "com.vaadin.ui.PopupDateField",
+ "com.vaadin.ui.PopupView", "com.vaadin.ui.ProgressIndicator",
+ "com.vaadin.ui.RichTextArea", "com.vaadin.ui.Select",
+ "com.vaadin.ui.Slider", "com.vaadin.ui.SplitPanel",
+ "com.vaadin.ui.Table", "com.vaadin.ui.TableFieldFactory",
+ "com.vaadin.ui.TabSheet", "com.vaadin.ui.TextField",
+ "com.vaadin.ui.Tree", "com.vaadin.ui.TwinColSelect",
+ "com.vaadin.ui.Upload", "com.vaadin.ui.UriFragmentUtility",
+ "com.vaadin.ui.VerticalLayout", "com.vaadin.ui.Window",
+ "com.vaadin.util.SerializerHelper", "org.vaadin.test.LastClass" };
+
+}
diff --git a/server/tests/src/com/vaadin/data/util/AbstractHierarchicalContainerTest.java b/server/tests/src/com/vaadin/data/util/AbstractHierarchicalContainerTest.java
new file mode 100644
index 0000000000..772cd250ce
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/AbstractHierarchicalContainerTest.java
@@ -0,0 +1,256 @@
+package com.vaadin.data.util;
+
+import java.util.Collection;
+
+import com.vaadin.data.Container;
+import com.vaadin.data.Container.Hierarchical;
+import com.vaadin.data.Container.Sortable;
+import com.vaadin.data.Item;
+
+public abstract class AbstractHierarchicalContainerTest extends
+ AbstractContainerTest {
+
+ /**
+ * @param container
+ * The container to validate
+ * @param expectedFirstItemId
+ * Expected first item id
+ * @param expectedLastItemId
+ * Expected last item id
+ * @param itemIdInSet
+ * An item id that is in the container
+ * @param itemIdNotInSet
+ * An item id that is not in the container
+ * @param checkGetItemNull
+ * true if getItem() should return null for itemIdNotInSet, false
+ * to skip the check (container.containsId() is checked in any
+ * case)
+ * @param expectedSize
+ * Expected number of items in the container. Not related to
+ * hierarchy.
+ * @param expectedTraversalSize
+ * Expected number of items found when traversing from the roots
+ * down to all available nodes.
+ * @param expectedRootSize
+ * Expected number of root items
+ * @param rootsHaveChildren
+ * true if all roots have children, false otherwise (skips some
+ * asserts)
+ */
+ protected void validateHierarchicalContainer(Hierarchical container,
+ Object expectedFirstItemId, Object expectedLastItemId,
+ Object itemIdInSet, Object itemIdNotInSet,
+ boolean checkGetItemNull, int expectedSize, int expectedRootSize,
+ boolean rootsHaveChildren) {
+
+ validateContainer(container, expectedFirstItemId, expectedLastItemId,
+ itemIdInSet, itemIdNotInSet, checkGetItemNull, expectedSize);
+
+ // rootItemIds
+ Collection<?> rootIds = container.rootItemIds();
+ assertEquals(expectedRootSize, rootIds.size());
+
+ for (Object rootId : rootIds) {
+ // All roots must be in container
+ assertTrue(container.containsId(rootId));
+
+ // All roots must have no parent
+ assertNull(container.getParent(rootId));
+
+ // all roots must be roots
+ assertTrue(container.isRoot(rootId));
+
+ if (rootsHaveChildren) {
+ // all roots have children allowed in this case
+ assertTrue(container.areChildrenAllowed(rootId));
+
+ // all roots have children in this case
+ Collection<?> children = container.getChildren(rootId);
+ assertNotNull(rootId + " should have children", children);
+ assertTrue(rootId + " should have children",
+ (children.size() > 0));
+ // getParent
+ for (Object childId : children) {
+ assertEquals(container.getParent(childId), rootId);
+ }
+
+ }
+ }
+
+ // isRoot should return false for unknown items
+ assertFalse(container.isRoot(itemIdNotInSet));
+
+ // hasChildren should return false for unknown items
+ assertFalse(container.hasChildren(itemIdNotInSet));
+
+ // areChildrenAllowed should return false for unknown items
+ assertFalse(container.areChildrenAllowed(itemIdNotInSet));
+
+ // removeItem of unknown items should return false
+ assertFalse(container.removeItem(itemIdNotInSet));
+
+ assertEquals(expectedSize, countNodes(container));
+
+ validateHierarchy(container);
+ }
+
+ private int countNodes(Hierarchical container) {
+ int totalNodes = 0;
+ for (Object rootId : container.rootItemIds()) {
+ totalNodes += countNodes(container, rootId);
+ }
+
+ return totalNodes;
+ }
+
+ private int countNodes(Hierarchical container, Object itemId) {
+ int nodes = 1; // This
+ Collection<?> children = container.getChildren(itemId);
+ if (children != null) {
+ for (Object id : children) {
+ nodes += countNodes(container, id);
+ }
+ }
+
+ return nodes;
+ }
+
+ private void validateHierarchy(Hierarchical container) {
+ for (Object rootId : container.rootItemIds()) {
+ validateHierarchy(container, rootId, null);
+ }
+ }
+
+ private void validateHierarchy(Hierarchical container, Object itemId,
+ Object parentId) {
+ Collection<?> children = container.getChildren(itemId);
+
+ // getParent
+ assertEquals(container.getParent(itemId), parentId);
+
+ if (!container.areChildrenAllowed(itemId)) {
+ // If no children is allowed the item should have no children
+ assertFalse(container.hasChildren(itemId));
+ assertTrue(children == null || children.size() == 0);
+
+ return;
+ }
+ if (children != null) {
+ for (Object id : children) {
+ validateHierarchy(container, id, itemId);
+ }
+ }
+ }
+
+ protected void testHierarchicalContainer(Container.Hierarchical container) {
+ initializeContainer(container);
+
+ int packages = 21 + 3;
+ int expectedSize = sampleData.length + packages;
+ validateHierarchicalContainer(container, "com",
+ "org.vaadin.test.LastClass",
+ "com.vaadin.server.ApplicationResource", "blah", true,
+ expectedSize, 2, true);
+
+ }
+
+ protected void testHierarchicalSorting(Container.Hierarchical container) {
+ Container.Sortable sortable = (Sortable) container;
+
+ initializeContainer(container);
+
+ // Must be able to sort based on PROP1 and PROP2 for this test
+ assertTrue(sortable.getSortableContainerPropertyIds().contains(
+ FULLY_QUALIFIED_NAME));
+ assertTrue(sortable.getSortableContainerPropertyIds().contains(
+ REVERSE_FULLY_QUALIFIED_NAME));
+
+ sortable.sort(new Object[] { FULLY_QUALIFIED_NAME },
+ new boolean[] { true });
+
+ int packages = 21 + 3;
+ int expectedSize = sampleData.length + packages;
+ validateHierarchicalContainer(container, "com",
+ "org.vaadin.test.LastClass",
+ "com.vaadin.server.ApplicationResource", "blah", true,
+ expectedSize, 2, true);
+
+ sortable.sort(new Object[] { REVERSE_FULLY_QUALIFIED_NAME },
+ new boolean[] { true });
+
+ validateHierarchicalContainer(container,
+ "com.vaadin.server.ApplicationPortlet2",
+ "com.vaadin.data.util.ObjectProperty",
+ "com.vaadin.server.ApplicationResource", "blah", true,
+ expectedSize, 2, true);
+
+ }
+
+ protected void initializeContainer(Container.Hierarchical container) {
+ container.removeAllItems();
+ Object[] propertyIds = container.getContainerPropertyIds().toArray();
+ for (Object propertyId : propertyIds) {
+ container.removeContainerProperty(propertyId);
+ }
+
+ container.addContainerProperty(FULLY_QUALIFIED_NAME, String.class, "");
+ container.addContainerProperty(SIMPLE_NAME, String.class, "");
+ container.addContainerProperty(REVERSE_FULLY_QUALIFIED_NAME,
+ String.class, null);
+ container.addContainerProperty(ID_NUMBER, Integer.class, null);
+
+ for (int i = 0; i < sampleData.length; i++) {
+ String id = sampleData[i];
+
+ // Add path as parent
+ String paths[] = id.split("\\.");
+ String path = paths[0];
+ // Adds "com" and other items multiple times so should return null
+ // for all but the first time
+ if (container.addItem(path) != null) {
+ assertTrue(container.setChildrenAllowed(path, false));
+ Item item = container.getItem(path);
+ item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(path);
+ item.getItemProperty(SIMPLE_NAME).setValue(getSimpleName(path));
+ item.getItemProperty(REVERSE_FULLY_QUALIFIED_NAME).setValue(
+ reverse(path));
+ item.getItemProperty(ID_NUMBER).setValue(1);
+ }
+ for (int j = 1; j < paths.length; j++) {
+ String parent = path;
+ path = path + "." + paths[j];
+
+ // Adds "com" and other items multiple times so should return
+ // null for all but the first time
+ if (container.addItem(path) != null) {
+ assertTrue(container.setChildrenAllowed(path, false));
+
+ Item item = container.getItem(path);
+ item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(path);
+ item.getItemProperty(SIMPLE_NAME).setValue(
+ getSimpleName(path));
+ item.getItemProperty(REVERSE_FULLY_QUALIFIED_NAME)
+ .setValue(reverse(path));
+ item.getItemProperty(ID_NUMBER).setValue(1);
+
+ }
+ assertTrue(container.setChildrenAllowed(parent, true));
+ assertTrue(
+ "Failed to set " + parent + " as parent for " + path,
+ container.setParent(path, parent));
+ }
+
+ Item item = container.getItem(id);
+ assertNotNull(item);
+ String parent = id.substring(0, id.lastIndexOf('.'));
+ assertTrue(container.setParent(id, parent));
+ item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(sampleData[i]);
+ item.getItemProperty(SIMPLE_NAME).setValue(
+ getSimpleName(sampleData[i]));
+ item.getItemProperty(REVERSE_FULLY_QUALIFIED_NAME).setValue(
+ reverse(sampleData[i]));
+ item.getItemProperty(ID_NUMBER).setValue(i % 2);
+ }
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/data/util/AbstractInMemoryContainerTest.java b/server/tests/src/com/vaadin/data/util/AbstractInMemoryContainerTest.java
new file mode 100644
index 0000000000..bbad33c5bc
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/AbstractInMemoryContainerTest.java
@@ -0,0 +1,6 @@
+package com.vaadin.data.util;
+
+public abstract class AbstractInMemoryContainerTest extends
+ AbstractContainerTest {
+
+}
diff --git a/server/tests/src/com/vaadin/data/util/BeanContainerTest.java b/server/tests/src/com/vaadin/data/util/BeanContainerTest.java
new file mode 100644
index 0000000000..9037e303a8
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/BeanContainerTest.java
@@ -0,0 +1,460 @@
+package com.vaadin.data.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import junit.framework.Assert;
+
+import com.vaadin.data.Container;
+import com.vaadin.data.Item;
+import com.vaadin.data.util.AbstractBeanContainer.BeanIdResolver;
+
+public class BeanContainerTest extends AbstractBeanContainerTest {
+
+ protected static class PersonNameResolver implements
+ BeanIdResolver<String, Person> {
+
+ @Override
+ public String getIdForBean(Person bean) {
+ return bean != null ? bean.getName() : null;
+ }
+
+ }
+
+ protected static class NullResolver implements
+ BeanIdResolver<String, Person> {
+
+ @Override
+ public String getIdForBean(Person bean) {
+ return null;
+ }
+
+ }
+
+ private Map<String, ClassName> nameToBean = new LinkedHashMap<String, ClassName>();
+
+ private BeanContainer<String, ClassName> getContainer() {
+ return new BeanContainer<String, ClassName>(ClassName.class);
+ }
+
+ @Override
+ public void setUp() {
+ nameToBean.clear();
+
+ for (int i = 0; i < sampleData.length; i++) {
+ ClassName className = new ClassName(sampleData[i], i);
+ nameToBean.put(sampleData[i], className);
+ }
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected void initializeContainer(Container container) {
+ BeanContainer<String, ClassName> beanItemContainer = (BeanContainer<String, ClassName>) container;
+
+ beanItemContainer.removeAllItems();
+
+ for (Entry<String, ClassName> entry : nameToBean.entrySet()) {
+ beanItemContainer.addItem(entry.getKey(), entry.getValue());
+ }
+ }
+
+ @Override
+ protected boolean isFilteredOutItemNull() {
+ return false;
+ }
+
+ public void testBasicOperations() {
+ testBasicContainerOperations(getContainer());
+ }
+
+ public void testFiltering() {
+ testContainerFiltering(getContainer());
+ }
+
+ public void testSorting() {
+ testContainerSorting(getContainer());
+ }
+
+ public void testSortingAndFiltering() {
+ testContainerSortingAndFiltering(getContainer());
+ }
+
+ // duplicated from parent class and modified - adding items to
+ // BeanContainer differs from other containers
+ public void testContainerOrdered() {
+ BeanContainer<String, String> container = new BeanContainer<String, String>(
+ String.class);
+
+ String id = "test1";
+
+ Item item = container.addItem(id, "value");
+ assertNotNull(item);
+
+ assertEquals(id, container.firstItemId());
+ assertEquals(id, container.lastItemId());
+
+ // isFirstId
+ assertTrue(container.isFirstId(id));
+ assertTrue(container.isFirstId(container.firstItemId()));
+ // isLastId
+ assertTrue(container.isLastId(id));
+ assertTrue(container.isLastId(container.lastItemId()));
+
+ // Add a new item before the first
+ // addItemAfter
+ String newFirstId = "newFirst";
+ item = container.addItemAfter(null, newFirstId, "newFirstValue");
+ assertNotNull(item);
+ assertNotNull(container.getItem(newFirstId));
+
+ // isFirstId
+ assertTrue(container.isFirstId(newFirstId));
+ assertTrue(container.isFirstId(container.firstItemId()));
+ // isLastId
+ assertTrue(container.isLastId(id));
+ assertTrue(container.isLastId(container.lastItemId()));
+
+ // nextItemId
+ assertEquals(id, container.nextItemId(newFirstId));
+ assertNull(container.nextItemId(id));
+ assertNull(container.nextItemId("not-in-container"));
+
+ // prevItemId
+ assertEquals(newFirstId, container.prevItemId(id));
+ assertNull(container.prevItemId(newFirstId));
+ assertNull(container.prevItemId("not-in-container"));
+
+ // addItemAfter(IDTYPE, IDTYPE, BT)
+ String newSecondItemId = "newSecond";
+ item = container.addItemAfter(newFirstId, newSecondItemId,
+ "newSecondValue");
+ // order is now: newFirstId, newSecondItemId, id
+ assertNotNull(item);
+ assertNotNull(container.getItem(newSecondItemId));
+ assertEquals(id, container.nextItemId(newSecondItemId));
+ assertEquals(newFirstId, container.prevItemId(newSecondItemId));
+
+ // addItemAfter(IDTYPE, IDTYPE, BT)
+ String fourthId = "id of the fourth item";
+ Item fourth = container.addItemAfter(newFirstId, fourthId,
+ "fourthValue");
+ // order is now: newFirstId, fourthId, newSecondItemId, id
+ assertNotNull(fourth);
+ assertEquals(fourth, container.getItem(fourthId));
+ assertEquals(newSecondItemId, container.nextItemId(fourthId));
+ assertEquals(newFirstId, container.prevItemId(fourthId));
+
+ // addItemAfter(IDTYPE, IDTYPE, BT)
+ String fifthId = "fifth";
+ Item fifth = container.addItemAfter(null, fifthId, "fifthValue");
+ // order is now: fifthId, newFirstId, fourthId, newSecondItemId, id
+ assertNotNull(fifth);
+ assertEquals(fifth, container.getItem(fifthId));
+ assertEquals(newFirstId, container.nextItemId(fifthId));
+ assertNull(container.prevItemId(fifthId));
+
+ }
+
+ // TODO test Container.Indexed interface operation - testContainerIndexed()?
+
+ public void testAddItemAt() {
+ BeanContainer<String, String> container = new BeanContainer<String, String>(
+ String.class);
+
+ container.addItem("id1", "value1");
+ // id1
+ container.addItemAt(0, "id2", "value2");
+ // id2, id1
+ container.addItemAt(1, "id3", "value3");
+ // id2, id3, id1
+ container.addItemAt(container.size(), "id4", "value4");
+ // id2, id3, id1, id4
+
+ assertNull(container.addItemAt(-1, "id5", "value5"));
+ assertNull(container.addItemAt(container.size() + 1, "id6", "value6"));
+
+ assertEquals(4, container.size());
+ assertEquals("id2", container.getIdByIndex(0));
+ assertEquals("id3", container.getIdByIndex(1));
+ assertEquals("id1", container.getIdByIndex(2));
+ assertEquals("id4", container.getIdByIndex(3));
+ }
+
+ public void testUnsupportedMethods() {
+ BeanContainer<String, Person> container = new BeanContainer<String, Person>(
+ Person.class);
+ container.addItem("John", new Person("John"));
+
+ try {
+ container.addItem();
+ Assert.fail();
+ } catch (UnsupportedOperationException e) {
+ // should get exception
+ }
+
+ try {
+ container.addItem(null);
+ Assert.fail();
+ } catch (UnsupportedOperationException e) {
+ // should get exception
+ }
+
+ try {
+ container.addItemAfter(null, null);
+ Assert.fail();
+ } catch (UnsupportedOperationException e) {
+ // should get exception
+ }
+
+ try {
+ container.addItemAfter(new Person("Jane"));
+ Assert.fail();
+ } catch (UnsupportedOperationException e) {
+ // should get exception
+ }
+
+ try {
+ container.addItemAt(0);
+ Assert.fail();
+ } catch (UnsupportedOperationException e) {
+ // should get exception
+ }
+
+ try {
+ container.addItemAt(0, new Person("Jane"));
+ Assert.fail();
+ } catch (UnsupportedOperationException e) {
+ // should get exception
+ }
+
+ try {
+ container.addContainerProperty("lastName", String.class, "");
+ Assert.fail();
+ } catch (UnsupportedOperationException e) {
+ // should get exception
+ }
+
+ assertEquals(1, container.size());
+ }
+
+ public void testRemoveContainerProperty() {
+ BeanContainer<String, Person> container = new BeanContainer<String, Person>(
+ Person.class);
+ container.setBeanIdResolver(new PersonNameResolver());
+ container.addBean(new Person("John"));
+
+ Assert.assertEquals("John",
+ container.getContainerProperty("John", "name").getValue());
+ Assert.assertTrue(container.removeContainerProperty("name"));
+ Assert.assertNull(container.getContainerProperty("John", "name"));
+
+ Assert.assertNotNull(container.getItem("John"));
+ // property removed also from item
+ Assert.assertNull(container.getItem("John").getItemProperty("name"));
+ }
+
+ public void testAddNullBeans() {
+ BeanContainer<String, Person> container = new BeanContainer<String, Person>(
+ Person.class);
+
+ assertNull(container.addItem("id1", null));
+ assertNull(container.addItemAfter(null, "id2", null));
+ assertNull(container.addItemAt(0, "id3", null));
+
+ assertEquals(0, container.size());
+ }
+
+ public void testAddNullId() {
+ BeanContainer<String, Person> container = new BeanContainer<String, Person>(
+ Person.class);
+
+ Person john = new Person("John");
+
+ assertNull(container.addItem(null, john));
+ assertNull(container.addItemAfter(null, null, john));
+ assertNull(container.addItemAt(0, null, john));
+
+ assertEquals(0, container.size());
+ }
+
+ public void testEmptyContainer() {
+ BeanContainer<String, Person> container = new BeanContainer<String, Person>(
+ Person.class);
+
+ assertNull(container.firstItemId());
+ assertNull(container.lastItemId());
+
+ assertEquals(0, container.size());
+
+ // could test more about empty container
+ }
+
+ public void testAddBeanWithoutResolver() {
+ BeanContainer<String, Person> container = new BeanContainer<String, Person>(
+ Person.class);
+
+ try {
+ container.addBean(new Person("John"));
+ Assert.fail();
+ } catch (IllegalStateException e) {
+ // should get exception
+ }
+ try {
+ container.addBeanAfter(null, new Person("Jane"));
+ Assert.fail();
+ } catch (IllegalStateException e) {
+ // should get exception
+ }
+ try {
+ container.addBeanAt(0, new Person("Jack"));
+ Assert.fail();
+ } catch (IllegalStateException e) {
+ // should get exception
+ }
+ try {
+ container
+ .addAll(Arrays.asList(new Person[] { new Person("Jack") }));
+ Assert.fail();
+ } catch (IllegalStateException e) {
+ // should get exception
+ }
+
+ assertEquals(0, container.size());
+ }
+
+ public void testAddAllWithNullItemId() {
+ BeanContainer<String, Person> container = new BeanContainer<String, Person>(
+ Person.class);
+ // resolver that returns null as item id
+ container
+ .setBeanIdResolver(new BeanIdResolver<String, AbstractBeanContainerTest.Person>() {
+
+ @Override
+ public String getIdForBean(Person bean) {
+ return bean.getName();
+ }
+ });
+
+ List<Person> persons = new ArrayList<Person>();
+ persons.add(new Person("John"));
+ persons.add(new Person("Marc"));
+ persons.add(new Person(null));
+ persons.add(new Person("foo"));
+
+ try {
+ container.addAll(persons);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // should get exception
+ }
+
+ container.removeAllItems();
+ persons.remove(2);
+ container.addAll(persons);
+ assertEquals(3, container.size());
+ }
+
+ public void testAddBeanWithNullResolver() {
+ BeanContainer<String, Person> container = new BeanContainer<String, Person>(
+ Person.class);
+ // resolver that returns null as item id
+ container.setBeanIdResolver(new NullResolver());
+
+ try {
+ container.addBean(new Person("John"));
+ Assert.fail();
+ } catch (IllegalArgumentException e) {
+ // should get exception
+ }
+ try {
+ container.addBeanAfter(null, new Person("Jane"));
+ Assert.fail();
+ } catch (IllegalArgumentException e) {
+ // should get exception
+ }
+ try {
+ container.addBeanAt(0, new Person("Jack"));
+ Assert.fail();
+ } catch (IllegalArgumentException e) {
+ // should get exception
+ }
+
+ assertEquals(0, container.size());
+ }
+
+ public void testAddBeanWithResolver() {
+ BeanContainer<String, Person> container = new BeanContainer<String, Person>(
+ Person.class);
+ container.setBeanIdResolver(new PersonNameResolver());
+
+ assertNotNull(container.addBean(new Person("John")));
+ assertNotNull(container.addBeanAfter(null, new Person("Jane")));
+ assertNotNull(container.addBeanAt(0, new Person("Jack")));
+
+ container.addAll(Arrays.asList(new Person[] { new Person("Jill"),
+ new Person("Joe") }));
+
+ assertTrue(container.containsId("John"));
+ assertTrue(container.containsId("Jane"));
+ assertTrue(container.containsId("Jack"));
+ assertTrue(container.containsId("Jill"));
+ assertTrue(container.containsId("Joe"));
+ assertEquals(3, container.indexOfId("Jill"));
+ assertEquals(4, container.indexOfId("Joe"));
+ assertEquals(5, container.size());
+ }
+
+ public void testAddNullBeansWithResolver() {
+ BeanContainer<String, Person> container = new BeanContainer<String, Person>(
+ Person.class);
+ container.setBeanIdResolver(new PersonNameResolver());
+
+ assertNull(container.addBean(null));
+ assertNull(container.addBeanAfter(null, null));
+ assertNull(container.addBeanAt(0, null));
+
+ assertEquals(0, container.size());
+ }
+
+ public void testAddBeanWithPropertyResolver() {
+ BeanContainer<String, Person> container = new BeanContainer<String, Person>(
+ Person.class);
+ container.setBeanIdProperty("name");
+
+ assertNotNull(container.addBean(new Person("John")));
+ assertNotNull(container.addBeanAfter(null, new Person("Jane")));
+ assertNotNull(container.addBeanAt(0, new Person("Jack")));
+
+ container.addAll(Arrays.asList(new Person[] { new Person("Jill"),
+ new Person("Joe") }));
+
+ assertTrue(container.containsId("John"));
+ assertTrue(container.containsId("Jane"));
+ assertTrue(container.containsId("Jack"));
+ assertTrue(container.containsId("Jill"));
+ assertTrue(container.containsId("Joe"));
+ assertEquals(3, container.indexOfId("Jill"));
+ assertEquals(4, container.indexOfId("Joe"));
+ assertEquals(5, container.size());
+ }
+
+ public void testAddNestedContainerProperty() {
+ BeanContainer<String, NestedMethodPropertyTest.Person> container = new BeanContainer<String, NestedMethodPropertyTest.Person>(
+ NestedMethodPropertyTest.Person.class);
+ container.setBeanIdProperty("name");
+
+ container.addBean(new NestedMethodPropertyTest.Person("John",
+ new NestedMethodPropertyTest.Address("Ruukinkatu 2-4", 20540)));
+
+ assertTrue(container.addNestedContainerProperty("address.street"));
+ assertEquals("Ruukinkatu 2-4",
+ container.getContainerProperty("John", "address.street")
+ .getValue());
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/data/util/BeanItemContainerSortTest.java b/server/tests/src/com/vaadin/data/util/BeanItemContainerSortTest.java
new file mode 100644
index 0000000000..38f317fef1
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/BeanItemContainerSortTest.java
@@ -0,0 +1,170 @@
+package com.vaadin.data.util;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+import com.vaadin.data.util.BeanItemContainer;
+import com.vaadin.data.util.DefaultItemSorter;
+
+public class BeanItemContainerSortTest {
+ public class Person {
+ private String name;
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ private int age;
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+ }
+
+ public class Parent extends Person {
+ private Set<Person> children = new HashSet<Person>();
+
+ public void setChildren(Set<Person> children) {
+ this.children = children;
+ }
+
+ public Set<Person> getChildren() {
+ return children;
+ }
+ }
+
+ String[] names = new String[] { "Antti", "Ville", "Sirkka", "Jaakko",
+ "Pekka", "John" };
+ int[] ages = new int[] { 10, 20, 50, 12, 64, 67 };
+ String[] sortedByAge = new String[] { names[0], names[3], names[1],
+ names[2], names[4], names[5] };
+
+ public BeanItemContainer<Person> getContainer() {
+ BeanItemContainer<Person> bc = new BeanItemContainer<Person>(
+ Person.class);
+ for (int i = 0; i < names.length; i++) {
+ Person p = new Person();
+ p.setName(names[i]);
+ p.setAge(ages[i]);
+ bc.addBean(p);
+ }
+ return bc;
+
+ }
+
+ public BeanItemContainer<Parent> getParentContainer() {
+ BeanItemContainer<Parent> bc = new BeanItemContainer<Parent>(
+ Parent.class);
+ for (int i = 0; i < names.length; i++) {
+ Parent p = new Parent();
+ p.setName(names[i]);
+ p.setAge(ages[i]);
+ bc.addBean(p);
+ }
+ return bc;
+ }
+
+ @Test
+ public void testSort() {
+ testSort(true);
+ }
+
+ public void testSort(boolean b) {
+ BeanItemContainer<Person> container = getContainer();
+ container.sort(new Object[] { "name" }, new boolean[] { b });
+
+ List<String> asList = Arrays.asList(names);
+ Collections.sort(asList);
+ if (!b) {
+ Collections.reverse(asList);
+ }
+
+ int i = 0;
+ for (String string : asList) {
+ Person idByIndex = container.getIdByIndex(i++);
+ Assert.assertTrue(container.containsId(idByIndex));
+ Assert.assertEquals(string, idByIndex.getName());
+ }
+ }
+
+ @Test
+ public void testReverseSort() {
+ testSort(false);
+ }
+
+ @Test
+ public void primitiveSorting() {
+ BeanItemContainer<Person> container = getContainer();
+ container.sort(new Object[] { "age" }, new boolean[] { true });
+
+ int i = 0;
+ for (String string : sortedByAge) {
+ Person idByIndex = container.getIdByIndex(i++);
+ Assert.assertTrue(container.containsId(idByIndex));
+ Assert.assertEquals(string, idByIndex.getName());
+ }
+ }
+
+ @Test
+ public void customSorting() {
+ BeanItemContainer<Person> container = getContainer();
+
+ // custom sorter using the reverse order
+ container.setItemSorter(new DefaultItemSorter() {
+ @Override
+ public int compare(Object o1, Object o2) {
+ return -super.compare(o1, o2);
+ }
+ });
+
+ container.sort(new Object[] { "age" }, new boolean[] { true });
+
+ int i = container.size() - 1;
+ for (String string : sortedByAge) {
+ Person idByIndex = container.getIdByIndex(i--);
+ Assert.assertTrue(container.containsId(idByIndex));
+ Assert.assertEquals(string, idByIndex.getName());
+ }
+ }
+
+ @Test
+ public void testGetSortableProperties() {
+ BeanItemContainer<Person> container = getContainer();
+
+ Collection<?> sortablePropertyIds = container
+ .getSortableContainerPropertyIds();
+ Assert.assertEquals(2, sortablePropertyIds.size());
+ Assert.assertTrue(sortablePropertyIds.contains("name"));
+ Assert.assertTrue(sortablePropertyIds.contains("age"));
+ }
+
+ @Test
+ public void testGetNonSortableProperties() {
+ BeanItemContainer<Parent> container = getParentContainer();
+
+ Assert.assertEquals(3, container.getContainerPropertyIds().size());
+
+ Collection<?> sortablePropertyIds = container
+ .getSortableContainerPropertyIds();
+ Assert.assertEquals(2, sortablePropertyIds.size());
+ Assert.assertTrue(sortablePropertyIds.contains("name"));
+ Assert.assertTrue(sortablePropertyIds.contains("age"));
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/data/util/BeanItemContainerTest.java b/server/tests/src/com/vaadin/data/util/BeanItemContainerTest.java
new file mode 100644
index 0000000000..29043b1670
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/BeanItemContainerTest.java
@@ -0,0 +1,718 @@
+package com.vaadin.data.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.Assert;
+
+import com.vaadin.data.Container;
+import com.vaadin.data.Item;
+import com.vaadin.data.util.BeanItemContainer;
+
+/**
+ * Test basic functionality of BeanItemContainer.
+ *
+ * Most sorting related tests are in {@link BeanItemContainerSortTest}.
+ */
+public class BeanItemContainerTest extends AbstractBeanContainerTest {
+
+ // basics from the common container test
+
+ private Map<String, ClassName> nameToBean = new LinkedHashMap<String, ClassName>();
+
+ private BeanItemContainer<ClassName> getContainer() {
+ return new BeanItemContainer<ClassName>(ClassName.class);
+ }
+
+ @Override
+ public void setUp() {
+ nameToBean.clear();
+
+ for (int i = 0; i < sampleData.length; i++) {
+ ClassName className = new ClassName(sampleData[i], i);
+ nameToBean.put(sampleData[i], className);
+ }
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected void initializeContainer(Container container) {
+ BeanItemContainer<ClassName> beanItemContainer = (BeanItemContainer<ClassName>) container;
+
+ beanItemContainer.removeAllItems();
+
+ Iterator<ClassName> it = nameToBean.values().iterator();
+ while (it.hasNext()) {
+ beanItemContainer.addBean(it.next());
+ }
+ }
+
+ @Override
+ protected void validateContainer(Container container,
+ Object expectedFirstItemId, Object expectedLastItemId,
+ Object itemIdInSet, Object itemIdNotInSet,
+ boolean checkGetItemNull, int expectedSize) {
+ Object notInSet = nameToBean.get(itemIdNotInSet);
+ if (notInSet == null && itemIdNotInSet != null) {
+ notInSet = new ClassName(String.valueOf(itemIdNotInSet), 9999);
+ }
+ super.validateContainer(container, nameToBean.get(expectedFirstItemId),
+ nameToBean.get(expectedLastItemId),
+ nameToBean.get(itemIdInSet), notInSet, checkGetItemNull,
+ expectedSize);
+ }
+
+ @Override
+ protected boolean isFilteredOutItemNull() {
+ return false;
+ }
+
+ public void testBasicOperations() {
+ testBasicContainerOperations(getContainer());
+ }
+
+ public void testFiltering() {
+ testContainerFiltering(getContainer());
+ }
+
+ public void testSorting() {
+ testContainerSorting(getContainer());
+ }
+
+ public void testSortingAndFiltering() {
+ testContainerSortingAndFiltering(getContainer());
+ }
+
+ // duplicated from parent class and modified - adding items to
+ // BeanItemContainer differs from other containers
+ public void testContainerOrdered() {
+ BeanItemContainer<String> container = new BeanItemContainer<String>(
+ String.class);
+
+ String id = "test1";
+
+ Item item = container.addBean(id);
+ assertNotNull(item);
+
+ assertEquals(id, container.firstItemId());
+ assertEquals(id, container.lastItemId());
+
+ // isFirstId
+ assertTrue(container.isFirstId(id));
+ assertTrue(container.isFirstId(container.firstItemId()));
+ // isLastId
+ assertTrue(container.isLastId(id));
+ assertTrue(container.isLastId(container.lastItemId()));
+
+ // Add a new item before the first
+ // addItemAfter
+ String newFirstId = "newFirst";
+ item = container.addItemAfter(null, newFirstId);
+ assertNotNull(item);
+ assertNotNull(container.getItem(newFirstId));
+
+ // isFirstId
+ assertTrue(container.isFirstId(newFirstId));
+ assertTrue(container.isFirstId(container.firstItemId()));
+ // isLastId
+ assertTrue(container.isLastId(id));
+ assertTrue(container.isLastId(container.lastItemId()));
+
+ // nextItemId
+ assertEquals(id, container.nextItemId(newFirstId));
+ assertNull(container.nextItemId(id));
+ assertNull(container.nextItemId("not-in-container"));
+
+ // prevItemId
+ assertEquals(newFirstId, container.prevItemId(id));
+ assertNull(container.prevItemId(newFirstId));
+ assertNull(container.prevItemId("not-in-container"));
+
+ // addItemAfter(Object)
+ String newSecondItemId = "newSecond";
+ item = container.addItemAfter(newFirstId, newSecondItemId);
+ // order is now: newFirstId, newSecondItemId, id
+ assertNotNull(item);
+ assertNotNull(container.getItem(newSecondItemId));
+ assertEquals(id, container.nextItemId(newSecondItemId));
+ assertEquals(newFirstId, container.prevItemId(newSecondItemId));
+
+ // addItemAfter(Object,Object)
+ String fourthId = "id of the fourth item";
+ Item fourth = container.addItemAfter(newFirstId, fourthId);
+ // order is now: newFirstId, fourthId, newSecondItemId, id
+ assertNotNull(fourth);
+ assertEquals(fourth, container.getItem(fourthId));
+ assertEquals(newSecondItemId, container.nextItemId(fourthId));
+ assertEquals(newFirstId, container.prevItemId(fourthId));
+
+ // addItemAfter(Object,Object)
+ Object fifthId = "fifth";
+ Item fifth = container.addItemAfter(null, fifthId);
+ // order is now: fifthId, newFirstId, fourthId, newSecondItemId, id
+ assertNotNull(fifth);
+ assertEquals(fifth, container.getItem(fifthId));
+ assertEquals(newFirstId, container.nextItemId(fifthId));
+ assertNull(container.prevItemId(fifthId));
+
+ }
+
+ public void testContainerIndexed() {
+ testContainerIndexed(getContainer(), nameToBean.get(sampleData[2]), 2,
+ false, new ClassName("org.vaadin.test.Test", 8888), true);
+ }
+
+ @SuppressWarnings("deprecation")
+ public void testCollectionConstructors() {
+ List<ClassName> classNames = new ArrayList<ClassName>();
+ classNames.add(new ClassName("a.b.c.Def", 1));
+ classNames.add(new ClassName("a.b.c.Fed", 2));
+ classNames.add(new ClassName("b.c.d.Def", 3));
+
+ // note that this constructor is problematic, users should use the
+ // version that
+ // takes the bean class as a parameter
+ BeanItemContainer<ClassName> container = new BeanItemContainer<ClassName>(
+ classNames);
+
+ Assert.assertEquals(3, container.size());
+ Assert.assertEquals(classNames.get(0), container.firstItemId());
+ Assert.assertEquals(classNames.get(1), container.getIdByIndex(1));
+ Assert.assertEquals(classNames.get(2), container.lastItemId());
+
+ BeanItemContainer<ClassName> container2 = new BeanItemContainer<ClassName>(
+ ClassName.class, classNames);
+
+ Assert.assertEquals(3, container2.size());
+ Assert.assertEquals(classNames.get(0), container2.firstItemId());
+ Assert.assertEquals(classNames.get(1), container2.getIdByIndex(1));
+ Assert.assertEquals(classNames.get(2), container2.lastItemId());
+ }
+
+ // this only applies to the collection constructor with no type parameter
+ @SuppressWarnings("deprecation")
+ public void testEmptyCollectionConstructor() {
+ try {
+ new BeanItemContainer<ClassName>((Collection<ClassName>) null);
+ Assert.fail("Initializing BeanItemContainer from a null collection should not work!");
+ } catch (IllegalArgumentException e) {
+ // success
+ }
+ try {
+ new BeanItemContainer<ClassName>(new ArrayList<ClassName>());
+ Assert.fail("Initializing BeanItemContainer from an empty collection should not work!");
+ } catch (IllegalArgumentException e) {
+ // success
+ }
+ }
+
+ public void testItemSetChangeListeners() {
+ BeanItemContainer<ClassName> container = getContainer();
+ ItemSetChangeCounter counter = new ItemSetChangeCounter();
+ container.addListener(counter);
+
+ ClassName cn1 = new ClassName("com.example.Test", 1111);
+ ClassName cn2 = new ClassName("com.example.Test2", 2222);
+
+ initializeContainer(container);
+ counter.reset();
+ container.addBean(cn1);
+ counter.assertOnce();
+
+ initializeContainer(container);
+ counter.reset();
+ container.addItem(cn1);
+ counter.assertOnce();
+ // no notification if already in container
+ container.addItem(cn1);
+ counter.assertNone();
+ container.addItem(cn2);
+ counter.assertOnce();
+
+ initializeContainer(container);
+ counter.reset();
+ container.addItemAfter(null, cn1);
+ counter.assertOnce();
+ Assert.assertEquals(
+ "com.example.Test",
+ container.getContainerProperty(container.firstItemId(),
+ FULLY_QUALIFIED_NAME).getValue());
+
+ initializeContainer(container);
+ counter.reset();
+ container.addItemAfter(container.firstItemId(), cn1);
+ counter.assertOnce();
+ Assert.assertEquals(
+ "com.example.Test",
+ container.getContainerProperty(container.getIdByIndex(1),
+ FULLY_QUALIFIED_NAME).getValue());
+
+ initializeContainer(container);
+ counter.reset();
+ container.addItemAfter(container.lastItemId(), cn1);
+ counter.assertOnce();
+ Assert.assertEquals(
+ "com.example.Test",
+ container.getContainerProperty(container.lastItemId(),
+ FULLY_QUALIFIED_NAME).getValue());
+
+ initializeContainer(container);
+ counter.reset();
+ container.addItemAt(0, cn1);
+ counter.assertOnce();
+ Assert.assertEquals(
+ "com.example.Test",
+ container.getContainerProperty(container.firstItemId(),
+ FULLY_QUALIFIED_NAME).getValue());
+
+ initializeContainer(container);
+ counter.reset();
+ container.addItemAt(1, cn1);
+ counter.assertOnce();
+ Assert.assertEquals(
+ "com.example.Test",
+ container.getContainerProperty(container.getIdByIndex(1),
+ FULLY_QUALIFIED_NAME).getValue());
+
+ initializeContainer(container);
+ counter.reset();
+ container.addItemAt(container.size(), cn1);
+ counter.assertOnce();
+ Assert.assertEquals(
+ "com.example.Test",
+ container.getContainerProperty(container.lastItemId(),
+ FULLY_QUALIFIED_NAME).getValue());
+
+ initializeContainer(container);
+ counter.reset();
+ container.removeItem(nameToBean.get(sampleData[0]));
+ counter.assertOnce();
+
+ initializeContainer(container);
+ counter.reset();
+ // no notification for removing a non-existing item
+ container.removeItem(cn1);
+ counter.assertNone();
+
+ initializeContainer(container);
+ counter.reset();
+ container.removeAllItems();
+ counter.assertOnce();
+ // already empty
+ container.removeAllItems();
+ counter.assertNone();
+
+ }
+
+ public void testItemSetChangeListenersFiltering() {
+ BeanItemContainer<ClassName> container = getContainer();
+ ItemSetChangeCounter counter = new ItemSetChangeCounter();
+ container.addListener(counter);
+
+ ClassName cn1 = new ClassName("com.example.Test", 1111);
+ ClassName cn2 = new ClassName("com.example.Test2", 2222);
+ ClassName other = new ClassName("com.example.Other", 3333);
+
+ // simply adding or removing container filters should cause event
+ // (content changes)
+
+ initializeContainer(container);
+ counter.reset();
+ container.addContainerFilter(SIMPLE_NAME, "a", true, false);
+ counter.assertOnce();
+ container.removeContainerFilters(SIMPLE_NAME);
+ counter.assertOnce();
+
+ initializeContainer(container);
+ counter.reset();
+ container.addContainerFilter(SIMPLE_NAME, "a", true, false);
+ counter.assertOnce();
+ container.removeAllContainerFilters();
+ counter.assertOnce();
+
+ // perform operations while filtering container
+
+ initializeContainer(container);
+ counter.reset();
+ container.addContainerFilter(FULLY_QUALIFIED_NAME, "Test", true, false);
+ counter.assertOnce();
+
+ // passes filter
+ container.addBean(cn1);
+ counter.assertOnce();
+
+ // passes filter but already in the container
+ container.addBean(cn1);
+ counter.assertNone();
+
+ initializeContainer(container);
+ counter.reset();
+
+ // passes filter
+ container.addItem(cn1);
+ counter.assertOnce();
+ // already in the container
+ container.addItem(cn1);
+ counter.assertNone();
+ container.addItem(cn2);
+ counter.assertOnce();
+ // does not pass filter
+ container.addItem(other);
+ counter.assertNone();
+
+ initializeContainer(container);
+ counter.reset();
+ container.addItemAfter(null, cn1);
+ counter.assertOnce();
+ Assert.assertEquals(
+ "com.example.Test",
+ container.getContainerProperty(container.firstItemId(),
+ FULLY_QUALIFIED_NAME).getValue());
+
+ initializeContainer(container);
+ counter.reset();
+ container.addItemAfter(container.firstItemId(), cn1);
+ counter.assertOnce();
+ Assert.assertEquals(
+ "com.example.Test",
+ container.getContainerProperty(container.getIdByIndex(1),
+ FULLY_QUALIFIED_NAME).getValue());
+
+ initializeContainer(container);
+ counter.reset();
+ container.addItemAfter(container.lastItemId(), cn1);
+ counter.assertOnce();
+ Assert.assertEquals(
+ "com.example.Test",
+ container.getContainerProperty(container.lastItemId(),
+ FULLY_QUALIFIED_NAME).getValue());
+
+ initializeContainer(container);
+ counter.reset();
+ container.addItemAt(0, cn1);
+ counter.assertOnce();
+ Assert.assertEquals(
+ "com.example.Test",
+ container.getContainerProperty(container.firstItemId(),
+ FULLY_QUALIFIED_NAME).getValue());
+
+ initializeContainer(container);
+ counter.reset();
+ container.addItemAt(1, cn1);
+ counter.assertOnce();
+ Assert.assertEquals(
+ "com.example.Test",
+ container.getContainerProperty(container.getIdByIndex(1),
+ FULLY_QUALIFIED_NAME).getValue());
+
+ initializeContainer(container);
+ counter.reset();
+ container.addItemAt(container.size(), cn1);
+ counter.assertOnce();
+ Assert.assertEquals(
+ "com.example.Test",
+ container.getContainerProperty(container.lastItemId(),
+ FULLY_QUALIFIED_NAME).getValue());
+
+ // does not pass filter
+ // note: testAddRemoveWhileFiltering() checks position for these after
+ // removing filter etc, here concentrating on listeners
+
+ initializeContainer(container);
+ counter.reset();
+ container.addItemAfter(null, other);
+ counter.assertNone();
+
+ initializeContainer(container);
+ counter.reset();
+ container.addItemAfter(container.firstItemId(), other);
+ counter.assertNone();
+
+ initializeContainer(container);
+ counter.reset();
+ container.addItemAfter(container.lastItemId(), other);
+ counter.assertNone();
+
+ initializeContainer(container);
+ counter.reset();
+ container.addItemAt(0, other);
+ counter.assertNone();
+
+ initializeContainer(container);
+ counter.reset();
+ container.addItemAt(1, other);
+ counter.assertNone();
+
+ initializeContainer(container);
+ counter.reset();
+ container.addItemAt(container.size(), other);
+ counter.assertNone();
+
+ // passes filter
+
+ initializeContainer(container);
+ counter.reset();
+ container.addItem(cn1);
+ counter.assertOnce();
+ container.removeItem(cn1);
+ counter.assertOnce();
+
+ // does not pass filter
+
+ initializeContainer(container);
+ counter.reset();
+ // not visible
+ container.removeItem(nameToBean.get(sampleData[0]));
+ counter.assertNone();
+
+ container.removeAllItems();
+ counter.assertOnce();
+ // no visible items
+ container.removeAllItems();
+ counter.assertNone();
+ }
+
+ public void testAddRemoveWhileFiltering() {
+ BeanItemContainer<Person> container = new BeanItemContainer<Person>(
+ Person.class);
+
+ Person john = new Person("John");
+ Person jane = new Person("Jane");
+ Person matthew = new Person("Matthew");
+
+ Person jack = new Person("Jack");
+ Person michael = new Person("Michael");
+ Person william = new Person("William");
+ Person julia = new Person("Julia");
+ Person george = new Person("George");
+ Person mark = new Person("Mark");
+
+ container.addBean(john);
+ container.addBean(jane);
+ container.addBean(matthew);
+
+ assertEquals(3, container.size());
+ // john, jane, matthew
+
+ container.addContainerFilter("name", "j", true, true);
+
+ assertEquals(2, container.size());
+ // john, jane, (matthew)
+
+ // add a bean that passes the filter
+ container.addBean(jack);
+ assertEquals(3, container.size());
+ assertEquals(jack, container.lastItemId());
+ // john, jane, (matthew), jack
+
+ // add beans that do not pass the filter
+ container.addBean(michael);
+ // john, jane, (matthew), jack, (michael)
+ container.addItemAfter(null, william);
+ // (william), john, jane, (matthew), jack, (michael)
+
+ // add after an item that is shown
+ container.addItemAfter(john, george);
+ // (william), john, (george), jane, (matthew), jack, (michael)
+ assertEquals(3, container.size());
+ assertEquals(john, container.firstItemId());
+
+ // add after an item that is not shown does nothing
+ container.addItemAfter(william, julia);
+ // (william), john, (george), jane, (matthew), jack, (michael)
+ assertEquals(3, container.size());
+ assertEquals(john, container.firstItemId());
+
+ container.addItemAt(1, julia);
+ // (william), john, julia, (george), jane, (matthew), jack, (michael)
+
+ container.addItemAt(2, mark);
+ // (william), john, julia, (mark), (george), jane, (matthew), jack,
+ // (michael)
+
+ container.removeItem(matthew);
+ // (william), john, julia, (mark), (george), jane, jack, (michael)
+
+ assertEquals(4, container.size());
+ assertEquals(jack, container.lastItemId());
+
+ container.removeContainerFilters("name");
+
+ assertEquals(8, container.size());
+ assertEquals(william, container.firstItemId());
+ assertEquals(john, container.nextItemId(william));
+ assertEquals(julia, container.nextItemId(john));
+ assertEquals(mark, container.nextItemId(julia));
+ assertEquals(george, container.nextItemId(mark));
+ assertEquals(jane, container.nextItemId(george));
+ assertEquals(jack, container.nextItemId(jane));
+ assertEquals(michael, container.lastItemId());
+ }
+
+ public void testRefilterOnPropertyModification() {
+ BeanItemContainer<Person> container = new BeanItemContainer<Person>(
+ Person.class);
+
+ Person john = new Person("John");
+ Person jane = new Person("Jane");
+ Person matthew = new Person("Matthew");
+
+ container.addBean(john);
+ container.addBean(jane);
+ container.addBean(matthew);
+
+ assertEquals(3, container.size());
+ // john, jane, matthew
+
+ container.addContainerFilter("name", "j", true, true);
+
+ assertEquals(2, container.size());
+ // john, jane, (matthew)
+
+ // #6053 currently, modification of an item that is not visible does not
+ // trigger refiltering - should it?
+ // matthew.setName("Julia");
+ // assertEquals(3, container.size());
+ // john, jane, julia
+
+ john.setName("Mark");
+ assertEquals(2, container.size());
+ // (mark), jane, julia
+
+ container.removeAllContainerFilters();
+
+ assertEquals(3, container.size());
+ }
+
+ public void testAddAll() {
+ BeanItemContainer<Person> container = new BeanItemContainer<Person>(
+ Person.class);
+
+ Person john = new Person("John");
+ Person jane = new Person("Jane");
+ Person matthew = new Person("Matthew");
+
+ container.addBean(john);
+ container.addBean(jane);
+ container.addBean(matthew);
+
+ assertEquals(3, container.size());
+ // john, jane, matthew
+
+ Person jack = new Person("Jack");
+ Person michael = new Person("Michael");
+
+ // addAll
+ container.addAll(Arrays.asList(jack, michael));
+ // john, jane, matthew, jack, michael
+
+ assertEquals(5, container.size());
+ assertEquals(jane, container.nextItemId(john));
+ assertEquals(matthew, container.nextItemId(jane));
+ assertEquals(jack, container.nextItemId(matthew));
+ assertEquals(michael, container.nextItemId(jack));
+ }
+
+ public void testUnsupportedMethods() {
+ BeanItemContainer<Person> container = new BeanItemContainer<Person>(
+ Person.class);
+ container.addBean(new Person("John"));
+
+ try {
+ container.addItem();
+ Assert.fail();
+ } catch (UnsupportedOperationException e) {
+ // should get exception
+ }
+
+ try {
+ container.addItemAfter(new Person("Jane"));
+ Assert.fail();
+ } catch (UnsupportedOperationException e) {
+ // should get exception
+ }
+
+ try {
+ container.addItemAt(0);
+ Assert.fail();
+ } catch (UnsupportedOperationException e) {
+ // should get exception
+ }
+
+ try {
+ container.addContainerProperty("lastName", String.class, "");
+ Assert.fail();
+ } catch (UnsupportedOperationException e) {
+ // should get exception
+ }
+
+ assertEquals(1, container.size());
+ }
+
+ public void testRemoveContainerProperty() {
+ BeanItemContainer<Person> container = new BeanItemContainer<Person>(
+ Person.class);
+ Person john = new Person("John");
+ container.addBean(john);
+
+ Assert.assertEquals("John", container
+ .getContainerProperty(john, "name").getValue());
+ Assert.assertTrue(container.removeContainerProperty("name"));
+ Assert.assertNull(container.getContainerProperty(john, "name"));
+
+ Assert.assertNotNull(container.getItem(john));
+ // property removed also from item
+ Assert.assertNull(container.getItem(john).getItemProperty("name"));
+ }
+
+ public void testAddNullBean() {
+ BeanItemContainer<Person> container = new BeanItemContainer<Person>(
+ Person.class);
+ Person john = new Person("John");
+ container.addBean(john);
+
+ assertNull(container.addItem(null));
+ assertNull(container.addItemAfter(null, null));
+ assertNull(container.addItemAfter(john, null));
+ assertNull(container.addItemAt(0, null));
+
+ assertEquals(1, container.size());
+ }
+
+ public void testBeanIdResolver() {
+ BeanItemContainer<Person> container = new BeanItemContainer<Person>(
+ Person.class);
+ Person john = new Person("John");
+
+ assertSame(john, container.getBeanIdResolver().getIdForBean(john));
+ }
+
+ public void testNullBeanClass() {
+ try {
+ new BeanItemContainer<Object>((Class<Object>) null);
+ } catch (IllegalArgumentException e) {
+ // should get exception
+ }
+ }
+
+ public void testAddNestedContainerProperty() {
+ BeanItemContainer<NestedMethodPropertyTest.Person> container = new BeanItemContainer<NestedMethodPropertyTest.Person>(
+ NestedMethodPropertyTest.Person.class);
+
+ NestedMethodPropertyTest.Person john = new NestedMethodPropertyTest.Person(
+ "John", new NestedMethodPropertyTest.Address("Ruukinkatu 2-4",
+ 20540));
+ container.addBean(john);
+
+ assertTrue(container.addNestedContainerProperty("address.street"));
+ assertEquals("Ruukinkatu 2-4",
+ container.getContainerProperty(john, "address.street")
+ .getValue());
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/data/util/BeanItemTest.java b/server/tests/src/com/vaadin/data/util/BeanItemTest.java
new file mode 100644
index 0000000000..e1ad75796c
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/BeanItemTest.java
@@ -0,0 +1,333 @@
+package com.vaadin.data.util;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+/**
+ * Test BeanItem specific features.
+ *
+ * Only public API is tested, not the methods with package visibility.
+ *
+ * See also {@link PropertySetItemTest}, which tests the base class.
+ */
+public class BeanItemTest extends TestCase {
+
+ @SuppressWarnings("unused")
+ protected static class MySuperClass {
+ private int superPrivate = 1;
+ private int superPrivate2 = 2;
+ protected double superProtected = 3.0;
+ private double superProtected2 = 4.0;
+ public boolean superPublic = true;
+ private boolean superPublic2 = true;
+
+ public int getSuperPrivate() {
+ return superPrivate;
+ }
+
+ public void setSuperPrivate(int superPrivate) {
+ this.superPrivate = superPrivate;
+ }
+
+ public double getSuperProtected() {
+ return superProtected;
+ }
+
+ public void setSuperProtected(double superProtected) {
+ this.superProtected = superProtected;
+ }
+
+ public boolean isSuperPublic() {
+ return superPublic;
+ }
+
+ public void setSuperPublic(boolean superPublic) {
+ this.superPublic = superPublic;
+ }
+
+ }
+
+ protected static class MyClass extends MySuperClass {
+ private String name;
+ public int value = 123;
+
+ public MyClass(String name) {
+ this.name = name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setNoField(String name) {
+ }
+
+ public String getNoField() {
+ return "no field backing this setter";
+ }
+
+ public String getName2() {
+ return name;
+ }
+ }
+
+ protected static class MyClass2 extends MyClass {
+ public MyClass2(String name) {
+ super(name);
+ }
+
+ @Override
+ public void setName(String name) {
+ super.setName(name + "2");
+ }
+
+ @Override
+ public String getName() {
+ return super.getName() + "2";
+ }
+
+ @Override
+ public String getName2() {
+ return super.getName();
+ }
+
+ public void setName2(String name) {
+ super.setName(name);
+ }
+ }
+
+ protected static interface MySuperInterface {
+ public int getSuper1();
+
+ public void setSuper1(int i);
+
+ public int getOverride();
+ }
+
+ protected static interface MySuperInterface2 {
+ public int getSuper2();
+ }
+
+ protected static interface MySubInterface extends MySuperInterface,
+ MySuperInterface2 {
+ public int getSub();
+
+ public void setSub(int i);
+
+ @Override
+ public int getOverride();
+
+ public void setOverride(int i);
+ }
+
+ public void testGetProperties() {
+ BeanItem<MySuperClass> item = new BeanItem<MySuperClass>(
+ new MySuperClass());
+
+ Collection<?> itemPropertyIds = item.getItemPropertyIds();
+ Assert.assertEquals(3, itemPropertyIds.size());
+ Assert.assertTrue(itemPropertyIds.contains("superPrivate"));
+ Assert.assertTrue(itemPropertyIds.contains("superProtected"));
+ Assert.assertTrue(itemPropertyIds.contains("superPublic"));
+ }
+
+ public void testGetSuperClassProperties() {
+ BeanItem<MyClass> item = new BeanItem<MyClass>(new MyClass("bean1"));
+
+ Collection<?> itemPropertyIds = item.getItemPropertyIds();
+ Assert.assertEquals(6, itemPropertyIds.size());
+ Assert.assertTrue(itemPropertyIds.contains("superPrivate"));
+ Assert.assertTrue(itemPropertyIds.contains("superProtected"));
+ Assert.assertTrue(itemPropertyIds.contains("superPublic"));
+ Assert.assertTrue(itemPropertyIds.contains("name"));
+ Assert.assertTrue(itemPropertyIds.contains("noField"));
+ Assert.assertTrue(itemPropertyIds.contains("name2"));
+ }
+
+ public void testOverridingProperties() {
+ BeanItem<MyClass2> item = new BeanItem<MyClass2>(new MyClass2("bean2"));
+
+ Collection<?> itemPropertyIds = item.getItemPropertyIds();
+ Assert.assertEquals(6, itemPropertyIds.size());
+
+ Assert.assertTrue(MyClass2.class.equals(item.getBean().getClass()));
+
+ // check that name2 accessed via MyClass2, not MyClass
+ Assert.assertFalse(item.getItemProperty("name2").isReadOnly());
+ }
+
+ public void testGetInterfaceProperties() throws SecurityException,
+ NoSuchMethodException, IllegalArgumentException,
+ IllegalAccessException, InvocationTargetException {
+ Method method = BeanItem.class.getDeclaredMethod(
+ "getPropertyDescriptors", Class.class);
+ method.setAccessible(true);
+ LinkedHashMap<String, VaadinPropertyDescriptor<Class>> propertyDescriptors = (LinkedHashMap<String, VaadinPropertyDescriptor<Class>>) method
+ .invoke(null, MySuperInterface.class);
+
+ Assert.assertEquals(2, propertyDescriptors.size());
+ Assert.assertTrue(propertyDescriptors.containsKey("super1"));
+ Assert.assertTrue(propertyDescriptors.containsKey("override"));
+
+ MethodProperty<?> property = (MethodProperty<?>) propertyDescriptors
+ .get("override").createProperty(getClass());
+ Assert.assertTrue(property.isReadOnly());
+ }
+
+ public void testGetSuperInterfaceProperties() throws SecurityException,
+ NoSuchMethodException, IllegalArgumentException,
+ IllegalAccessException, InvocationTargetException {
+ Method method = BeanItem.class.getDeclaredMethod(
+ "getPropertyDescriptors", Class.class);
+ method.setAccessible(true);
+ LinkedHashMap<String, VaadinPropertyDescriptor<Class>> propertyDescriptors = (LinkedHashMap<String, VaadinPropertyDescriptor<Class>>) method
+ .invoke(null, MySubInterface.class);
+
+ Assert.assertEquals(4, propertyDescriptors.size());
+ Assert.assertTrue(propertyDescriptors.containsKey("sub"));
+ Assert.assertTrue(propertyDescriptors.containsKey("super1"));
+ Assert.assertTrue(propertyDescriptors.containsKey("super2"));
+ Assert.assertTrue(propertyDescriptors.containsKey("override"));
+
+ MethodProperty<?> property = (MethodProperty<?>) propertyDescriptors
+ .get("override").createProperty(getClass());
+ Assert.assertFalse(property.isReadOnly());
+ }
+
+ public void testPropertyExplicitOrder() {
+ Collection<String> ids = new ArrayList<String>();
+ ids.add("name");
+ ids.add("superPublic");
+ ids.add("name2");
+ ids.add("noField");
+
+ BeanItem<MyClass> item = new BeanItem<MyClass>(new MyClass("bean1"),
+ ids);
+
+ Iterator<?> it = item.getItemPropertyIds().iterator();
+ Assert.assertEquals("name", it.next());
+ Assert.assertEquals("superPublic", it.next());
+ Assert.assertEquals("name2", it.next());
+ Assert.assertEquals("noField", it.next());
+ Assert.assertFalse(it.hasNext());
+ }
+
+ public void testPropertyExplicitOrder2() {
+ BeanItem<MyClass> item = new BeanItem<MyClass>(new MyClass("bean1"),
+ new String[] { "name", "superPublic", "name2", "noField" });
+
+ Iterator<?> it = item.getItemPropertyIds().iterator();
+ Assert.assertEquals("name", it.next());
+ Assert.assertEquals("superPublic", it.next());
+ Assert.assertEquals("name2", it.next());
+ Assert.assertEquals("noField", it.next());
+ Assert.assertFalse(it.hasNext());
+ }
+
+ public void testPropertyBadPropertyName() {
+ Collection<String> ids = new ArrayList<String>();
+ ids.add("name3");
+ ids.add("name");
+
+ // currently silently ignores non-existent properties
+ BeanItem<MyClass> item = new BeanItem<MyClass>(new MyClass("bean1"),
+ ids);
+
+ Iterator<?> it = item.getItemPropertyIds().iterator();
+ Assert.assertEquals("name", it.next());
+ Assert.assertFalse(it.hasNext());
+ }
+
+ public void testRemoveProperty() {
+ BeanItem<MyClass> item = new BeanItem<MyClass>(new MyClass("bean1"));
+
+ Collection<?> itemPropertyIds = item.getItemPropertyIds();
+ Assert.assertEquals(6, itemPropertyIds.size());
+
+ item.removeItemProperty("name2");
+ Assert.assertEquals(5, itemPropertyIds.size());
+ Assert.assertFalse(itemPropertyIds.contains("name2"));
+ }
+
+ public void testRemoveSuperProperty() {
+ BeanItem<MyClass> item = new BeanItem<MyClass>(new MyClass("bean1"));
+
+ Collection<?> itemPropertyIds = item.getItemPropertyIds();
+ Assert.assertEquals(6, itemPropertyIds.size());
+
+ item.removeItemProperty("superPrivate");
+ Assert.assertEquals(5, itemPropertyIds.size());
+ Assert.assertFalse(itemPropertyIds.contains("superPrivate"));
+ }
+
+ public void testPropertyTypes() {
+ BeanItem<MyClass> item = new BeanItem<MyClass>(new MyClass("bean1"));
+
+ Assert.assertTrue(Integer.class.equals(item.getItemProperty(
+ "superPrivate").getType()));
+ Assert.assertTrue(Double.class.equals(item.getItemProperty(
+ "superProtected").getType()));
+ Assert.assertTrue(Boolean.class.equals(item.getItemProperty(
+ "superPublic").getType()));
+ Assert.assertTrue(String.class.equals(item.getItemProperty("name")
+ .getType()));
+ }
+
+ public void testPropertyReadOnly() {
+ BeanItem<MyClass> item = new BeanItem<MyClass>(new MyClass("bean1"));
+
+ Assert.assertFalse(item.getItemProperty("name").isReadOnly());
+ Assert.assertTrue(item.getItemProperty("name2").isReadOnly());
+ }
+
+ public void testCustomProperties() throws Exception {
+ LinkedHashMap<String, VaadinPropertyDescriptor<MyClass>> propertyDescriptors = new LinkedHashMap<String, VaadinPropertyDescriptor<MyClass>>();
+ propertyDescriptors.put(
+ "myname",
+ new MethodPropertyDescriptor<BeanItemTest.MyClass>("myname",
+ MyClass.class, MyClass.class
+ .getDeclaredMethod("getName"), MyClass.class
+ .getDeclaredMethod("setName", String.class)));
+ MyClass instance = new MyClass("bean1");
+ Constructor<BeanItem> constructor = BeanItem.class
+ .getDeclaredConstructor(Object.class, Map.class);
+ constructor.setAccessible(true);
+ BeanItem<MyClass> item = constructor.newInstance(instance,
+ propertyDescriptors);
+
+ Assert.assertEquals(1, item.getItemPropertyIds().size());
+ Assert.assertEquals("bean1", item.getItemProperty("myname").getValue());
+ }
+
+ public void testAddRemoveProperty() throws Exception {
+ MethodPropertyDescriptor<BeanItemTest.MyClass> pd = new MethodPropertyDescriptor<BeanItemTest.MyClass>(
+ "myname", MyClass.class,
+ MyClass.class.getDeclaredMethod("getName"),
+ MyClass.class.getDeclaredMethod("setName", String.class));
+
+ BeanItem<MyClass> item = new BeanItem<MyClass>(new MyClass("bean1"));
+
+ Assert.assertEquals(6, item.getItemPropertyIds().size());
+ Assert.assertEquals(null, item.getItemProperty("myname"));
+
+ item.addItemProperty("myname", pd.createProperty(item.getBean()));
+ Assert.assertEquals(7, item.getItemPropertyIds().size());
+ Assert.assertEquals("bean1", item.getItemProperty("myname").getValue());
+ item.removeItemProperty("myname");
+ Assert.assertEquals(6, item.getItemPropertyIds().size());
+ Assert.assertEquals(null, item.getItemProperty("myname"));
+ }
+}
diff --git a/server/tests/src/com/vaadin/data/util/FileSystemContainerTest.java b/server/tests/src/com/vaadin/data/util/FileSystemContainerTest.java
new file mode 100644
index 0000000000..f4bb794e5c
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/FileSystemContainerTest.java
@@ -0,0 +1,16 @@
+package com.vaadin.data.util;
+
+import java.io.File;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class FileSystemContainerTest {
+
+ @Test
+ public void nonExistingDirectory() {
+ FilesystemContainer fsc = new FilesystemContainer(new File(
+ "/non/existing"));
+ Assert.assertTrue(fsc.getItemIds().isEmpty());
+ }
+}
diff --git a/server/tests/src/com/vaadin/data/util/NestedMethodPropertyTest.java b/server/tests/src/com/vaadin/data/util/NestedMethodPropertyTest.java
new file mode 100644
index 0000000000..640ede8743
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/NestedMethodPropertyTest.java
@@ -0,0 +1,327 @@
+package com.vaadin.data.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+public class NestedMethodPropertyTest extends TestCase {
+
+ public static class Address implements Serializable {
+ private String street;
+ private int postalCodePrimitive;
+ private Integer postalCodeObject;
+
+ public Address(String street, int postalCode) {
+ this.street = street;
+ postalCodePrimitive = postalCode;
+ postalCodeObject = postalCode;
+ }
+
+ public void setStreet(String street) {
+ this.street = street;
+ }
+
+ public String getStreet() {
+ return street;
+ }
+
+ public void setPostalCodePrimitive(int postalCodePrimitive) {
+ this.postalCodePrimitive = postalCodePrimitive;
+ }
+
+ public int getPostalCodePrimitive() {
+ return postalCodePrimitive;
+ }
+
+ public void setPostalCodeObject(Integer postalCodeObject) {
+ this.postalCodeObject = postalCodeObject;
+ }
+
+ public Integer getPostalCodeObject() {
+ return postalCodeObject;
+ }
+
+ // read-only boolean property
+ public boolean isBoolean() {
+ return true;
+ }
+ }
+
+ public static class Person implements Serializable {
+ private String name;
+ private Address address;
+
+ public Person(String name, Address address) {
+ this.name = name;
+ this.address = address;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setAddress(Address address) {
+ this.address = address;
+ }
+
+ public Address getAddress() {
+ return address;
+ }
+ }
+
+ public static class Team implements Serializable {
+ private String name;
+ private Person manager;
+
+ public Team(String name, Person manager) {
+ this.name = name;
+ this.manager = manager;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setManager(Person manager) {
+ this.manager = manager;
+ }
+
+ public Person getManager() {
+ return manager;
+ }
+ }
+
+ private Address oldMill;
+ private Person joonas;
+ private Team vaadin;
+
+ @Override
+ public void setUp() {
+ oldMill = new Address("Ruukinkatu 2-4", 20540);
+ joonas = new Person("Joonas", oldMill);
+ vaadin = new Team("Vaadin", joonas);
+ }
+
+ @Override
+ public void tearDown() {
+ vaadin = null;
+ joonas = null;
+ oldMill = null;
+ }
+
+ public void testSingleLevelNestedSimpleProperty() {
+ NestedMethodProperty<String> nameProperty = new NestedMethodProperty<String>(
+ vaadin, "name");
+
+ Assert.assertEquals(String.class, nameProperty.getType());
+ Assert.assertEquals("Vaadin", nameProperty.getValue());
+ }
+
+ public void testSingleLevelNestedObjectProperty() {
+ NestedMethodProperty<Person> managerProperty = new NestedMethodProperty<Person>(
+ vaadin, "manager");
+
+ Assert.assertEquals(Person.class, managerProperty.getType());
+ Assert.assertEquals(joonas, managerProperty.getValue());
+ }
+
+ public void testMultiLevelNestedProperty() {
+ NestedMethodProperty<String> managerNameProperty = new NestedMethodProperty<String>(
+ vaadin, "manager.name");
+ NestedMethodProperty<Address> addressProperty = new NestedMethodProperty<Address>(
+ vaadin, "manager.address");
+ NestedMethodProperty<String> streetProperty = new NestedMethodProperty<String>(
+ vaadin, "manager.address.street");
+ NestedMethodProperty<Integer> postalCodePrimitiveProperty = new NestedMethodProperty<Integer>(
+ vaadin, "manager.address.postalCodePrimitive");
+ NestedMethodProperty<Integer> postalCodeObjectProperty = new NestedMethodProperty<Integer>(
+ vaadin, "manager.address.postalCodeObject");
+ NestedMethodProperty<Boolean> booleanProperty = new NestedMethodProperty<Boolean>(
+ vaadin, "manager.address.boolean");
+
+ Assert.assertEquals(String.class, managerNameProperty.getType());
+ Assert.assertEquals("Joonas", managerNameProperty.getValue());
+
+ Assert.assertEquals(Address.class, addressProperty.getType());
+ Assert.assertEquals(oldMill, addressProperty.getValue());
+
+ Assert.assertEquals(String.class, streetProperty.getType());
+ Assert.assertEquals("Ruukinkatu 2-4", streetProperty.getValue());
+
+ Assert.assertEquals(Integer.class,
+ postalCodePrimitiveProperty.getType());
+ Assert.assertEquals(Integer.valueOf(20540),
+ postalCodePrimitiveProperty.getValue());
+
+ Assert.assertEquals(Integer.class, postalCodeObjectProperty.getType());
+ Assert.assertEquals(Integer.valueOf(20540),
+ postalCodeObjectProperty.getValue());
+
+ Assert.assertEquals(Boolean.class, booleanProperty.getType());
+ Assert.assertEquals(Boolean.TRUE, booleanProperty.getValue());
+ }
+
+ public void testEmptyPropertyName() {
+ try {
+ new NestedMethodProperty<Object>(vaadin, "");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // should get exception
+ }
+
+ try {
+ new NestedMethodProperty<Object>(vaadin, " ");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // should get exception
+ }
+ }
+
+ public void testInvalidPropertyName() {
+ try {
+ new NestedMethodProperty<Object>(vaadin, ".");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // should get exception
+ }
+ try {
+ new NestedMethodProperty<Object>(vaadin, ".manager");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // should get exception
+ }
+ try {
+ new NestedMethodProperty<Object>(vaadin, "manager.");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // should get exception
+ }
+ try {
+ new NestedMethodProperty<Object>(vaadin, "manager..name");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // should get exception
+ }
+ }
+
+ public void testInvalidNestedPropertyName() {
+ try {
+ new NestedMethodProperty<Object>(vaadin, "member");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // should get exception
+ }
+
+ try {
+ new NestedMethodProperty<Object>(vaadin, "manager.pet");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // should get exception
+ }
+
+ try {
+ new NestedMethodProperty<Object>(vaadin, "manager.address.city");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // should get exception
+ }
+ }
+
+ public void testNullNestedProperty() {
+ NestedMethodProperty<String> managerNameProperty = new NestedMethodProperty<String>(
+ vaadin, "manager.name");
+ NestedMethodProperty<String> streetProperty = new NestedMethodProperty<String>(
+ vaadin, "manager.address.street");
+
+ joonas.setAddress(null);
+ try {
+ streetProperty.getValue();
+ fail();
+ } catch (Exception e) {
+ // should get exception
+ }
+
+ vaadin.setManager(null);
+ try {
+ managerNameProperty.getValue();
+ fail();
+ } catch (Exception e) {
+ // should get exception
+ }
+ try {
+ streetProperty.getValue();
+ fail();
+ } catch (Exception e) {
+ // should get exception
+ }
+
+ vaadin.setManager(joonas);
+ Assert.assertEquals("Joonas", managerNameProperty.getValue());
+ }
+
+ public void testMultiLevelNestedPropertySetValue() {
+ NestedMethodProperty<String> managerNameProperty = new NestedMethodProperty<String>(
+ vaadin, "manager.name");
+ NestedMethodProperty<Address> addressProperty = new NestedMethodProperty<Address>(
+ vaadin, "manager.address");
+ NestedMethodProperty<String> streetProperty = new NestedMethodProperty<String>(
+ vaadin, "manager.address.street");
+ NestedMethodProperty<Integer> postalCodePrimitiveProperty = new NestedMethodProperty<Integer>(
+ vaadin, "manager.address.postalCodePrimitive");
+ NestedMethodProperty<Integer> postalCodeObjectProperty = new NestedMethodProperty<Integer>(
+ vaadin, "manager.address.postalCodeObject");
+
+ managerNameProperty.setValue("Joonas L");
+ Assert.assertEquals("Joonas L", joonas.getName());
+ streetProperty.setValue("Ruukinkatu");
+ Assert.assertEquals("Ruukinkatu", oldMill.getStreet());
+ postalCodePrimitiveProperty.setValue(0);
+ postalCodeObjectProperty.setValue(1);
+ Assert.assertEquals(0, oldMill.getPostalCodePrimitive());
+ Assert.assertEquals(Integer.valueOf(1), oldMill.getPostalCodeObject());
+
+ postalCodeObjectProperty.setValue(null);
+ Assert.assertNull(oldMill.getPostalCodeObject());
+
+ Address address2 = new Address("Other street", 12345);
+ addressProperty.setValue(address2);
+ Assert.assertEquals("Other street", streetProperty.getValue());
+ }
+
+ public void testSerialization() throws IOException, ClassNotFoundException {
+ NestedMethodProperty<String> streetProperty = new NestedMethodProperty<String>(
+ vaadin, "manager.address.street");
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ new ObjectOutputStream(baos).writeObject(streetProperty);
+ @SuppressWarnings("unchecked")
+ NestedMethodProperty<String> property2 = (NestedMethodProperty<String>) new ObjectInputStream(
+ new ByteArrayInputStream(baos.toByteArray())).readObject();
+
+ Assert.assertEquals("Ruukinkatu 2-4", property2.getValue());
+ }
+
+ public void testIsReadOnly() {
+ NestedMethodProperty<String> streetProperty = new NestedMethodProperty<String>(
+ vaadin, "manager.address.street");
+ NestedMethodProperty<Boolean> booleanProperty = new NestedMethodProperty<Boolean>(
+ vaadin, "manager.address.boolean");
+
+ Assert.assertFalse(streetProperty.isReadOnly());
+ Assert.assertTrue(booleanProperty.isReadOnly());
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/data/util/ObjectPropertyTest.java b/server/tests/src/com/vaadin/data/util/ObjectPropertyTest.java
new file mode 100644
index 0000000000..99ca58ba42
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/ObjectPropertyTest.java
@@ -0,0 +1,97 @@
+package com.vaadin.data.util;
+
+import junit.framework.TestCase;
+
+import org.junit.Assert;
+
+public class ObjectPropertyTest extends TestCase {
+
+ public static class TestSuperClass {
+ private String name;
+
+ public TestSuperClass(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String toString() {
+ return getName();
+ }
+ }
+
+ public static class TestSubClass extends TestSuperClass {
+ public TestSubClass(String name) {
+ super("Subclass: " + name);
+ }
+ }
+
+ private TestSuperClass super1 = new TestSuperClass("super1");
+ private TestSubClass sub1 = new TestSubClass("sub1");
+
+ public void testSimple() {
+ ObjectProperty<TestSuperClass> prop1 = new ObjectProperty<TestSuperClass>(
+ super1, TestSuperClass.class);
+ Assert.assertEquals("super1", prop1.getValue().getName());
+ prop1 = new ObjectProperty<TestSuperClass>(super1);
+ Assert.assertEquals("super1", prop1.getValue().getName());
+
+ ObjectProperty<TestSubClass> prop2 = new ObjectProperty<TestSubClass>(
+ sub1, TestSubClass.class);
+ Assert.assertEquals("Subclass: sub1", prop2.getValue().getName());
+ prop2 = new ObjectProperty<TestSubClass>(sub1);
+ Assert.assertEquals("Subclass: sub1", prop2.getValue().getName());
+ }
+
+ public void testSetValueObjectSuper() {
+ ObjectProperty<TestSuperClass> prop = new ObjectProperty<TestSuperClass>(
+ super1, TestSuperClass.class);
+ Assert.assertEquals("super1", prop.getValue().getName());
+ prop.setValue(new TestSuperClass("super2"));
+ Assert.assertEquals("super1", super1.getName());
+ Assert.assertEquals("super2", prop.getValue().getName());
+ }
+
+ public void testSetValueObjectSub() {
+ ObjectProperty<TestSubClass> prop = new ObjectProperty<TestSubClass>(
+ sub1, TestSubClass.class);
+ Assert.assertEquals("Subclass: sub1", prop.getValue().getName());
+ prop.setValue(new TestSubClass("sub2"));
+ Assert.assertEquals("Subclass: sub1", sub1.getName());
+ Assert.assertEquals("Subclass: sub2", prop.getValue().getName());
+ }
+
+ public void testSetValueStringSuper() {
+ ObjectProperty<TestSuperClass> prop = new ObjectProperty<TestSuperClass>(
+ super1, TestSuperClass.class);
+ Assert.assertEquals("super1", prop.getValue().getName());
+ prop.setValue(new TestSuperClass("super2"));
+ Assert.assertEquals("super1", super1.getName());
+ Assert.assertEquals("super2", prop.getValue().getName());
+ }
+
+ public void testSetValueStringSub() {
+ ObjectProperty<TestSubClass> prop = new ObjectProperty<TestSubClass>(
+ sub1, TestSubClass.class);
+ Assert.assertEquals("Subclass: sub1", prop.getValue().getName());
+ prop.setValue(new TestSubClass("sub2"));
+ Assert.assertEquals("Subclass: sub1", sub1.getName());
+ Assert.assertEquals("Subclass: sub2", prop.getValue().getName());
+ }
+
+ public void testMixedGenerics() {
+ ObjectProperty<TestSuperClass> prop = new ObjectProperty<TestSuperClass>(
+ sub1);
+ Assert.assertEquals("Subclass: sub1", prop.getValue().getName());
+ Assert.assertEquals(prop.getType(), TestSubClass.class);
+ // create correct subclass based on the runtime type of the instance
+ // given to ObjectProperty constructor, which is a subclass of the type
+ // parameter
+ prop.setValue(new TestSubClass("sub2"));
+ Assert.assertEquals("Subclass: sub2", prop.getValue().getName());
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/data/util/PerformanceTestIndexedContainer.java b/server/tests/src/com/vaadin/data/util/PerformanceTestIndexedContainer.java
new file mode 100644
index 0000000000..c4ed12efc0
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/PerformanceTestIndexedContainer.java
@@ -0,0 +1,117 @@
+package com.vaadin.data.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import com.vaadin.data.util.IndexedContainer;
+
+public class PerformanceTestIndexedContainer extends TestCase {
+
+ private static final int REPEATS = 10;
+ private final static int ITEMS = 50000;
+ private static final long ADD_ITEM_FAIL_THRESHOLD = 200;
+ // TODO should improve performance of these methods
+ private static final long ADD_ITEM_AT_FAIL_THRESHOLD = 5000;
+ private static final long ADD_ITEM_AFTER_FAIL_THRESHOLD = 5000;
+ private static final long ADD_ITEM_AFTER_LAST_FAIL_THRESHOLD = 5000;
+ private static final long ADD_ITEMS_CONSTRUCTOR_FAIL_THRESHOLD = 200;
+
+ public void testAddItemPerformance() {
+ Collection<Long> times = new ArrayList<Long>();
+ for (int j = 0; j < REPEATS; ++j) {
+ IndexedContainer c = new IndexedContainer();
+ long start = System.currentTimeMillis();
+ for (int i = 0; i < ITEMS; i++) {
+ c.addItem();
+ }
+ times.add(System.currentTimeMillis() - start);
+ }
+ checkMedian(ITEMS, times, "IndexedContainer.addItem()",
+ ADD_ITEM_FAIL_THRESHOLD);
+ }
+
+ public void testAddItemAtPerformance() {
+ Collection<Long> times = new ArrayList<Long>();
+ for (int j = 0; j < REPEATS; ++j) {
+ IndexedContainer c = new IndexedContainer();
+ long start = System.currentTimeMillis();
+ for (int i = 0; i < ITEMS; i++) {
+ c.addItemAt(0);
+ }
+ times.add(System.currentTimeMillis() - start);
+ }
+ checkMedian(ITEMS, times, "IndexedContainer.addItemAt()",
+ ADD_ITEM_AT_FAIL_THRESHOLD);
+ }
+
+ public void testAddItemAfterPerformance() {
+ Object initialId = "Item0";
+ Collection<Long> times = new ArrayList<Long>();
+ for (int j = 0; j < REPEATS; ++j) {
+ IndexedContainer c = new IndexedContainer();
+ c.addItem(initialId);
+ long start = System.currentTimeMillis();
+ for (int i = 0; i < ITEMS; i++) {
+ c.addItemAfter(initialId);
+ }
+ times.add(System.currentTimeMillis() - start);
+ }
+ checkMedian(ITEMS, times, "IndexedContainer.addItemAfter()",
+ ADD_ITEM_AFTER_FAIL_THRESHOLD);
+ }
+
+ public void testAddItemAfterLastPerformance() {
+ // TODO running with less items because slow otherwise
+ Collection<Long> times = new ArrayList<Long>();
+ for (int j = 0; j < REPEATS; ++j) {
+ IndexedContainer c = new IndexedContainer();
+ c.addItem();
+ long start = System.currentTimeMillis();
+ for (int i = 0; i < ITEMS / 3; i++) {
+ c.addItemAfter(c.lastItemId());
+ }
+ times.add(System.currentTimeMillis() - start);
+ }
+ checkMedian(ITEMS / 3, times, "IndexedContainer.addItemAfter(lastId)",
+ ADD_ITEM_AFTER_LAST_FAIL_THRESHOLD);
+ }
+
+ public void testAddItemsConstructorPerformance() {
+ Collection<Object> items = new ArrayList<Object>(50000);
+ for (int i = 0; i < ITEMS; ++i) {
+ items.add(new Object());
+ }
+
+ SortedSet<Long> times = new TreeSet<Long>();
+ for (int j = 0; j < REPEATS; ++j) {
+ long start = System.currentTimeMillis();
+ new IndexedContainer(items);
+ times.add(System.currentTimeMillis() - start);
+ }
+ checkMedian(ITEMS, times, "IndexedContainer(Collection)",
+ ADD_ITEMS_CONSTRUCTOR_FAIL_THRESHOLD);
+ }
+
+ private void checkMedian(int items, Collection<Long> times,
+ String methodName, long threshold) {
+ long median = median(times);
+ System.out.println(methodName + " timings (ms) for " + items
+ + " items: " + times);
+ Assert.assertTrue(methodName + " too slow, median time " + median
+ + "ms for " + items + " items", median <= threshold);
+ }
+
+ private Long median(Collection<Long> times) {
+ ArrayList<Long> list = new ArrayList<Long>(times);
+ Collections.sort(list);
+ // not exact median in some cases, but good enough
+ return list.get(list.size() / 2);
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/data/util/PropertyDescriptorTest.java b/server/tests/src/com/vaadin/data/util/PropertyDescriptorTest.java
new file mode 100644
index 0000000000..14e70d76d4
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/PropertyDescriptorTest.java
@@ -0,0 +1,55 @@
+package com.vaadin.data.util;
+
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import com.vaadin.data.Property;
+import com.vaadin.data.util.NestedMethodPropertyTest.Person;
+
+public class PropertyDescriptorTest extends TestCase {
+ public void testMethodPropertyDescriptorSerialization() throws Exception {
+ PropertyDescriptor[] pds = Introspector.getBeanInfo(Person.class)
+ .getPropertyDescriptors();
+
+ MethodPropertyDescriptor<Person> descriptor = null;
+
+ for (PropertyDescriptor pd : pds) {
+ if ("name".equals(pd.getName())) {
+ descriptor = new MethodPropertyDescriptor<Person>(pd.getName(),
+ String.class, pd.getReadMethod(), pd.getWriteMethod());
+ break;
+ }
+ }
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ new ObjectOutputStream(baos).writeObject(descriptor);
+ @SuppressWarnings("unchecked")
+ VaadinPropertyDescriptor<Person> descriptor2 = (VaadinPropertyDescriptor<Person>) new ObjectInputStream(
+ new ByteArrayInputStream(baos.toByteArray())).readObject();
+
+ Property<?> property = descriptor2.createProperty(new Person("John",
+ null));
+ Assert.assertEquals("John", property.getValue());
+ }
+
+ public void testNestedPropertyDescriptorSerialization() throws Exception {
+ NestedPropertyDescriptor<Person> pd = new NestedPropertyDescriptor<Person>(
+ "name", Person.class);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ new ObjectOutputStream(baos).writeObject(pd);
+ @SuppressWarnings("unchecked")
+ VaadinPropertyDescriptor<Person> pd2 = (VaadinPropertyDescriptor<Person>) new ObjectInputStream(
+ new ByteArrayInputStream(baos.toByteArray())).readObject();
+
+ Property<?> property = pd2.createProperty(new Person("John", null));
+ Assert.assertEquals("John", property.getValue());
+ }
+}
diff --git a/server/tests/src/com/vaadin/data/util/PropertySetItemTest.java b/server/tests/src/com/vaadin/data/util/PropertySetItemTest.java
new file mode 100644
index 0000000000..a3169332ec
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/PropertySetItemTest.java
@@ -0,0 +1,405 @@
+package com.vaadin.data.util;
+
+import java.util.Iterator;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.easymock.EasyMock;
+
+import com.vaadin.data.Item.PropertySetChangeEvent;
+import com.vaadin.data.Item.PropertySetChangeListener;
+
+public class PropertySetItemTest extends TestCase {
+
+ private static final String ID1 = "id1";
+ private static final String ID2 = "id2";
+ private static final String ID3 = "id3";
+
+ private static final String VALUE1 = "value1";
+ private static final String VALUE2 = "value2";
+ private static final String VALUE3 = "value3";
+
+ private ObjectProperty<String> prop1;
+ private ObjectProperty<String> prop2;
+ private ObjectProperty<String> prop3;
+
+ private PropertySetChangeListener propertySetListenerMock;
+ private PropertySetChangeListener propertySetListenerMock2;
+
+ @Override
+ protected void setUp() throws Exception {
+ prop1 = new ObjectProperty<String>(VALUE1, String.class);
+ prop2 = new ObjectProperty<String>(VALUE2, String.class);
+ prop3 = new ObjectProperty<String>(VALUE3, String.class);
+
+ propertySetListenerMock = EasyMock
+ .createStrictMock(PropertySetChangeListener.class);
+ propertySetListenerMock2 = EasyMock
+ .createMock(PropertySetChangeListener.class);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ prop1 = null;
+ prop2 = null;
+ prop3 = null;
+
+ propertySetListenerMock = null;
+ propertySetListenerMock2 = null;
+ }
+
+ private PropertysetItem createPropertySetItem() {
+ return new PropertysetItem();
+ }
+
+ public void testEmptyItem() {
+ PropertysetItem item = createPropertySetItem();
+ Assert.assertNotNull(item.getItemPropertyIds());
+ Assert.assertEquals(0, item.getItemPropertyIds().size());
+ }
+
+ public void testGetProperty() {
+ PropertysetItem item = createPropertySetItem();
+
+ Assert.assertNull(item.getItemProperty(ID1));
+
+ item.addItemProperty(ID1, prop1);
+
+ Assert.assertEquals(prop1, item.getItemProperty(ID1));
+ Assert.assertNull(item.getItemProperty(ID2));
+ }
+
+ public void testAddSingleProperty() {
+ PropertysetItem item = createPropertySetItem();
+
+ item.addItemProperty(ID1, prop1);
+ Assert.assertEquals(1, item.getItemPropertyIds().size());
+ Object firstValue = item.getItemPropertyIds().iterator().next();
+ Assert.assertEquals(ID1, firstValue);
+ Assert.assertEquals(prop1, item.getItemProperty(ID1));
+ }
+
+ public void testAddMultipleProperties() {
+ PropertysetItem item = createPropertySetItem();
+
+ item.addItemProperty(ID1, prop1);
+ Assert.assertEquals(1, item.getItemPropertyIds().size());
+ Assert.assertEquals(prop1, item.getItemProperty(ID1));
+
+ item.addItemProperty(ID2, prop2);
+ Assert.assertEquals(2, item.getItemPropertyIds().size());
+ Assert.assertEquals(prop1, item.getItemProperty(ID1));
+ Assert.assertEquals(prop2, item.getItemProperty(ID2));
+
+ item.addItemProperty(ID3, prop3);
+ Assert.assertEquals(3, item.getItemPropertyIds().size());
+ }
+
+ public void testAddedPropertyOrder() {
+ PropertysetItem item = createPropertySetItem();
+ item.addItemProperty(ID1, prop1);
+ item.addItemProperty(ID2, prop2);
+ item.addItemProperty(ID3, prop3);
+
+ Iterator<?> it = item.getItemPropertyIds().iterator();
+ Assert.assertEquals(ID1, it.next());
+ Assert.assertEquals(ID2, it.next());
+ Assert.assertEquals(ID3, it.next());
+ }
+
+ public void testAddPropertyTwice() {
+ PropertysetItem item = createPropertySetItem();
+ Assert.assertTrue(item.addItemProperty(ID1, prop1));
+ Assert.assertFalse(item.addItemProperty(ID1, prop1));
+
+ Assert.assertEquals(1, item.getItemPropertyIds().size());
+ Assert.assertEquals(prop1, item.getItemProperty(ID1));
+ }
+
+ public void testCannotChangeProperty() {
+ PropertysetItem item = createPropertySetItem();
+ Assert.assertTrue(item.addItemProperty(ID1, prop1));
+
+ Assert.assertEquals(prop1, item.getItemProperty(ID1));
+
+ Assert.assertFalse(item.addItemProperty(ID1, prop2));
+
+ Assert.assertEquals(1, item.getItemPropertyIds().size());
+ Assert.assertEquals(prop1, item.getItemProperty(ID1));
+ }
+
+ public void testRemoveProperty() {
+ PropertysetItem item = createPropertySetItem();
+ item.addItemProperty(ID1, prop1);
+ item.removeItemProperty(ID1);
+
+ Assert.assertEquals(0, item.getItemPropertyIds().size());
+ Assert.assertNull(item.getItemProperty(ID1));
+ }
+
+ public void testRemovePropertyOrder() {
+ PropertysetItem item = createPropertySetItem();
+ item.addItemProperty(ID1, prop1);
+ item.addItemProperty(ID2, prop2);
+ item.addItemProperty(ID3, prop3);
+
+ item.removeItemProperty(ID2);
+
+ Iterator<?> it = item.getItemPropertyIds().iterator();
+ Assert.assertEquals(ID1, it.next());
+ Assert.assertEquals(ID3, it.next());
+ }
+
+ public void testRemoveNonExistentListener() {
+ PropertysetItem item = createPropertySetItem();
+ item.removeListener(propertySetListenerMock);
+ }
+
+ public void testRemoveListenerTwice() {
+ PropertysetItem item = createPropertySetItem();
+ item.addListener(propertySetListenerMock);
+ item.removeListener(propertySetListenerMock);
+ item.removeListener(propertySetListenerMock);
+ }
+
+ public void testAddPropertyNotification() {
+ // exactly one notification each time
+ PropertysetItem item = createPropertySetItem();
+
+ // Expectations and start test
+ propertySetListenerMock.itemPropertySetChange(EasyMock
+ .isA(PropertySetChangeEvent.class));
+ EasyMock.replay(propertySetListenerMock);
+
+ // Add listener and add a property -> should end up in listener once
+ item.addListener(propertySetListenerMock);
+ item.addItemProperty(ID1, prop1);
+
+ // Ensure listener was called once
+ EasyMock.verify(propertySetListenerMock);
+
+ // Remove the listener -> should not end up in listener when adding a
+ // property
+ item.removeListener(propertySetListenerMock);
+ item.addItemProperty(ID2, prop2);
+
+ // Ensure listener still has been called only once
+ EasyMock.verify(propertySetListenerMock);
+ }
+
+ public void testRemovePropertyNotification() {
+ // exactly one notification each time
+ PropertysetItem item = createPropertySetItem();
+ item.addItemProperty(ID1, prop1);
+ item.addItemProperty(ID2, prop2);
+
+ // Expectations and start test
+ propertySetListenerMock.itemPropertySetChange(EasyMock
+ .isA(PropertySetChangeEvent.class));
+ EasyMock.replay(propertySetListenerMock);
+
+ // Add listener and add a property -> should end up in listener once
+ item.addListener(propertySetListenerMock);
+ item.removeItemProperty(ID1);
+
+ // Ensure listener was called once
+ EasyMock.verify(propertySetListenerMock);
+
+ // Remove the listener -> should not end up in listener
+ item.removeListener(propertySetListenerMock);
+ item.removeItemProperty(ID2);
+
+ // Ensure listener still has been called only once
+ EasyMock.verify(propertySetListenerMock);
+ }
+
+ public void testItemEqualsNull() {
+ PropertysetItem item = createPropertySetItem();
+
+ Assert.assertFalse(item.equals(null));
+ }
+
+ public void testEmptyItemEquals() {
+ PropertysetItem item1 = createPropertySetItem();
+ PropertysetItem item2 = createPropertySetItem();
+
+ Assert.assertTrue(item1.equals(item2));
+ }
+
+ public void testItemEqualsSingleProperty() {
+ PropertysetItem item1 = createPropertySetItem();
+ PropertysetItem item2 = createPropertySetItem();
+ item2.addItemProperty(ID1, prop1);
+ PropertysetItem item3 = createPropertySetItem();
+ item3.addItemProperty(ID1, prop1);
+ PropertysetItem item4 = createPropertySetItem();
+ item4.addItemProperty(ID1, prop2);
+ PropertysetItem item5 = createPropertySetItem();
+ item5.addItemProperty(ID2, prop2);
+
+ Assert.assertFalse(item1.equals(item2));
+ Assert.assertFalse(item1.equals(item3));
+ Assert.assertFalse(item1.equals(item4));
+ Assert.assertFalse(item1.equals(item5));
+
+ Assert.assertTrue(item2.equals(item3));
+ Assert.assertFalse(item2.equals(item4));
+ Assert.assertFalse(item2.equals(item5));
+
+ Assert.assertFalse(item3.equals(item4));
+ Assert.assertFalse(item3.equals(item5));
+
+ Assert.assertFalse(item4.equals(item5));
+
+ Assert.assertFalse(item2.equals(item1));
+ }
+
+ public void testItemEqualsMultipleProperties() {
+ PropertysetItem item1 = createPropertySetItem();
+ item1.addItemProperty(ID1, prop1);
+
+ PropertysetItem item2 = createPropertySetItem();
+ item2.addItemProperty(ID1, prop1);
+ item2.addItemProperty(ID2, prop2);
+
+ PropertysetItem item3 = createPropertySetItem();
+ item3.addItemProperty(ID1, prop1);
+ item3.addItemProperty(ID2, prop2);
+
+ Assert.assertFalse(item1.equals(item2));
+
+ Assert.assertTrue(item2.equals(item3));
+ }
+
+ public void testItemEqualsPropertyOrder() {
+ PropertysetItem item1 = createPropertySetItem();
+ item1.addItemProperty(ID1, prop1);
+ item1.addItemProperty(ID2, prop2);
+
+ PropertysetItem item2 = createPropertySetItem();
+ item2.addItemProperty(ID2, prop2);
+ item2.addItemProperty(ID1, prop1);
+
+ Assert.assertFalse(item1.equals(item2));
+ }
+
+ public void testEqualsSingleListener() {
+ PropertysetItem item1 = createPropertySetItem();
+ PropertysetItem item2 = createPropertySetItem();
+
+ item1.addListener(propertySetListenerMock);
+
+ Assert.assertFalse(item1.equals(item2));
+ Assert.assertFalse(item2.equals(item1));
+
+ item2.addListener(propertySetListenerMock);
+
+ Assert.assertTrue(item1.equals(item2));
+ Assert.assertTrue(item2.equals(item1));
+ }
+
+ public void testEqualsMultipleListeners() {
+ PropertysetItem item1 = createPropertySetItem();
+ PropertysetItem item2 = createPropertySetItem();
+
+ item1.addListener(propertySetListenerMock);
+ item1.addListener(propertySetListenerMock2);
+
+ item2.addListener(propertySetListenerMock);
+
+ Assert.assertFalse(item1.equals(item2));
+ Assert.assertFalse(item2.equals(item1));
+
+ item2.addListener(propertySetListenerMock2);
+
+ Assert.assertTrue(item1.equals(item2));
+ Assert.assertTrue(item2.equals(item1));
+ }
+
+ public void testEqualsAddRemoveListener() {
+ PropertysetItem item1 = createPropertySetItem();
+ PropertysetItem item2 = createPropertySetItem();
+
+ item1.addListener(propertySetListenerMock);
+ item1.removeListener(propertySetListenerMock);
+
+ Assert.assertTrue(item1.equals(item2));
+ Assert.assertTrue(item2.equals(item1));
+ }
+
+ public void testItemHashCodeEmpty() {
+ PropertysetItem item1 = createPropertySetItem();
+ PropertysetItem item2 = createPropertySetItem();
+
+ Assert.assertEquals(item1.hashCode(), item2.hashCode());
+ }
+
+ public void testItemHashCodeAddProperties() {
+ PropertysetItem item1 = createPropertySetItem();
+ PropertysetItem item2 = createPropertySetItem();
+
+ Assert.assertEquals(item1.hashCode(), item2.hashCode());
+
+ item1.addItemProperty(ID1, prop1);
+ item1.addItemProperty(ID2, prop2);
+ // hashCodes can be equal even if items are different
+
+ item2.addItemProperty(ID1, prop1);
+ item2.addItemProperty(ID2, prop2);
+ // but here hashCodes must be equal
+ Assert.assertEquals(item1.hashCode(), item2.hashCode());
+ }
+
+ public void testItemHashCodeAddListeners() {
+ PropertysetItem item1 = createPropertySetItem();
+ PropertysetItem item2 = createPropertySetItem();
+
+ Assert.assertEquals(item1.hashCode(), item2.hashCode());
+
+ item1.addListener(propertySetListenerMock);
+ // hashCodes can be equal even if items are different
+
+ item2.addListener(propertySetListenerMock);
+ // but here hashCodes must be equal
+ Assert.assertEquals(item1.hashCode(), item2.hashCode());
+ }
+
+ public void testItemHashCodeAddRemoveProperty() {
+ PropertysetItem item1 = createPropertySetItem();
+ PropertysetItem item2 = createPropertySetItem();
+
+ item1.addItemProperty(ID1, prop1);
+ item1.removeItemProperty(ID1);
+
+ Assert.assertEquals(item1.hashCode(), item2.hashCode());
+ }
+
+ public void testItemHashCodeAddRemoveListener() {
+ PropertysetItem item1 = createPropertySetItem();
+ PropertysetItem item2 = createPropertySetItem();
+
+ item1.addListener(propertySetListenerMock);
+ item1.removeListener(propertySetListenerMock);
+
+ Assert.assertEquals(item1.hashCode(), item2.hashCode());
+ }
+
+ public void testToString() {
+ // toString() behavior is specified in the class javadoc
+ PropertysetItem item = createPropertySetItem();
+
+ Assert.assertEquals("", item.toString());
+
+ item.addItemProperty(ID1, prop1);
+
+ Assert.assertEquals(String.valueOf(prop1.getValue()), item.toString());
+
+ item.addItemProperty(ID2, prop2);
+
+ Assert.assertEquals(
+ String.valueOf(prop1.getValue()) + " "
+ + String.valueOf(prop2.getValue()), item.toString());
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/data/util/TestContainerHierarchicalWrapper.java b/server/tests/src/com/vaadin/data/util/TestContainerHierarchicalWrapper.java
new file mode 100644
index 0000000000..ff6de50651
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/TestContainerHierarchicalWrapper.java
@@ -0,0 +1,42 @@
+package com.vaadin.data.util;
+
+import java.util.Collection;
+
+public class TestContainerHierarchicalWrapper extends
+ AbstractHierarchicalContainerTest {
+
+ public void testBasicOperations() {
+ testBasicContainerOperations(new ContainerHierarchicalWrapper(
+ new IndexedContainer()));
+ }
+
+ public void testHierarchicalContainer() {
+ testHierarchicalContainer(new ContainerHierarchicalWrapper(
+ new IndexedContainer()));
+ }
+
+ public void testRemoveSubtree() {
+ testRemoveHierarchicalWrapperSubtree(new ContainerHierarchicalWrapper(
+ new IndexedContainer()));
+ }
+
+ protected void testRemoveHierarchicalWrapperSubtree(
+ ContainerHierarchicalWrapper container) {
+ initializeContainer(container);
+
+ // remove root item
+ container.removeItemRecursively("org");
+
+ int packages = 21 + 3 - 3;
+ int expectedSize = sampleData.length + packages - 1;
+
+ validateContainer(container, "com", "com.vaadin.util.SerializerHelper",
+ "com.vaadin.server.ApplicationResource", "blah", true,
+ expectedSize);
+
+ // rootItemIds
+ Collection<?> rootIds = container.rootItemIds();
+ assertEquals(1, rootIds.size());
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/data/util/TestContainerSorting.java b/server/tests/src/com/vaadin/data/util/TestContainerSorting.java
new file mode 100644
index 0000000000..497699605a
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/TestContainerSorting.java
@@ -0,0 +1,224 @@
+package com.vaadin.data.util;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.Container;
+import com.vaadin.data.Item;
+import com.vaadin.tests.util.TestUtil;
+
+public class TestContainerSorting extends TestCase {
+
+ private static final String ITEM_DATA_MINUS2_NULL = "Data -2 null";
+ private static final String ITEM_DATA_MINUS2 = "Data -2";
+ private static final String ITEM_DATA_MINUS1 = "Data -1";
+ private static final String ITEM_DATA_MINUS1_NULL = "Data -1 null";
+ private static final String ITEM_ANOTHER_NULL = "Another null";
+ private static final String ITEM_STRING_2 = "String 2";
+ private static final String ITEM_STRING_NULL2 = "String null";
+ private static final String ITEM_STRING_1 = "String 1";
+
+ private static final String PROPERTY_INTEGER_NULL2 = "integer-null";
+ private static final String PROPERTY_INTEGER_NOT_NULL = "integer-not-null";
+ private static final String PROPERTY_STRING_NULL = "string-null";
+ private static final String PROPERTY_STRING_ID = "string-not-null";
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ public void testEmptyFilteredIndexedContainer() {
+ IndexedContainer ic = new IndexedContainer();
+
+ addProperties(ic);
+ populate(ic);
+
+ ic.addContainerFilter(PROPERTY_STRING_ID, "aasdfasdfasdf", true, false);
+ ic.sort(new Object[] { PROPERTY_STRING_ID }, new boolean[] { true });
+
+ }
+
+ public void testFilteredIndexedContainer() {
+ IndexedContainer ic = new IndexedContainer();
+
+ addProperties(ic);
+ populate(ic);
+
+ ic.addContainerFilter(PROPERTY_STRING_ID, "a", true, false);
+ ic.sort(new Object[] { PROPERTY_STRING_ID }, new boolean[] { true });
+ verifyOrder(ic,
+ new String[] { ITEM_ANOTHER_NULL, ITEM_DATA_MINUS1,
+ ITEM_DATA_MINUS1_NULL, ITEM_DATA_MINUS2,
+ ITEM_DATA_MINUS2_NULL, });
+ }
+
+ public void testIndexedContainer() {
+ IndexedContainer ic = new IndexedContainer();
+
+ addProperties(ic);
+ populate(ic);
+
+ ic.sort(new Object[] { PROPERTY_STRING_ID }, new boolean[] { true });
+ verifyOrder(ic, new String[] { ITEM_ANOTHER_NULL, ITEM_DATA_MINUS1,
+ ITEM_DATA_MINUS1_NULL, ITEM_DATA_MINUS2, ITEM_DATA_MINUS2_NULL,
+ ITEM_STRING_1, ITEM_STRING_2, ITEM_STRING_NULL2 });
+
+ ic.sort(new Object[] { PROPERTY_INTEGER_NOT_NULL,
+ PROPERTY_INTEGER_NULL2, PROPERTY_STRING_ID }, new boolean[] {
+ true, false, true });
+ verifyOrder(ic, new String[] { ITEM_DATA_MINUS2, ITEM_DATA_MINUS2_NULL,
+ ITEM_DATA_MINUS1, ITEM_DATA_MINUS1_NULL, ITEM_ANOTHER_NULL,
+ ITEM_STRING_NULL2, ITEM_STRING_1, ITEM_STRING_2 });
+
+ ic.sort(new Object[] { PROPERTY_INTEGER_NOT_NULL,
+ PROPERTY_INTEGER_NULL2, PROPERTY_STRING_ID }, new boolean[] {
+ true, true, true });
+ verifyOrder(ic, new String[] { ITEM_DATA_MINUS2_NULL, ITEM_DATA_MINUS2,
+ ITEM_DATA_MINUS1_NULL, ITEM_DATA_MINUS1, ITEM_ANOTHER_NULL,
+ ITEM_STRING_NULL2, ITEM_STRING_1, ITEM_STRING_2 });
+
+ }
+
+ public void testHierarchicalContainer() {
+ HierarchicalContainer hc = new HierarchicalContainer();
+ populateContainer(hc);
+ hc.sort(new Object[] { "name" }, new boolean[] { true });
+ verifyOrder(hc, new String[] { "Audi", "C++", "Call of Duty", "Cars",
+ "English", "Fallout", "Finnish", "Ford", "Games", "Java",
+ "Might and Magic", "Natural languages", "PHP",
+ "Programming languages", "Python", "Red Alert", "Swedish",
+ "Toyota", "Volvo" });
+ TestUtil.assertArrays(
+ hc.rootItemIds().toArray(),
+ new Integer[] { nameToId.get("Cars"), nameToId.get("Games"),
+ nameToId.get("Natural languages"),
+ nameToId.get("Programming languages") });
+ TestUtil.assertArrays(
+ hc.getChildren(nameToId.get("Games")).toArray(),
+ new Integer[] { nameToId.get("Call of Duty"),
+ nameToId.get("Fallout"),
+ nameToId.get("Might and Magic"),
+ nameToId.get("Red Alert") });
+ }
+
+ private static void populateContainer(HierarchicalContainer container) {
+ container.addContainerProperty("name", String.class, null);
+
+ addItem(container, "Games", null);
+ addItem(container, "Call of Duty", "Games");
+ addItem(container, "Might and Magic", "Games");
+ addItem(container, "Fallout", "Games");
+ addItem(container, "Red Alert", "Games");
+
+ addItem(container, "Cars", null);
+ addItem(container, "Toyota", "Cars");
+ addItem(container, "Volvo", "Cars");
+ addItem(container, "Audi", "Cars");
+ addItem(container, "Ford", "Cars");
+
+ addItem(container, "Natural languages", null);
+ addItem(container, "Swedish", "Natural languages");
+ addItem(container, "English", "Natural languages");
+ addItem(container, "Finnish", "Natural languages");
+
+ addItem(container, "Programming languages", null);
+ addItem(container, "C++", "Programming languages");
+ addItem(container, "PHP", "Programming languages");
+ addItem(container, "Java", "Programming languages");
+ addItem(container, "Python", "Programming languages");
+
+ }
+
+ private static int index = 0;
+ private static Map<String, Integer> nameToId = new HashMap<String, Integer>();
+ private static Map<Integer, String> idToName = new HashMap<Integer, String>();
+
+ public static void addItem(IndexedContainer container, String string,
+ String parent) {
+ nameToId.put(string, index);
+ idToName.put(index, string);
+
+ Item item = container.addItem(index);
+ item.getItemProperty("name").setValue(string);
+
+ if (parent != null && container instanceof HierarchicalContainer) {
+ ((HierarchicalContainer) container).setParent(index,
+ nameToId.get(parent));
+ }
+
+ index++;
+ }
+
+ private void verifyOrder(Container.Sortable ic, Object[] idOrder) {
+ int size = ic.size();
+ Object[] actual = new Object[size];
+ Iterator<?> i = ic.getItemIds().iterator();
+ int index = 0;
+ while (i.hasNext()) {
+ Object o = i.next();
+ if (o.getClass() == Integer.class
+ && idOrder[index].getClass() == String.class) {
+ o = idToName.get(o);
+ }
+ actual[index++] = o;
+ }
+
+ TestUtil.assertArrays(actual, idOrder);
+
+ }
+
+ private void populate(IndexedContainer ic) {
+ addItem(ic, ITEM_STRING_1, ITEM_STRING_1, 1, 1);
+ addItem(ic, ITEM_STRING_NULL2, null, 0, null);
+ addItem(ic, ITEM_STRING_2, ITEM_STRING_2, 2, 2);
+ addItem(ic, ITEM_ANOTHER_NULL, null, 0, null);
+ addItem(ic, ITEM_DATA_MINUS1, ITEM_DATA_MINUS1, -1, -1);
+ addItem(ic, ITEM_DATA_MINUS1_NULL, null, -1, null);
+ addItem(ic, ITEM_DATA_MINUS2, ITEM_DATA_MINUS2, -2, -2);
+ addItem(ic, ITEM_DATA_MINUS2_NULL, null, -2, null);
+ }
+
+ private Item addItem(Container ic, String id, String string_null,
+ int integer, Integer integer_null) {
+ Item i = ic.addItem(id);
+ i.getItemProperty(PROPERTY_STRING_ID).setValue(id);
+ i.getItemProperty(PROPERTY_STRING_NULL).setValue(string_null);
+ i.getItemProperty(PROPERTY_INTEGER_NOT_NULL).setValue(integer);
+ i.getItemProperty(PROPERTY_INTEGER_NULL2).setValue(integer_null);
+
+ return i;
+ }
+
+ private void addProperties(IndexedContainer ic) {
+ ic.addContainerProperty("id", String.class, null);
+ ic.addContainerProperty(PROPERTY_STRING_ID, String.class, "");
+ ic.addContainerProperty(PROPERTY_STRING_NULL, String.class, null);
+ ic.addContainerProperty(PROPERTY_INTEGER_NULL2, Integer.class, null);
+ ic.addContainerProperty(PROPERTY_INTEGER_NOT_NULL, Integer.class, 0);
+ ic.addContainerProperty("comparable-null", Integer.class, 0);
+ }
+
+ public class MyObject implements Comparable<MyObject> {
+ private String data;
+
+ @Override
+ public int compareTo(MyObject o) {
+ if (o == null) {
+ return 1;
+ }
+
+ if (o.data == null) {
+ return data == null ? 0 : 1;
+ } else if (data == null) {
+ return -1;
+ } else {
+ return data.compareTo(o.data);
+ }
+ }
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/data/util/TestHierarchicalContainer.java b/server/tests/src/com/vaadin/data/util/TestHierarchicalContainer.java
new file mode 100644
index 0000000000..10bc71c3a7
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/TestHierarchicalContainer.java
@@ -0,0 +1,263 @@
+package com.vaadin.data.util;
+
+import com.vaadin.data.Container.Filter;
+import com.vaadin.data.Item;
+
+public class TestHierarchicalContainer extends
+ AbstractHierarchicalContainerTest {
+
+ public void testBasicOperations() {
+ testBasicContainerOperations(new HierarchicalContainer());
+ }
+
+ public void testFiltering() {
+ testContainerFiltering(new HierarchicalContainer());
+ }
+
+ public void testSorting() {
+ testContainerSorting(new HierarchicalContainer());
+ }
+
+ public void testOrdered() {
+ testContainerOrdered(new HierarchicalContainer());
+ }
+
+ public void testHierarchicalSorting() {
+ testHierarchicalSorting(new HierarchicalContainer());
+ }
+
+ public void testSortingAndFiltering() {
+ testContainerSortingAndFiltering(new HierarchicalContainer());
+ }
+
+ public void testRemovingItemsFromFilteredContainer() {
+ HierarchicalContainer container = new HierarchicalContainer();
+ initializeContainer(container);
+ container.setIncludeParentsWhenFiltering(true);
+ container.addContainerFilter(FULLY_QUALIFIED_NAME, "ab", false, false);
+ Object p1 = container.getParent("com.vaadin.ui.TabSheet");
+ assertEquals("com.vaadin.ui", p1);
+
+ container.removeItem("com.vaadin.ui.TabSheet");
+ // Parent for the removed item must be null because the item is no
+ // longer in the container
+ p1 = container.getParent("com.vaadin.ui.TabSheet");
+ assertNull("Parent should be null, is " + p1, p1);
+
+ container.removeAllItems();
+ p1 = container.getParent("com.vaadin.client.Focusable");
+ assertNull("Parent should be null, is " + p1, p1);
+
+ }
+
+ public void testParentWhenRemovingFilterFromContainer() {
+ HierarchicalContainer container = new HierarchicalContainer();
+ initializeContainer(container);
+ container.setIncludeParentsWhenFiltering(true);
+ container.addContainerFilter(FULLY_QUALIFIED_NAME, "ab", false, false);
+ Object p1 = container.getParent("com.vaadin.ui.TabSheet");
+ assertEquals("com.vaadin.ui", p1);
+ p1 = container.getParent("com.vaadin.client.ui.VPopupCalendar");
+ assertNull(p1);
+ container.removeAllContainerFilters();
+ p1 = container.getParent("com.vaadin.client.ui.VPopupCalendar");
+ assertEquals("com.vaadin.client.ui", p1);
+
+ }
+
+ public void testChangeParentInFilteredContainer() {
+ HierarchicalContainer container = new HierarchicalContainer();
+ initializeContainer(container);
+ container.setIncludeParentsWhenFiltering(true);
+ container.addContainerFilter(FULLY_QUALIFIED_NAME, "Tab", false, false);
+
+ // Change parent of filtered item
+ Object p1 = container.getParent("com.vaadin.ui.TabSheet");
+ assertEquals("com.vaadin.ui", p1);
+ container.setParent("com.vaadin.ui.TabSheet", "com.vaadin");
+ p1 = container.getParent("com.vaadin.ui.TabSheet");
+ assertEquals("com.vaadin", p1);
+ container.setParent("com.vaadin.ui.TabSheet", "com");
+ p1 = container.getParent("com.vaadin.ui.TabSheet");
+ assertEquals("com", p1);
+ container.setParent("com.vaadin.ui.TabSheet", null);
+ p1 = container.getParent("com.vaadin.ui.TabSheet");
+ assertNull(p1);
+
+ // root -> non-root
+ container.setParent("com.vaadin.ui.TabSheet", "com");
+ p1 = container.getParent("com.vaadin.ui.TabSheet");
+ assertEquals("com", p1);
+
+ }
+
+ public void testHierarchicalFilteringWithParents() {
+ HierarchicalContainer container = new HierarchicalContainer();
+ initializeContainer(container);
+ container.setIncludeParentsWhenFiltering(true);
+
+ // Filter by "contains ab"
+ container.addContainerFilter(FULLY_QUALIFIED_NAME, "ab", false, false);
+
+ // 20 items match the filters and the have 8 parents that should also be
+ // included
+ // only one root "com" should exist
+ // filtered
+ int expectedSize = 29;
+ int expectedRoots = 1;
+
+ validateHierarchicalContainer(container, "com",
+ "com.vaadin.ui.TabSheet", "com.vaadin.client.Focusable",
+ "blah", true, expectedSize, expectedRoots, true);
+
+ // only include .gwt.client classes
+ container.removeAllContainerFilters();
+ container.addContainerFilter(FULLY_QUALIFIED_NAME, ".gwt.client.",
+ false, false);
+
+ int packages = 6;
+ int classes = 112;
+
+ expectedSize = packages + classes;
+ expectedRoots = 1;
+
+ validateHierarchicalContainer(container, "com",
+ "com.vaadin.client.WidgetSet",
+ "com.vaadin.client.ui.VSplitPanelVertical", "blah", true,
+ expectedSize, expectedRoots, true);
+
+ // Additionally remove all without 'm' in the simple name.
+ container.addContainerFilter(SIMPLE_NAME, "m", false, false);
+
+ expectedSize = 7 + 18;
+ expectedRoots = 1;
+
+ validateHierarchicalContainer(container, "com",
+ "com.vaadin.client.ui.VUriFragmentUtility",
+ "com.vaadin.client.ui.layout.ChildComponentContainer", "blah",
+ true, expectedSize, expectedRoots, true);
+
+ }
+
+ public void testRemoveLastChild() {
+ HierarchicalContainer c = new HierarchicalContainer();
+
+ c.addItem("root");
+ assertEquals(false, c.hasChildren("root"));
+
+ c.addItem("child");
+ c.setParent("child", "root");
+ assertEquals(true, c.hasChildren("root"));
+
+ c.removeItem("child");
+ assertFalse(c.containsId("child"));
+ assertNull(c.getChildren("root"));
+ assertNull(c.getChildren("child"));
+ assertFalse(c.hasChildren("child"));
+ assertFalse(c.hasChildren("root"));
+ }
+
+ public void testRemoveLastChildFromFiltered() {
+ HierarchicalContainer c = new HierarchicalContainer();
+
+ c.addItem("root");
+ assertEquals(false, c.hasChildren("root"));
+
+ c.addItem("child");
+ c.setParent("child", "root");
+ assertEquals(true, c.hasChildren("root"));
+
+ // Dummy filter that does not remove any items
+ c.addContainerFilter(new Filter() {
+
+ @Override
+ public boolean passesFilter(Object itemId, Item item)
+ throws UnsupportedOperationException {
+ return true;
+ }
+
+ @Override
+ public boolean appliesToProperty(Object propertyId) {
+ return true;
+ }
+ });
+ c.removeItem("child");
+
+ assertFalse(c.containsId("child"));
+ assertNull(c.getChildren("root"));
+ assertNull(c.getChildren("child"));
+ assertFalse(c.hasChildren("child"));
+ assertFalse(c.hasChildren("root"));
+ }
+
+ public void testHierarchicalFilteringWithoutParents() {
+ HierarchicalContainer container = new HierarchicalContainer();
+
+ initializeContainer(container);
+ container.setIncludeParentsWhenFiltering(false);
+
+ // Filter by "contains ab"
+ container.addContainerFilter(SIMPLE_NAME, "ab", false, false);
+
+ // 20 items match the filter.
+ // com.vaadin.data.BufferedValidatable
+ // com.vaadin.data.Validatable
+ // com.vaadin.client.Focusable
+ // com.vaadin.client.Paintable
+ // com.vaadin.client.ui.Table
+ // com.vaadin.client.ui.VLabel
+ // com.vaadin.client.ui.VScrollTable
+ // com.vaadin.client.ui.VTablePaging
+ // com.vaadin.client.ui.VTabsheet
+ // com.vaadin.client.ui.VTabsheetBase
+ // com.vaadin.client.ui.VTabsheetPanel
+ // com.vaadin.server.ChangeVariablesErrorEvent
+ // com.vaadin.server.Paintable
+ // com.vaadin.server.Scrollable
+ // com.vaadin.server.Sizeable
+ // com.vaadin.server.VariableOwner
+ // com.vaadin.ui.Label
+ // com.vaadin.ui.Table
+ // com.vaadin.ui.TableFieldFactory
+ // com.vaadin.ui.TabSheet
+ // all become roots.
+ int expectedSize = 20;
+ int expectedRoots = 20;
+
+ validateHierarchicalContainer(container,
+ "com.vaadin.data.BufferedValidatable",
+ "com.vaadin.ui.TabSheet", "com.vaadin.client.ui.VTabsheetBase",
+ "blah", true, expectedSize, expectedRoots, false);
+
+ // only include .gwt.client classes
+ container.removeAllContainerFilters();
+ container.addContainerFilter(FULLY_QUALIFIED_NAME, ".gwt.client.",
+ false, false);
+
+ int packages = 3;
+ int classes = 110;
+
+ expectedSize = packages + classes;
+ expectedRoots = 35 + 1; // com.vaadin.client.ui +
+ // com.vaadin.client.*
+
+ // Sorting is case insensitive
+ validateHierarchicalContainer(container,
+ "com.vaadin.client.ApplicationConfiguration",
+ "com.vaadin.client.WidgetSet",
+ "com.vaadin.client.ui.VOptionGroup", "blah", true,
+ expectedSize, expectedRoots, false);
+
+ // Additionally remove all without 'P' in the simple name.
+ container.addContainerFilter(SIMPLE_NAME, "P", false, false);
+
+ expectedSize = 13;
+ expectedRoots = expectedSize;
+
+ validateHierarchicalContainer(container, "com.vaadin.client.Paintable",
+ "com.vaadin.client.ui.VTabsheetPanel",
+ "com.vaadin.client.ui.VPopupCalendar", "blah", true,
+ expectedSize, expectedRoots, false);
+
+ }
+}
diff --git a/server/tests/src/com/vaadin/data/util/TestIndexedContainer.java b/server/tests/src/com/vaadin/data/util/TestIndexedContainer.java
new file mode 100644
index 0000000000..156ff83883
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/TestIndexedContainer.java
@@ -0,0 +1,271 @@
+package com.vaadin.data.util;
+
+import com.vaadin.data.Item;
+import com.vaadin.data.util.IndexedContainer;
+
+public class TestIndexedContainer extends AbstractInMemoryContainerTest {
+
+ public void testBasicOperations() {
+ testBasicContainerOperations(new IndexedContainer());
+ }
+
+ public void testFiltering() {
+ testContainerFiltering(new IndexedContainer());
+ }
+
+ public void testSorting() {
+ testContainerSorting(new IndexedContainer());
+ }
+
+ public void testSortingAndFiltering() {
+ testContainerSortingAndFiltering(new IndexedContainer());
+ }
+
+ public void testContainerOrdered() {
+ testContainerOrdered(new IndexedContainer());
+ }
+
+ public void testContainerIndexed() {
+ testContainerIndexed(new IndexedContainer(), sampleData[2], 2, true,
+ "newItemId", true);
+ }
+
+ public void testItemSetChangeListeners() {
+ IndexedContainer container = new IndexedContainer();
+ ItemSetChangeCounter counter = new ItemSetChangeCounter();
+ container.addListener(counter);
+
+ String id1 = "id1";
+ String id2 = "id2";
+ String id3 = "id3";
+
+ initializeContainer(container);
+ counter.reset();
+ container.addItem();
+ counter.assertOnce();
+ container.addItem(id1);
+ counter.assertOnce();
+
+ initializeContainer(container);
+ counter.reset();
+ container.addItemAt(0);
+ counter.assertOnce();
+ container.addItemAt(0, id1);
+ counter.assertOnce();
+ container.addItemAt(0, id2);
+ counter.assertOnce();
+ container.addItemAt(container.size(), id3);
+ counter.assertOnce();
+ // no notification if already in container
+ container.addItemAt(0, id1);
+ counter.assertNone();
+
+ initializeContainer(container);
+ counter.reset();
+ container.addItemAfter(null);
+ counter.assertOnce();
+ container.addItemAfter(null, id1);
+ counter.assertOnce();
+ container.addItemAfter(id1);
+ counter.assertOnce();
+ container.addItemAfter(id1, id2);
+ counter.assertOnce();
+ container.addItemAfter(container.firstItemId());
+ counter.assertOnce();
+ container.addItemAfter(container.lastItemId());
+ counter.assertOnce();
+ container.addItemAfter(container.lastItemId(), id3);
+ counter.assertOnce();
+ // no notification if already in container
+ container.addItemAfter(0, id1);
+ counter.assertNone();
+
+ initializeContainer(container);
+ counter.reset();
+ container.removeItem(sampleData[0]);
+ counter.assertOnce();
+
+ initializeContainer(container);
+ counter.reset();
+ // no notification for removing a non-existing item
+ container.removeItem(id1);
+ counter.assertNone();
+
+ initializeContainer(container);
+ counter.reset();
+ container.removeAllItems();
+ counter.assertOnce();
+ // already empty
+ container.removeAllItems();
+ counter.assertNone();
+
+ }
+
+ public void testAddRemoveContainerFilter() {
+ IndexedContainer container = new IndexedContainer();
+ ItemSetChangeCounter counter = new ItemSetChangeCounter();
+ container.addListener(counter);
+
+ // simply adding or removing container filters should cause events
+ // (content changes)
+
+ initializeContainer(container);
+ counter.reset();
+ container.addContainerFilter(SIMPLE_NAME, "a", true, false);
+ counter.assertOnce();
+ container.removeContainerFilters(SIMPLE_NAME);
+ counter.assertOnce();
+ container.addContainerFilter(SIMPLE_NAME, "a", true, false);
+ counter.assertOnce();
+ container.removeAllContainerFilters();
+ counter.assertOnce();
+ }
+
+ // TODO other tests should check positions after removing filter etc,
+ // here concentrating on listeners
+ public void testItemSetChangeListenersFiltering() {
+ IndexedContainer container = new IndexedContainer();
+ ItemSetChangeCounter counter = new ItemSetChangeCounter();
+ container.addListener(counter);
+
+ counter.reset();
+ container.addContainerFilter(FULLY_QUALIFIED_NAME, "Test", true, false);
+ // no real change, so no notification required
+ counter.assertNone();
+
+ String id1 = "com.example.Test1";
+ String id2 = "com.example.Test2";
+ String id3 = "com.example.Other";
+
+ // perform operations while filtering container
+
+ Item item;
+
+ initializeContainer(container);
+ counter.reset();
+ // passes filter
+ item = container.addItem(id1);
+ // no event if filtered out
+ counter.assertNone();
+ item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id1);
+ counter.assertOnce();
+ // passes filter but already in the container
+ item = container.addItem(id1);
+ counter.assertNone();
+
+ initializeContainer(container);
+ counter.reset();
+ // passes filter after change
+ item = container.addItemAt(0, id1);
+ counter.assertNone();
+ item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id1);
+ counter.assertOnce();
+ item = container.addItemAt(container.size(), id2);
+ counter.assertNone();
+ item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id2);
+ counter.assertOnce();
+ // passes filter but already in the container
+ item = container.addItemAt(0, id1);
+ counter.assertNone();
+ item = container.addItemAt(container.size(), id2);
+ counter.assertNone();
+
+ initializeContainer(container);
+ counter.reset();
+ // passes filter
+ item = container.addItemAfter(null, id1);
+ counter.assertNone();
+ item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id1);
+ counter.assertOnce();
+ item = container.addItemAfter(container.lastItemId(), id2);
+ counter.assertNone();
+ item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id2);
+ counter.assertOnce();
+ // passes filter but already in the container
+ item = container.addItemAfter(null, id1);
+ counter.assertNone();
+ item = container.addItemAfter(container.lastItemId(), id2);
+ counter.assertNone();
+
+ // does not pass filter
+
+ // TODO implement rest
+
+ initializeContainer(container);
+ counter.reset();
+ item = container.addItemAfter(null, id3);
+ counter.assertNone();
+ item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id3);
+ counter.assertNone();
+
+ initializeContainer(container);
+ counter.reset();
+ item = container.addItemAfter(container.firstItemId(), id3);
+ counter.assertNone();
+ item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id3);
+ counter.assertNone();
+
+ initializeContainer(container);
+ counter.reset();
+ item = container.addItemAfter(container.lastItemId(), id3);
+ counter.assertNone();
+ item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id3);
+ counter.assertNone();
+
+ initializeContainer(container);
+ counter.reset();
+ item = container.addItemAt(0, id3);
+ counter.assertNone();
+ item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id3);
+ counter.assertNone();
+
+ initializeContainer(container);
+ counter.reset();
+ item = container.addItemAt(1, id3);
+ counter.assertNone();
+ item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id3);
+ counter.assertNone();
+
+ initializeContainer(container);
+ counter.reset();
+ item = container.addItemAt(container.size(), id3);
+ counter.assertNone();
+ item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id3);
+ counter.assertNone();
+
+ // passes filter
+
+ initializeContainer(container);
+ counter.reset();
+ item = container.addItem(id1);
+ counter.assertNone();
+ item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id1);
+ counter.assertOnce();
+ container.removeItem(id1);
+ counter.assertOnce();
+ // already removed
+ container.removeItem(id1);
+ counter.assertNone();
+
+ item = container.addItem(id3);
+ counter.assertNone();
+ item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id3);
+ counter.assertNone();
+ // not visible
+ container.removeItem(id3);
+ counter.assertNone();
+
+ // remove all
+
+ initializeContainer(container);
+ item = container.addItem(id1);
+ item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id1);
+ counter.reset();
+ container.removeAllItems();
+ counter.assertOnce();
+ // no visible items
+ container.removeAllItems();
+ counter.assertNone();
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/data/util/filter/AbstractFilterTest.java b/server/tests/src/com/vaadin/data/util/filter/AbstractFilterTest.java
new file mode 100644
index 0000000000..6f96c3a51a
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/filter/AbstractFilterTest.java
@@ -0,0 +1,97 @@
+package com.vaadin.data.util.filter;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.Container.Filter;
+import com.vaadin.data.Item;
+import com.vaadin.data.Property;
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.data.util.PropertysetItem;
+
+public abstract class AbstractFilterTest<FILTERTYPE extends Filter> extends
+ TestCase {
+
+ protected static final String PROPERTY1 = "property1";
+ protected static final String PROPERTY2 = "property2";
+
+ protected static class TestItem<T1, T2> extends PropertysetItem {
+
+ public TestItem(T1 value1, T2 value2) {
+ addItemProperty(PROPERTY1, new ObjectProperty<T1>(value1));
+ addItemProperty(PROPERTY2, new ObjectProperty<T2>(value2));
+ }
+ }
+
+ protected static class NullProperty implements Property<String> {
+
+ @Override
+ public String getValue() {
+ return null;
+ }
+
+ @Override
+ public void setValue(Object newValue) throws ReadOnlyException {
+ throw new ReadOnlyException();
+ }
+
+ @Override
+ public Class<String> getType() {
+ return String.class;
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return true;
+ }
+
+ @Override
+ public void setReadOnly(boolean newStatus) {
+ // do nothing
+ }
+
+ }
+
+ public static class SameItemFilter implements Filter {
+
+ private final Item item;
+ private final Object propertyId;
+
+ public SameItemFilter(Item item) {
+ this(item, "");
+ }
+
+ public SameItemFilter(Item item, Object propertyId) {
+ this.item = item;
+ this.propertyId = propertyId;
+ }
+
+ @Override
+ public boolean passesFilter(Object itemId, Item item)
+ throws UnsupportedOperationException {
+ return this.item == item;
+ }
+
+ @Override
+ public boolean appliesToProperty(Object propertyId) {
+ return this.propertyId != null ? this.propertyId.equals(propertyId)
+ : true;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null || !getClass().equals(obj.getClass())) {
+ return false;
+ }
+ SameItemFilter other = (SameItemFilter) obj;
+ return item == other.item
+ && (propertyId == null ? other.propertyId == null
+ : propertyId.equals(other.propertyId));
+ }
+
+ @Override
+ public int hashCode() {
+ return item.hashCode();
+ }
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/data/util/filter/AndOrFilterTest.java b/server/tests/src/com/vaadin/data/util/filter/AndOrFilterTest.java
new file mode 100644
index 0000000000..fdd5b8a645
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/filter/AndOrFilterTest.java
@@ -0,0 +1,232 @@
+package com.vaadin.data.util.filter;
+
+import junit.framework.Assert;
+
+import com.vaadin.data.Container.Filter;
+import com.vaadin.data.Item;
+import com.vaadin.data.util.BeanItem;
+
+public class AndOrFilterTest extends AbstractFilterTest<AbstractJunctionFilter> {
+
+ protected Item item1 = new BeanItem<Integer>(1);
+ protected Item item2 = new BeanItem<Integer>(2);
+
+ public void testNoFilterAnd() {
+ Filter filter = new And();
+
+ Assert.assertTrue(filter.passesFilter(null, item1));
+ }
+
+ public void testSingleFilterAnd() {
+ Filter filter = new And(new SameItemFilter(item1));
+
+ Assert.assertTrue(filter.passesFilter(null, item1));
+ Assert.assertFalse(filter.passesFilter(null, item2));
+ }
+
+ public void testTwoFilterAnd() {
+ Filter filter1 = new And(new SameItemFilter(item1), new SameItemFilter(
+ item1));
+ Filter filter2 = new And(new SameItemFilter(item1), new SameItemFilter(
+ item2));
+
+ Assert.assertTrue(filter1.passesFilter(null, item1));
+ Assert.assertFalse(filter1.passesFilter(null, item2));
+
+ Assert.assertFalse(filter2.passesFilter(null, item1));
+ Assert.assertFalse(filter2.passesFilter(null, item2));
+ }
+
+ public void testThreeFilterAnd() {
+ Filter filter1 = new And(new SameItemFilter(item1), new SameItemFilter(
+ item1), new SameItemFilter(item1));
+ Filter filter2 = new And(new SameItemFilter(item1), new SameItemFilter(
+ item1), new SameItemFilter(item2));
+
+ Assert.assertTrue(filter1.passesFilter(null, item1));
+ Assert.assertFalse(filter1.passesFilter(null, item2));
+
+ Assert.assertFalse(filter2.passesFilter(null, item1));
+ Assert.assertFalse(filter2.passesFilter(null, item2));
+ }
+
+ public void testNoFilterOr() {
+ Filter filter = new Or();
+
+ Assert.assertFalse(filter.passesFilter(null, item1));
+ }
+
+ public void testSingleFilterOr() {
+ Filter filter = new Or(new SameItemFilter(item1));
+
+ Assert.assertTrue(filter.passesFilter(null, item1));
+ Assert.assertFalse(filter.passesFilter(null, item2));
+ }
+
+ public void testTwoFilterOr() {
+ Filter filter1 = new Or(new SameItemFilter(item1), new SameItemFilter(
+ item1));
+ Filter filter2 = new Or(new SameItemFilter(item1), new SameItemFilter(
+ item2));
+
+ Assert.assertTrue(filter1.passesFilter(null, item1));
+ Assert.assertFalse(filter1.passesFilter(null, item2));
+
+ Assert.assertTrue(filter2.passesFilter(null, item1));
+ Assert.assertTrue(filter2.passesFilter(null, item2));
+ }
+
+ public void testThreeFilterOr() {
+ Filter filter1 = new Or(new SameItemFilter(item1), new SameItemFilter(
+ item1), new SameItemFilter(item1));
+ Filter filter2 = new Or(new SameItemFilter(item1), new SameItemFilter(
+ item1), new SameItemFilter(item2));
+
+ Assert.assertTrue(filter1.passesFilter(null, item1));
+ Assert.assertFalse(filter1.passesFilter(null, item2));
+
+ Assert.assertTrue(filter2.passesFilter(null, item1));
+ Assert.assertTrue(filter2.passesFilter(null, item2));
+ }
+
+ public void testAndEqualsHashCode() {
+ Filter filter0 = new And();
+ Filter filter0b = new And();
+ Filter filter1a = new And(new SameItemFilter(item1));
+ Filter filter1a2 = new And(new SameItemFilter(item1));
+ Filter filter1b = new And(new SameItemFilter(item2));
+ Filter filter2a = new And(new SameItemFilter(item1),
+ new SameItemFilter(item1));
+ Filter filter2b = new And(new SameItemFilter(item1),
+ new SameItemFilter(item2));
+ Filter filter2b2 = new And(new SameItemFilter(item1),
+ new SameItemFilter(item2));
+ Filter other0 = new Or();
+ Filter other1 = new Or(new SameItemFilter(item1));
+
+ Assert.assertEquals(filter0, filter0);
+ Assert.assertEquals(filter0, filter0b);
+ Assert.assertFalse(filter0.equals(filter1a));
+ Assert.assertFalse(filter0.equals(other0));
+ Assert.assertFalse(filter0.equals(other1));
+
+ Assert.assertFalse(filter1a.equals(filter1b));
+ Assert.assertFalse(filter1a.equals(other1));
+
+ Assert.assertFalse(filter1a.equals(filter2a));
+ Assert.assertFalse(filter2a.equals(filter1a));
+
+ Assert.assertFalse(filter2a.equals(filter2b));
+ Assert.assertEquals(filter2b, filter2b2);
+
+ // hashCode()
+ Assert.assertEquals(filter0.hashCode(), filter0.hashCode());
+ Assert.assertEquals(filter0.hashCode(), filter0b.hashCode());
+ Assert.assertEquals(filter1a.hashCode(), filter1a.hashCode());
+ Assert.assertEquals(filter1a.hashCode(), filter1a2.hashCode());
+ Assert.assertEquals(filter2a.hashCode(), filter2a.hashCode());
+ Assert.assertEquals(filter2b.hashCode(), filter2b2.hashCode());
+ }
+
+ public void testOrEqualsHashCode() {
+ Filter filter0 = new Or();
+ Filter filter0b = new Or();
+ Filter filter1a = new Or(new SameItemFilter(item1));
+ Filter filter1a2 = new Or(new SameItemFilter(item1));
+ Filter filter1b = new Or(new SameItemFilter(item2));
+ Filter filter2a = new Or(new SameItemFilter(item1), new SameItemFilter(
+ item1));
+ Filter filter2b = new Or(new SameItemFilter(item1), new SameItemFilter(
+ item2));
+ Filter filter2b2 = new Or(new SameItemFilter(item1),
+ new SameItemFilter(item2));
+ Filter other0 = new And();
+ Filter other1 = new And(new SameItemFilter(item1));
+
+ Assert.assertEquals(filter0, filter0);
+ Assert.assertEquals(filter0, filter0b);
+ Assert.assertFalse(filter0.equals(filter1a));
+ Assert.assertFalse(filter0.equals(other0));
+ Assert.assertFalse(filter0.equals(other1));
+
+ Assert.assertFalse(filter1a.equals(filter1b));
+ Assert.assertFalse(filter1a.equals(other1));
+
+ Assert.assertFalse(filter1a.equals(filter2a));
+ Assert.assertFalse(filter2a.equals(filter1a));
+
+ Assert.assertFalse(filter2a.equals(filter2b));
+ Assert.assertEquals(filter2b, filter2b2);
+
+ // hashCode()
+ Assert.assertEquals(filter0.hashCode(), filter0.hashCode());
+ Assert.assertEquals(filter0.hashCode(), filter0b.hashCode());
+ Assert.assertEquals(filter1a.hashCode(), filter1a.hashCode());
+ Assert.assertEquals(filter1a.hashCode(), filter1a2.hashCode());
+ Assert.assertEquals(filter2a.hashCode(), filter2a.hashCode());
+ Assert.assertEquals(filter2b.hashCode(), filter2b2.hashCode());
+ }
+
+ public void testAndAppliesToProperty() {
+ Filter filter0 = new And();
+ Filter filter1a = new And(new SameItemFilter(item1, "a"));
+ Filter filter1b = new And(new SameItemFilter(item1, "b"));
+ Filter filter2aa = new And(new SameItemFilter(item1, "a"),
+ new SameItemFilter(item1, "a"));
+ Filter filter2ab = new And(new SameItemFilter(item1, "a"),
+ new SameItemFilter(item1, "b"));
+ Filter filter3abc = new And(new SameItemFilter(item1, "a"),
+ new SameItemFilter(item1, "b"), new SameItemFilter(item1, "c"));
+
+ // empty And does not filter out anything
+ Assert.assertFalse(filter0.appliesToProperty("a"));
+ Assert.assertFalse(filter0.appliesToProperty("d"));
+
+ Assert.assertTrue(filter1a.appliesToProperty("a"));
+ Assert.assertFalse(filter1a.appliesToProperty("b"));
+ Assert.assertFalse(filter1b.appliesToProperty("a"));
+ Assert.assertTrue(filter1b.appliesToProperty("b"));
+
+ Assert.assertTrue(filter2aa.appliesToProperty("a"));
+ Assert.assertFalse(filter2aa.appliesToProperty("b"));
+ Assert.assertTrue(filter2ab.appliesToProperty("a"));
+ Assert.assertTrue(filter2ab.appliesToProperty("b"));
+
+ Assert.assertTrue(filter3abc.appliesToProperty("a"));
+ Assert.assertTrue(filter3abc.appliesToProperty("b"));
+ Assert.assertTrue(filter3abc.appliesToProperty("c"));
+ Assert.assertFalse(filter3abc.appliesToProperty("d"));
+ }
+
+ public void testOrAppliesToProperty() {
+ Filter filter0 = new Or();
+ Filter filter1a = new Or(new SameItemFilter(item1, "a"));
+ Filter filter1b = new Or(new SameItemFilter(item1, "b"));
+ Filter filter2aa = new Or(new SameItemFilter(item1, "a"),
+ new SameItemFilter(item1, "a"));
+ Filter filter2ab = new Or(new SameItemFilter(item1, "a"),
+ new SameItemFilter(item1, "b"));
+ Filter filter3abc = new Or(new SameItemFilter(item1, "a"),
+ new SameItemFilter(item1, "b"), new SameItemFilter(item1, "c"));
+
+ // empty Or filters out everything
+ Assert.assertTrue(filter0.appliesToProperty("a"));
+ Assert.assertTrue(filter0.appliesToProperty("d"));
+
+ Assert.assertTrue(filter1a.appliesToProperty("a"));
+ Assert.assertFalse(filter1a.appliesToProperty("b"));
+ Assert.assertFalse(filter1b.appliesToProperty("a"));
+ Assert.assertTrue(filter1b.appliesToProperty("b"));
+
+ Assert.assertTrue(filter2aa.appliesToProperty("a"));
+ Assert.assertFalse(filter2aa.appliesToProperty("b"));
+ Assert.assertTrue(filter2ab.appliesToProperty("a"));
+ Assert.assertTrue(filter2ab.appliesToProperty("b"));
+
+ Assert.assertTrue(filter3abc.appliesToProperty("a"));
+ Assert.assertTrue(filter3abc.appliesToProperty("b"));
+ Assert.assertTrue(filter3abc.appliesToProperty("c"));
+ Assert.assertFalse(filter3abc.appliesToProperty("d"));
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/data/util/filter/CompareFilterTest.java b/server/tests/src/com/vaadin/data/util/filter/CompareFilterTest.java
new file mode 100644
index 0000000000..99e8429a51
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/filter/CompareFilterTest.java
@@ -0,0 +1,260 @@
+package com.vaadin.data.util.filter;
+
+import java.util.Date;
+
+import junit.framework.Assert;
+
+import com.vaadin.data.Container.Filter;
+import com.vaadin.data.Item;
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.data.util.PropertysetItem;
+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;
+
+public class CompareFilterTest extends AbstractFilterTest<Compare> {
+
+ protected Item itemNull;
+ protected Item itemEmpty;
+ protected Item itemA;
+ protected Item itemB;
+ protected Item itemC;
+
+ protected final Filter equalB = new Equal(PROPERTY1, "b");
+ protected final Filter greaterB = new Greater(PROPERTY1, "b");
+ protected final Filter lessB = new Less(PROPERTY1, "b");
+ protected final Filter greaterEqualB = new GreaterOrEqual(PROPERTY1, "b");
+ protected final Filter lessEqualB = new LessOrEqual(PROPERTY1, "b");
+
+ protected final Filter equalNull = new Equal(PROPERTY1, null);
+ protected final Filter greaterNull = new Greater(PROPERTY1, null);
+ protected final Filter lessNull = new Less(PROPERTY1, null);
+ protected final Filter greaterEqualNull = new GreaterOrEqual(PROPERTY1,
+ null);
+ protected final Filter lessEqualNull = new LessOrEqual(PROPERTY1, null);
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ itemNull = new PropertysetItem();
+ itemNull.addItemProperty(PROPERTY1, new ObjectProperty<String>(null,
+ String.class));
+ itemEmpty = new PropertysetItem();
+ itemEmpty.addItemProperty(PROPERTY1, new ObjectProperty<String>("",
+ String.class));
+ itemA = new PropertysetItem();
+ itemA.addItemProperty(PROPERTY1, new ObjectProperty<String>("a",
+ String.class));
+ itemB = new PropertysetItem();
+ itemB.addItemProperty(PROPERTY1, new ObjectProperty<String>("b",
+ String.class));
+ itemC = new PropertysetItem();
+ itemC.addItemProperty(PROPERTY1, new ObjectProperty<String>("c",
+ String.class));
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ itemNull = null;
+ itemEmpty = null;
+ itemA = null;
+ itemB = null;
+ }
+
+ public void testCompareString() {
+ Assert.assertFalse(equalB.passesFilter(null, itemEmpty));
+ Assert.assertFalse(equalB.passesFilter(null, itemA));
+ Assert.assertTrue(equalB.passesFilter(null, itemB));
+ Assert.assertFalse(equalB.passesFilter(null, itemC));
+
+ Assert.assertFalse(greaterB.passesFilter(null, itemEmpty));
+ Assert.assertFalse(greaterB.passesFilter(null, itemA));
+ Assert.assertFalse(greaterB.passesFilter(null, itemB));
+ Assert.assertTrue(greaterB.passesFilter(null, itemC));
+
+ Assert.assertTrue(lessB.passesFilter(null, itemEmpty));
+ Assert.assertTrue(lessB.passesFilter(null, itemA));
+ Assert.assertFalse(lessB.passesFilter(null, itemB));
+ Assert.assertFalse(lessB.passesFilter(null, itemC));
+
+ Assert.assertFalse(greaterEqualB.passesFilter(null, itemEmpty));
+ Assert.assertFalse(greaterEqualB.passesFilter(null, itemA));
+ Assert.assertTrue(greaterEqualB.passesFilter(null, itemB));
+ Assert.assertTrue(greaterEqualB.passesFilter(null, itemC));
+
+ Assert.assertTrue(lessEqualB.passesFilter(null, itemEmpty));
+ Assert.assertTrue(lessEqualB.passesFilter(null, itemA));
+ Assert.assertTrue(lessEqualB.passesFilter(null, itemB));
+ Assert.assertFalse(lessEqualB.passesFilter(null, itemC));
+ }
+
+ public void testCompareWithNull() {
+ // null comparisons: null is less than any other value
+ Assert.assertFalse(equalB.passesFilter(null, itemNull));
+ Assert.assertTrue(greaterB.passesFilter(null, itemNull));
+ Assert.assertFalse(lessB.passesFilter(null, itemNull));
+ Assert.assertTrue(greaterEqualB.passesFilter(null, itemNull));
+ Assert.assertFalse(lessEqualB.passesFilter(null, itemNull));
+
+ Assert.assertTrue(equalNull.passesFilter(null, itemNull));
+ Assert.assertFalse(greaterNull.passesFilter(null, itemNull));
+ Assert.assertFalse(lessNull.passesFilter(null, itemNull));
+ Assert.assertTrue(greaterEqualNull.passesFilter(null, itemNull));
+ Assert.assertTrue(lessEqualNull.passesFilter(null, itemNull));
+
+ Assert.assertFalse(equalNull.passesFilter(null, itemA));
+ Assert.assertFalse(greaterNull.passesFilter(null, itemA));
+ Assert.assertTrue(lessNull.passesFilter(null, itemA));
+ Assert.assertFalse(greaterEqualNull.passesFilter(null, itemA));
+ Assert.assertTrue(lessEqualNull.passesFilter(null, itemA));
+ }
+
+ public void testCompareInteger() {
+ int negative = -1;
+ int zero = 0;
+ int positive = 1;
+
+ Item itemNegative = new PropertysetItem();
+ itemNegative.addItemProperty(PROPERTY1, new ObjectProperty<Integer>(
+ negative, Integer.class));
+ Item itemZero = new PropertysetItem();
+ itemZero.addItemProperty(PROPERTY1, new ObjectProperty<Integer>(zero,
+ Integer.class));
+ Item itemPositive = new PropertysetItem();
+ itemPositive.addItemProperty(PROPERTY1, new ObjectProperty<Integer>(
+ positive, Integer.class));
+
+ Filter equalZero = new Equal(PROPERTY1, zero);
+ Assert.assertFalse(equalZero.passesFilter(null, itemNegative));
+ Assert.assertTrue(equalZero.passesFilter(null, itemZero));
+ Assert.assertFalse(equalZero.passesFilter(null, itemPositive));
+
+ Filter isPositive = new Greater(PROPERTY1, zero);
+ Assert.assertFalse(isPositive.passesFilter(null, itemNegative));
+ Assert.assertFalse(isPositive.passesFilter(null, itemZero));
+ Assert.assertTrue(isPositive.passesFilter(null, itemPositive));
+
+ Filter isNegative = new Less(PROPERTY1, zero);
+ Assert.assertTrue(isNegative.passesFilter(null, itemNegative));
+ Assert.assertFalse(isNegative.passesFilter(null, itemZero));
+ Assert.assertFalse(isNegative.passesFilter(null, itemPositive));
+
+ Filter isNonNegative = new GreaterOrEqual(PROPERTY1, zero);
+ Assert.assertFalse(isNonNegative.passesFilter(null, itemNegative));
+ Assert.assertTrue(isNonNegative.passesFilter(null, itemZero));
+ Assert.assertTrue(isNonNegative.passesFilter(null, itemPositive));
+
+ Filter isNonPositive = new LessOrEqual(PROPERTY1, zero);
+ Assert.assertTrue(isNonPositive.passesFilter(null, itemNegative));
+ Assert.assertTrue(isNonPositive.passesFilter(null, itemZero));
+ Assert.assertFalse(isNonPositive.passesFilter(null, itemPositive));
+ }
+
+ public void testCompareDate() {
+ Date now = new Date();
+ // new Date() is only accurate to the millisecond, so repeating it gives
+ // the same date
+ Date earlier = new Date(now.getTime() - 1);
+ Date later = new Date(now.getTime() + 1);
+
+ Item itemEarlier = new PropertysetItem();
+ itemEarlier.addItemProperty(PROPERTY1, new ObjectProperty<Date>(
+ earlier, Date.class));
+ Item itemNow = new PropertysetItem();
+ itemNow.addItemProperty(PROPERTY1, new ObjectProperty<Date>(now,
+ Date.class));
+ Item itemLater = new PropertysetItem();
+ itemLater.addItemProperty(PROPERTY1, new ObjectProperty<Date>(later,
+ Date.class));
+
+ Filter equalNow = new Equal(PROPERTY1, now);
+ Assert.assertFalse(equalNow.passesFilter(null, itemEarlier));
+ Assert.assertTrue(equalNow.passesFilter(null, itemNow));
+ Assert.assertFalse(equalNow.passesFilter(null, itemLater));
+
+ Filter after = new Greater(PROPERTY1, now);
+ Assert.assertFalse(after.passesFilter(null, itemEarlier));
+ Assert.assertFalse(after.passesFilter(null, itemNow));
+ Assert.assertTrue(after.passesFilter(null, itemLater));
+
+ Filter before = new Less(PROPERTY1, now);
+ Assert.assertTrue(before.passesFilter(null, itemEarlier));
+ Assert.assertFalse(before.passesFilter(null, itemNow));
+ Assert.assertFalse(before.passesFilter(null, itemLater));
+
+ Filter afterOrNow = new GreaterOrEqual(PROPERTY1, now);
+ Assert.assertFalse(afterOrNow.passesFilter(null, itemEarlier));
+ Assert.assertTrue(afterOrNow.passesFilter(null, itemNow));
+ Assert.assertTrue(afterOrNow.passesFilter(null, itemLater));
+
+ Filter beforeOrNow = new LessOrEqual(PROPERTY1, now);
+ Assert.assertTrue(beforeOrNow.passesFilter(null, itemEarlier));
+ Assert.assertTrue(beforeOrNow.passesFilter(null, itemNow));
+ Assert.assertFalse(beforeOrNow.passesFilter(null, itemLater));
+ }
+
+ public void testCompareAppliesToProperty() {
+ Filter filterA = new Equal("a", 1);
+ Filter filterB = new Equal("b", 1);
+
+ Assert.assertTrue(filterA.appliesToProperty("a"));
+ Assert.assertFalse(filterA.appliesToProperty("b"));
+ Assert.assertFalse(filterB.appliesToProperty("a"));
+ Assert.assertTrue(filterB.appliesToProperty("b"));
+ }
+
+ public void testCompareEqualsHashCode() {
+ // most checks with Equal filter, then only some with others
+ Filter equalNull2 = new Equal(PROPERTY1, null);
+ Filter equalNullProperty2 = new Equal(PROPERTY2, null);
+ Filter equalEmpty = new Equal(PROPERTY1, "");
+ Filter equalEmpty2 = new Equal(PROPERTY1, "");
+ Filter equalEmptyProperty2 = new Equal(PROPERTY2, "");
+ Filter equalA = new Equal(PROPERTY1, "a");
+ Filter equalB2 = new Equal(PROPERTY1, "b");
+ Filter equalBProperty2 = new Equal(PROPERTY2, "b");
+
+ Filter greaterEmpty = new Greater(PROPERTY1, "");
+
+ // equals()
+ Assert.assertEquals(equalNull, equalNull);
+ Assert.assertEquals(equalNull, equalNull2);
+ Assert.assertFalse(equalNull.equals(equalNullProperty2));
+ Assert.assertFalse(equalNull.equals(equalEmpty));
+ Assert.assertFalse(equalNull.equals(equalB));
+
+ Assert.assertEquals(equalEmpty, equalEmpty);
+ Assert.assertFalse(equalEmpty.equals(equalNull));
+ Assert.assertEquals(equalEmpty, equalEmpty2);
+ Assert.assertFalse(equalEmpty.equals(equalEmptyProperty2));
+ Assert.assertFalse(equalEmpty.equals(equalB));
+
+ Assert.assertEquals(equalB, equalB);
+ Assert.assertFalse(equalB.equals(equalNull));
+ Assert.assertFalse(equalB.equals(equalEmpty));
+ Assert.assertEquals(equalB, equalB2);
+ Assert.assertFalse(equalB.equals(equalBProperty2));
+ Assert.assertFalse(equalB.equals(equalA));
+
+ Assert.assertEquals(greaterB, greaterB);
+ Assert.assertFalse(greaterB.equals(lessB));
+ Assert.assertFalse(greaterB.equals(greaterEqualB));
+ Assert.assertFalse(greaterB.equals(lessEqualB));
+
+ Assert.assertFalse(greaterNull.equals(greaterEmpty));
+ Assert.assertFalse(greaterNull.equals(greaterB));
+ Assert.assertFalse(greaterEmpty.equals(greaterNull));
+ Assert.assertFalse(greaterEmpty.equals(greaterB));
+ Assert.assertFalse(greaterB.equals(greaterNull));
+ Assert.assertFalse(greaterB.equals(greaterEmpty));
+
+ // hashCode()
+ Assert.assertEquals(equalNull.hashCode(), equalNull2.hashCode());
+ Assert.assertEquals(equalEmpty.hashCode(), equalEmpty2.hashCode());
+ Assert.assertEquals(equalB.hashCode(), equalB2.hashCode());
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/data/util/filter/IsNullFilterTest.java b/server/tests/src/com/vaadin/data/util/filter/IsNullFilterTest.java
new file mode 100644
index 0000000000..6f90273de1
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/filter/IsNullFilterTest.java
@@ -0,0 +1,57 @@
+package com.vaadin.data.util.filter;
+
+import junit.framework.Assert;
+
+import com.vaadin.data.Container.Filter;
+import com.vaadin.data.Item;
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.data.util.PropertysetItem;
+
+public class IsNullFilterTest extends AbstractFilterTest<IsNull> {
+
+ public void testIsNull() {
+ Item item1 = new PropertysetItem();
+ item1.addItemProperty("a", new ObjectProperty<String>(null,
+ String.class));
+ item1.addItemProperty("b",
+ new ObjectProperty<String>("b", String.class));
+ Item item2 = new PropertysetItem();
+ item2.addItemProperty("a",
+ new ObjectProperty<String>("a", String.class));
+ item2.addItemProperty("b", new ObjectProperty<String>(null,
+ String.class));
+
+ Filter filter1 = new IsNull("a");
+ Filter filter2 = new IsNull("b");
+
+ Assert.assertTrue(filter1.passesFilter(null, item1));
+ Assert.assertFalse(filter1.passesFilter(null, item2));
+ Assert.assertFalse(filter2.passesFilter(null, item1));
+ Assert.assertTrue(filter2.passesFilter(null, item2));
+ }
+
+ public void testIsNullAppliesToProperty() {
+ Filter filterA = new IsNull("a");
+ Filter filterB = new IsNull("b");
+
+ Assert.assertTrue(filterA.appliesToProperty("a"));
+ Assert.assertFalse(filterA.appliesToProperty("b"));
+ Assert.assertFalse(filterB.appliesToProperty("a"));
+ Assert.assertTrue(filterB.appliesToProperty("b"));
+ }
+
+ public void testIsNullEqualsHashCode() {
+ Filter filter1 = new IsNull("a");
+ Filter filter1b = new IsNull("a");
+ Filter filter2 = new IsNull("b");
+
+ // equals()
+ Assert.assertEquals(filter1, filter1b);
+ Assert.assertFalse(filter1.equals(filter2));
+ Assert.assertFalse(filter1.equals(new And()));
+
+ // hashCode()
+ Assert.assertEquals(filter1.hashCode(), filter1b.hashCode());
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/data/util/filter/NotFilterTest.java b/server/tests/src/com/vaadin/data/util/filter/NotFilterTest.java
new file mode 100644
index 0000000000..c3b666e6f7
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/filter/NotFilterTest.java
@@ -0,0 +1,50 @@
+package com.vaadin.data.util.filter;
+
+import junit.framework.Assert;
+
+import com.vaadin.data.Container.Filter;
+import com.vaadin.data.Item;
+import com.vaadin.data.util.BeanItem;
+
+public class NotFilterTest extends AbstractFilterTest<Not> {
+
+ protected Item item1 = new BeanItem<Integer>(1);
+ protected Item item2 = new BeanItem<Integer>(2);
+
+ public void testNot() {
+ Filter origFilter = new SameItemFilter(item1);
+ Filter filter = new Not(origFilter);
+
+ Assert.assertTrue(origFilter.passesFilter(null, item1));
+ Assert.assertFalse(origFilter.passesFilter(null, item2));
+ Assert.assertFalse(filter.passesFilter(null, item1));
+ Assert.assertTrue(filter.passesFilter(null, item2));
+ }
+
+ public void testANotAppliesToProperty() {
+ Filter filterA = new Not(new SameItemFilter(item1, "a"));
+ Filter filterB = new Not(new SameItemFilter(item1, "b"));
+
+ Assert.assertTrue(filterA.appliesToProperty("a"));
+ Assert.assertFalse(filterA.appliesToProperty("b"));
+ Assert.assertFalse(filterB.appliesToProperty("a"));
+ Assert.assertTrue(filterB.appliesToProperty("b"));
+ }
+
+ public void testNotEqualsHashCode() {
+ Filter origFilter = new SameItemFilter(item1);
+ Filter filter1 = new Not(origFilter);
+ Filter filter1b = new Not(new SameItemFilter(item1));
+ Filter filter2 = new Not(new SameItemFilter(item2));
+
+ // equals()
+ Assert.assertEquals(filter1, filter1b);
+ Assert.assertFalse(filter1.equals(filter2));
+ Assert.assertFalse(filter1.equals(origFilter));
+ Assert.assertFalse(filter1.equals(new And()));
+
+ // hashCode()
+ Assert.assertEquals(filter1.hashCode(), filter1b.hashCode());
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/data/util/filter/SimpleStringFilterTest.java b/server/tests/src/com/vaadin/data/util/filter/SimpleStringFilterTest.java
new file mode 100644
index 0000000000..bc63d57752
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/filter/SimpleStringFilterTest.java
@@ -0,0 +1,130 @@
+package com.vaadin.data.util.filter;
+
+import junit.framework.Assert;
+
+public class SimpleStringFilterTest extends
+ AbstractFilterTest<SimpleStringFilter> {
+
+ protected static TestItem<String, String> createTestItem() {
+ return new TestItem<String, String>("abcde", "TeSt");
+ }
+
+ protected TestItem<String, String> getTestItem() {
+ return createTestItem();
+ }
+
+ protected SimpleStringFilter f(Object propertyId, String filterString,
+ boolean ignoreCase, boolean onlyMatchPrefix) {
+ return new SimpleStringFilter(propertyId, filterString, ignoreCase,
+ onlyMatchPrefix);
+ }
+
+ protected boolean passes(Object propertyId, String filterString,
+ boolean ignoreCase, boolean onlyMatchPrefix) {
+ return f(propertyId, filterString, ignoreCase, onlyMatchPrefix)
+ .passesFilter(null, getTestItem());
+ }
+
+ public void testStartsWithCaseSensitive() {
+ Assert.assertTrue(passes(PROPERTY1, "ab", false, true));
+ Assert.assertTrue(passes(PROPERTY1, "", false, true));
+
+ Assert.assertFalse(passes(PROPERTY2, "ab", false, true));
+ Assert.assertFalse(passes(PROPERTY1, "AB", false, true));
+ }
+
+ public void testStartsWithCaseInsensitive() {
+ Assert.assertTrue(passes(PROPERTY1, "AB", true, true));
+ Assert.assertTrue(passes(PROPERTY2, "te", true, true));
+ Assert.assertFalse(passes(PROPERTY2, "AB", true, true));
+ }
+
+ public void testContainsCaseSensitive() {
+ Assert.assertTrue(passes(PROPERTY1, "ab", false, false));
+ Assert.assertTrue(passes(PROPERTY1, "abcde", false, false));
+ Assert.assertTrue(passes(PROPERTY1, "cd", false, false));
+ Assert.assertTrue(passes(PROPERTY1, "e", false, false));
+ Assert.assertTrue(passes(PROPERTY1, "", false, false));
+
+ Assert.assertFalse(passes(PROPERTY2, "ab", false, false));
+ Assert.assertFalse(passes(PROPERTY1, "es", false, false));
+ }
+
+ public void testContainsCaseInsensitive() {
+ Assert.assertTrue(passes(PROPERTY1, "AB", true, false));
+ Assert.assertTrue(passes(PROPERTY1, "aBcDe", true, false));
+ Assert.assertTrue(passes(PROPERTY1, "CD", true, false));
+ Assert.assertTrue(passes(PROPERTY1, "", true, false));
+
+ Assert.assertTrue(passes(PROPERTY2, "es", true, false));
+
+ Assert.assertFalse(passes(PROPERTY2, "ab", true, false));
+ }
+
+ public void testAppliesToProperty() {
+ SimpleStringFilter filter = f(PROPERTY1, "ab", false, true);
+ Assert.assertTrue(filter.appliesToProperty(PROPERTY1));
+ Assert.assertFalse(filter.appliesToProperty(PROPERTY2));
+ Assert.assertFalse(filter.appliesToProperty("other"));
+ }
+
+ public void testEqualsHashCode() {
+ SimpleStringFilter filter = f(PROPERTY1, "ab", false, true);
+
+ SimpleStringFilter f1 = f(PROPERTY2, "ab", false, true);
+ SimpleStringFilter f1b = f(PROPERTY2, "ab", false, true);
+ SimpleStringFilter f2 = f(PROPERTY1, "cd", false, true);
+ SimpleStringFilter f2b = f(PROPERTY1, "cd", false, true);
+ SimpleStringFilter f3 = f(PROPERTY1, "ab", true, true);
+ SimpleStringFilter f3b = f(PROPERTY1, "ab", true, true);
+ SimpleStringFilter f4 = f(PROPERTY1, "ab", false, false);
+ SimpleStringFilter f4b = f(PROPERTY1, "ab", false, false);
+
+ // equal but not same instance
+ Assert.assertEquals(f1, f1b);
+ Assert.assertEquals(f2, f2b);
+ Assert.assertEquals(f3, f3b);
+ Assert.assertEquals(f4, f4b);
+
+ // more than one property differ
+ Assert.assertFalse(f1.equals(f2));
+ Assert.assertFalse(f1.equals(f3));
+ Assert.assertFalse(f1.equals(f4));
+ Assert.assertFalse(f2.equals(f1));
+ Assert.assertFalse(f2.equals(f3));
+ Assert.assertFalse(f2.equals(f4));
+ Assert.assertFalse(f3.equals(f1));
+ Assert.assertFalse(f3.equals(f2));
+ Assert.assertFalse(f3.equals(f4));
+ Assert.assertFalse(f4.equals(f1));
+ Assert.assertFalse(f4.equals(f2));
+ Assert.assertFalse(f4.equals(f3));
+
+ // only one property differs
+ Assert.assertFalse(filter.equals(f1));
+ Assert.assertFalse(filter.equals(f2));
+ Assert.assertFalse(filter.equals(f3));
+ Assert.assertFalse(filter.equals(f4));
+
+ Assert.assertFalse(f1.equals(null));
+ Assert.assertFalse(f1.equals(new Object()));
+
+ Assert.assertEquals(f1.hashCode(), f1b.hashCode());
+ Assert.assertEquals(f2.hashCode(), f2b.hashCode());
+ Assert.assertEquals(f3.hashCode(), f3b.hashCode());
+ Assert.assertEquals(f4.hashCode(), f4b.hashCode());
+ }
+
+ public void testNonExistentProperty() {
+ Assert.assertFalse(passes("other1", "ab", false, true));
+ }
+
+ public void testNullValueForProperty() {
+ TestItem<String, String> item = createTestItem();
+ item.addItemProperty("other1", new NullProperty());
+
+ Assert.assertFalse(f("other1", "ab", false, true).passesFilter(null,
+ item));
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/data/util/sqlcontainer/AllTests.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/AllTests.java
new file mode 100644
index 0000000000..057527307f
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/AllTests.java
@@ -0,0 +1,145 @@
+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;
+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;
+
+@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,
+ TicketTests.class, BetweenTest.class, ReadOnlyRowIdTest.class })
+public class AllTests {
+ /* 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;
+ /* 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)" };
+ 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\"();" };
+ 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/server/tests/src/com/vaadin/data/util/sqlcontainer/ColumnPropertyTest.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/ColumnPropertyTest.java
new file mode 100644
index 0000000000..09f620cc2a
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/ColumnPropertyTest.java
@@ -0,0 +1,315 @@
+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/server/tests/src/com/vaadin/data/util/sqlcontainer/DataGenerator.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/DataGenerator.java
new file mode 100644
index 0000000000..489f780d61
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/DataGenerator.java
@@ -0,0 +1,139 @@
+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.AllTests.DB;
+import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool;
+
+public class DataGenerator {
+
+ @Test
+ public void testDummy() {
+ // Added dummy test so JUnit will not complain about
+ // "No runnable methods".
+ }
+
+ public static void addPeopleToDatabase(JDBCConnectionPool connectionPool)
+ throws SQLException {
+ Connection conn = connectionPool.reserveConnection();
+ Statement statement = conn.createStatement();
+ try {
+ statement.execute("drop table PEOPLE");
+ if (AllTests.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(AllTests.peopleFirst);
+ if (AllTests.peopleSecond != null) {
+ statement.execute(AllTests.peopleSecond);
+ }
+ if (AllTests.db == DB.ORACLE) {
+ statement.execute(AllTests.peopleThird);
+ }
+ if (AllTests.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 (AllTests.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 (AllTests.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 : AllTests.versionStatements) {
+ statement.execute(stmtString);
+ }
+ if (AllTests.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 (AllTests.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(AllTests.createGarbage);
+ if (AllTests.db == DB.ORACLE) {
+ statement.execute(AllTests.createGarbageSecond);
+ statement.execute(AllTests.createGarbageThird);
+ }
+ conn.commit();
+ connectionPool.releaseConnection(conn);
+ }
+}
diff --git a/server/tests/src/com/vaadin/data/util/sqlcontainer/FreeformQueryUtil.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/FreeformQueryUtil.java
new file mode 100644
index 0000000000..b0e2a232ca
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/FreeformQueryUtil.java
@@ -0,0 +1,71 @@
+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.AllTests.DB;
+import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
+import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder;
+
+public class FreeformQueryUtil {
+
+ @Test
+ public void testDummy() {
+ // Added dummy test so JUnit will not complain about
+ // "No runnable methods".
+ }
+
+ public static StatementHelper getQueryWithFilters(List<Filter> filters,
+ int offset, int limit) {
+ StatementHelper sh = new StatementHelper();
+ if (AllTests.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 (AllTests.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/server/tests/src/com/vaadin/data/util/sqlcontainer/ReadOnlyRowIdTest.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/ReadOnlyRowIdTest.java
new file mode 100644
index 0000000000..d2b6ee2555
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/ReadOnlyRowIdTest.java
@@ -0,0 +1,50 @@
+package com.vaadin.data.util.sqlcontainer;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+import com.vaadin.data.util.sqlcontainer.ReadOnlyRowId;
+
+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));
+ }
+}
diff --git a/server/tests/src/com/vaadin/data/util/sqlcontainer/RowIdTest.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/RowIdTest.java
new file mode 100644
index 0000000000..399db06869
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/RowIdTest.java
@@ -0,0 +1,55 @@
+package com.vaadin.data.util.sqlcontainer;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.util.sqlcontainer.RowId;
+
+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)));
+ }
+}
diff --git a/server/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java
new file mode 100644
index 0000000000..438c40823d
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java
@@ -0,0 +1,1519 @@
+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 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.AllTests.DB;
+import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool;
+import com.vaadin.data.util.sqlcontainer.connection.SimpleJDBCConnectionPool;
+import com.vaadin.data.util.sqlcontainer.query.OrderBy;
+import com.vaadin.data.util.sqlcontainer.query.TableQuery;
+
+public class SQLContainerTableQueryTest {
+
+ private static final int offset = AllTests.offset;
+ private static final String createGarbage = AllTests.createGarbage;
+ private JDBCConnectionPool connectionPool;
+
+ @Before
+ public void setUp() throws SQLException {
+
+ try {
+ connectionPool = new SimpleJDBCConnectionPool(AllTests.dbDriver,
+ AllTests.dbURL, AllTests.dbUser, AllTests.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_withTableQuery_shouldSucceed() throws SQLException {
+ new SQLContainer(new TableQuery("people", connectionPool,
+ AllTests.sqlGen));
+ }
+
+ @Test
+ public void containsId_withTableQueryAndExistingId_returnsTrue()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Assert.assertTrue(container.containsId(new RowId(
+ new Object[] { 1 + offset })));
+ }
+
+ @Test
+ public void containsId_withTableQueryAndNonexistingId_returnsFalse()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Assert.assertFalse(container.containsId(new RowId(
+ new Object[] { 1337 + offset })));
+ }
+
+ @Test
+ public void getContainerProperty_tableExistingItemIdAndPropertyId_returnsProperty()
+ throws SQLException {
+ TableQuery t = new TableQuery("people", connectionPool, AllTests.sqlGen);
+ SQLContainer container = new SQLContainer(t);
+ if (AllTests.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_tableExistingItemIdAndNonexistingPropertyId_returnsNull()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Assert.assertNull(container.getContainerProperty(new RowId(
+ new Object[] { 1 + offset }), "asdf"));
+ }
+
+ @Test
+ public void getContainerProperty_tableNonexistingItemId_returnsNull()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Assert.assertNull(container.getContainerProperty(new RowId(
+ new Object[] { 1337 + offset }), "NAME"));
+ }
+
+ @Test
+ public void getContainerPropertyIds_table_returnsIDAndNAME()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Collection<?> propertyIds = container.getContainerPropertyIds();
+ Assert.assertEquals(3, propertyIds.size());
+ Assert.assertArrayEquals(new String[] { "ID", "NAME", "AGE" },
+ propertyIds.toArray());
+ }
+
+ @Test
+ public void getItem_tableExistingItemId_returnsItem() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Item item;
+ if (AllTests.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 getItem_commitedModifiedAndRefreshed() throws SQLException {
+ String OLD_VALUE = "SomeValue"; //$NON-NLS-1$
+ String NEW_VALUE = "OtherValue"; //$NON-NLS-1$
+
+ SQLContainer container = new SQLContainer(new TableQuery("people", //$NON-NLS-1$
+ connectionPool, AllTests.sqlGen));
+ Object itemID = container.addItem();
+ Item item = container.getItem(itemID);
+ item.getItemProperty("NAME").setValue(OLD_VALUE); //$NON-NLS-1$
+ container.commit();
+
+ itemID = container.getIdByIndex(container.size() - 1);
+ item = container.getItem(itemID);
+ Assert.assertEquals(OLD_VALUE, item.getItemProperty("NAME") //$NON-NLS-1$
+ .getValue());
+ item.getItemProperty("NAME").setValue(NEW_VALUE); //$NON-NLS-1$
+
+ // refresh the container which free's the caches
+ // and the modified cache keeps untouched which is a really powerful
+ // feature
+ container.refresh();
+
+ // access the item again will use the item from the modified cache.
+ item = container.getItem(itemID);
+ Assert.assertEquals(NEW_VALUE, item.getItemProperty("NAME") //$NON-NLS-1$
+ .getValue());
+ }
+
+ @Test
+ public void getItem_table5000RowsWithParameter1337_returnsItemWithId1337()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ TableQuery query = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+ SQLContainer container = new SQLContainer(query);
+
+ Item item;
+ if (AllTests.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_table_returnsItemIdsWithKeys0through3()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ 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 (AllTests.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_tableNAMEPropertyId_returnsString() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Assert.assertEquals(String.class, container.getType("NAME"));
+ }
+
+ @Test
+ public void getType_tableIDPropertyId_returnsInteger() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ if (AllTests.db == DB.ORACLE) {
+ Assert.assertEquals(BigDecimal.class, container.getType("ID"));
+ } else {
+ Assert.assertEquals(Integer.class, container.getType("ID"));
+ }
+ }
+
+ @Test
+ public void getType_tableNonexistingPropertyId_returnsNull()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Assert.assertNull(container.getType("asdf"));
+ }
+
+ @Test
+ public void size_table_returnsFour() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Assert.assertEquals(4, container.size());
+ }
+
+ @Test
+ public void size_tableOneAddedItem_returnsFive() throws SQLException {
+ Connection conn = connectionPool.reserveConnection();
+ Statement statement = conn.createStatement();
+ if (AllTests.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);
+
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Assert.assertEquals(5, container.size());
+ }
+
+ @Test
+ public void indexOfId_tableWithParameterThree_returnsThree()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ if (AllTests.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_table5000RowsWithParameter1337_returns1337()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ TableQuery q = new TableQuery("people", connectionPool, AllTests.sqlGen);
+ SQLContainer container = new SQLContainer(q);
+ if (AllTests.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_table5000rowsIndex1337_returnsRowId1337()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Object itemId = container.getIdByIndex(1337);
+ if (AllTests.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 getIdByIndex_tableWithPaging5000rowsIndex1337_returnsRowId1337()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ TableQuery query = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+ SQLContainer container = new SQLContainer(query);
+ Object itemId = container.getIdByIndex(1337);
+ if (AllTests.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_tableCurrentItem1337_returnsItem1338()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Object itemId = container.getIdByIndex(1337);
+ if (AllTests.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_tableCurrentItem1337_returns1336()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Object itemId = container.getIdByIndex(1337);
+ if (AllTests.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_table_returnsItemId0() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ if (AllTests.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_table5000Rows_returnsItemId4999()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ if (AllTests.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_tableActualFirstId_returnsTrue() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ if (AllTests.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_tableSecondId_returnsFalse() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ if (AllTests.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 {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ if (AllTests.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 {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ if (AllTests.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_table5000RowsLastId_returnsTrue() throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ if (AllTests.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 allIdsFound_table5000RowsLastId_shouldSucceed()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ for (int i = 0; i < 5000; i++) {
+ Assert.assertTrue(container.containsId(container.getIdByIndex(i)));
+ }
+ }
+
+ @Test
+ public void allIdsFound_table5000RowsLastId_autoCommit_shouldSucceed()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ container.setAutoCommit(true);
+ for (int i = 0; i < 5000; i++) {
+ Assert.assertTrue(container.containsId(container.getIdByIndex(i)));
+ }
+ }
+
+ @Test
+ public void refresh_table_sizeShouldUpdate() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Assert.assertEquals(4, container.size());
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ container.refresh();
+ Assert.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.
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Assert.assertEquals(4, container.size());
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ Assert.assertEquals(4, container.size());
+ }
+
+ @Test
+ public void setAutoCommit_table_shouldSucceed() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ container.setAutoCommit(true);
+ Assert.assertTrue(container.isAutoCommit());
+ container.setAutoCommit(false);
+ Assert.assertFalse(container.isAutoCommit());
+ }
+
+ @Test
+ public void getPageLength_table_returnsDefault100() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Assert.assertEquals(100, container.getPageLength());
+ }
+
+ @Test
+ public void setPageLength_table_shouldSucceed() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ 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 TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ container.addContainerProperty("asdf", String.class, "");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void removeContainerProperty_normal_isUnsupported()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ container.removeContainerProperty("asdf");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void addItemObject_normal_isUnsupported() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ container.addItem("asdf");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void addItemAfterObjectObject_normal_isUnsupported()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ container.addItemAfter("asdf", "foo");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void addItemAtIntObject_normal_isUnsupported() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ container.addItemAt(2, "asdf");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void addItemAtInt_normal_isUnsupported() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ container.addItemAt(2);
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void addItemAfterObject_normal_isUnsupported() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ container.addItemAfter("asdf");
+ }
+
+ @Test
+ public void addItem_tableAddOneNewItem_returnsItemId() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Object itemId = container.addItem();
+ Assert.assertNotNull(itemId);
+ }
+
+ @Test
+ public void addItem_tableAddOneNewItem_autoCommit_returnsFinalItemId()
+ throws SQLException {
+ TableQuery query = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+ SQLContainer container = new SQLContainer(query);
+ container.setAutoCommit(true);
+ Object itemId = container.addItem();
+ Assert.assertNotNull(itemId);
+ Assert.assertTrue(itemId instanceof RowId);
+ Assert.assertFalse(itemId instanceof TemporaryRowId);
+ }
+
+ @Test
+ public void addItem_tableAddOneNewItem_autoCommit_sizeIsIncreased()
+ throws SQLException {
+ TableQuery query = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+ SQLContainer container = new SQLContainer(query);
+ container.setAutoCommit(true);
+ int originalSize = container.size();
+ container.addItem();
+ Assert.assertEquals(originalSize + 1, container.size());
+ }
+
+ @Test
+ public void addItem_tableAddOneNewItem_shouldChangeSize()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ int size = container.size();
+ container.addItem();
+ Assert.assertEquals(size + 1, container.size());
+ }
+
+ @Test
+ public void addItem_tableAddTwoNewItems_shouldChangeSize()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ 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_tableNewlyAddedItem_returnsNewlyAdded()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Object lastId = container.lastItemId();
+ Object id = container.addItem();
+ Assert.assertEquals(id, container.nextItemId(lastId));
+ }
+
+ @Test
+ public void lastItemId_tableNewlyAddedItem_returnsNewlyAdded()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Object lastId = container.lastItemId();
+ Object id = container.addItem();
+ Assert.assertEquals(id, container.lastItemId());
+ Assert.assertNotSame(lastId, container.lastItemId());
+ }
+
+ @Test
+ public void indexOfId_tableNewlyAddedItem_returnsFour() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Object id = container.addItem();
+ Assert.assertEquals(4, container.indexOfId(id));
+ }
+
+ @Test
+ public void getItem_tableNewlyAddedItem_returnsNewlyAdded()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Object id = container.addItem();
+ Assert.assertNotNull(container.getItem(id));
+ }
+
+ @Test
+ public void getItemIds_tableNewlyAddedItem_containsNewlyAdded()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Object id = container.addItem();
+ Assert.assertTrue(container.getItemIds().contains(id));
+ }
+
+ @Test
+ public void getContainerProperty_tableNewlyAddedItem_returnsPropertyOfNewlyAddedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ 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_tableNewlyAddedItem_returnsTrue()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Object id = container.addItem();
+ Assert.assertTrue(container.containsId(id));
+ }
+
+ @Test
+ public void prevItemId_tableTwoNewlyAddedItems_returnsFirstAddedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Object id1 = container.addItem();
+ Object id2 = container.addItem();
+ Assert.assertEquals(id1, container.prevItemId(id2));
+ }
+
+ @Test
+ public void firstItemId_tableEmptyResultSet_returnsFirstAddedItem()
+ throws SQLException {
+ DataGenerator.createGarbage(connectionPool);
+ SQLContainer container = new SQLContainer(new TableQuery("garbage",
+ connectionPool, AllTests.sqlGen));
+ Object id = container.addItem();
+ Assert.assertSame(id, container.firstItemId());
+ }
+
+ @Test
+ public void isFirstId_tableEmptyResultSet_returnsFirstAddedItem()
+ throws SQLException {
+ DataGenerator.createGarbage(connectionPool);
+ SQLContainer container = new SQLContainer(new TableQuery("garbage",
+ connectionPool, AllTests.sqlGen));
+ Object id = container.addItem();
+ Assert.assertTrue(container.isFirstId(id));
+ }
+
+ @Test
+ public void isLastId_tableOneItemAdded_returnsTrueForAddedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Object id = container.addItem();
+ Assert.assertTrue(container.isLastId(id));
+ }
+
+ @Test
+ public void isLastId_tableTwoItemsAdded_returnsTrueForLastAddedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ container.addItem();
+ Object id2 = container.addItem();
+ Assert.assertTrue(container.isLastId(id2));
+ }
+
+ @Test
+ public void getIdByIndex_tableOneItemAddedLastIndexInContainer_returnsAddedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Object id = container.addItem();
+ Assert.assertEquals(id, container.getIdByIndex(container.size() - 1));
+ }
+
+ @Test
+ public void removeItem_tableNoAddedItems_removesItemFromContainer()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ 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_tableRemovedItem_returnsFalse() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Object id = container.firstItemId();
+ Assert.assertTrue(container.removeItem(id));
+ Assert.assertFalse(container.containsId(id));
+ }
+
+ @Test
+ public void removeItem_tableOneAddedItem_removesTheAddedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ 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_tableItemRemoved_returnsNull() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Object id = container.firstItemId();
+ Assert.assertTrue(container.removeItem(id));
+ Assert.assertNull(container.getItem(id));
+ }
+
+ @Test
+ public void getItem_tableAddedItemRemoved_returnsNull() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Object id = container.addItem();
+ Assert.assertNotNull(container.getItem(id));
+ Assert.assertTrue(container.removeItem(id));
+ Assert.assertNull(container.getItem(id));
+ }
+
+ @Test
+ public void getItemIds_tableItemRemoved_shouldNotContainRemovedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ 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_tableAddedItemRemoved_shouldNotContainRemovedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ 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_tableItemRemoved_returnsFalse() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Object id = container.firstItemId();
+ Assert.assertTrue(container.containsId(id));
+ Assert.assertTrue(container.removeItem(id));
+ Assert.assertFalse(container.containsId(id));
+ }
+
+ @Test
+ public void containsId_tableAddedItemRemoved_returnsFalse()
+ throws SQLException {
+ TableQuery query = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+ SQLContainer container = new SQLContainer(query);
+ Object id = container.addItem();
+ Assert.assertTrue(container.containsId(id));
+ Assert.assertTrue(container.removeItem(id));
+ Assert.assertFalse(container.containsId(id));
+ }
+
+ @Test
+ public void nextItemId_tableItemRemoved_skipsRemovedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ 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_tableAddedItemRemoved_skipsRemovedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ 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_tableItemRemoved_skipsRemovedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ 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_tableAddedItemRemoved_skipsRemovedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ 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_tableFirstItemRemoved_resultChanges()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Object first = container.firstItemId();
+ Assert.assertTrue(container.removeItem(first));
+ Assert.assertNotSame(first, container.firstItemId());
+ }
+
+ @Test
+ public void firstItemId_tableNewlyAddedFirstItemRemoved_resultChanges()
+ throws SQLException {
+ DataGenerator.createGarbage(connectionPool);
+ SQLContainer container = new SQLContainer(new TableQuery("garbage",
+ connectionPool, AllTests.sqlGen));
+ 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_tableLastItemRemoved_resultChanges()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Object last = container.lastItemId();
+ Assert.assertTrue(container.removeItem(last));
+ Assert.assertNotSame(last, container.lastItemId());
+ }
+
+ @Test
+ public void lastItemId_tableAddedLastItemRemoved_resultChanges()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Object last = container.addItem();
+ Assert.assertSame(last, container.lastItemId());
+ Assert.assertTrue(container.removeItem(last));
+ Assert.assertNotSame(last, container.lastItemId());
+ }
+
+ @Test
+ public void isFirstId_tableFirstItemRemoved_returnsFalse()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Object first = container.firstItemId();
+ Assert.assertTrue(container.removeItem(first));
+ Assert.assertFalse(container.isFirstId(first));
+ }
+
+ @Test
+ public void isFirstId_tableAddedFirstItemRemoved_returnsFalse()
+ throws SQLException {
+ DataGenerator.createGarbage(connectionPool);
+ SQLContainer container = new SQLContainer(new TableQuery("garbage",
+ connectionPool, AllTests.sqlGen));
+ 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_tableLastItemRemoved_returnsFalse()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Object last = container.lastItemId();
+ Assert.assertTrue(container.removeItem(last));
+ Assert.assertFalse(container.isLastId(last));
+ }
+
+ @Test
+ public void isLastId_tableAddedLastItemRemoved_returnsFalse()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Object last = container.addItem();
+ Assert.assertSame(last, container.lastItemId());
+ Assert.assertTrue(container.removeItem(last));
+ Assert.assertFalse(container.isLastId(last));
+ }
+
+ @Test
+ public void indexOfId_tableItemRemoved_returnsNegOne() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Object id = container.getIdByIndex(2);
+ Assert.assertTrue(container.removeItem(id));
+ Assert.assertEquals(-1, container.indexOfId(id));
+ }
+
+ @Test
+ public void indexOfId_tableAddedItemRemoved_returnsNegOne()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ 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_tableItemRemoved_resultChanges()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Object id = container.getIdByIndex(2);
+ Assert.assertTrue(container.removeItem(id));
+ Assert.assertNotSame(id, container.getIdByIndex(2));
+ }
+
+ @Test
+ public void getIdByIndex_tableAddedItemRemoved_resultChanges()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ 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_table_shouldSucceed() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Assert.assertTrue(container.removeAllItems());
+ Assert.assertEquals(0, container.size());
+ }
+
+ @Test
+ public void removeAllItems_tableAddedItems_shouldSucceed()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ container.addItem();
+ container.addItem();
+ Assert.assertTrue(container.removeAllItems());
+ Assert.assertEquals(0, container.size());
+ }
+
+ @Test
+ public void commit_tableAddedItem_shouldBeWrittenToDB() throws SQLException {
+ TableQuery query = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+ SQLContainer container = new SQLContainer(query);
+ Object id = container.addItem();
+ container.getContainerProperty(id, "NAME").setValue("New Name");
+ 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());
+ }
+
+ @Test
+ public void commit_tableTwoAddedItems_shouldBeWrittenToDB()
+ throws SQLException {
+ TableQuery query = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+ SQLContainer container = new SQLContainer(query);
+ Object id = container.addItem();
+ Object id2 = container.addItem();
+ container.getContainerProperty(id, "NAME").setValue("Herbert");
+ container.getContainerProperty(id2, "NAME").setValue("Larry");
+ 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());
+ }
+
+ @Test
+ public void commit_tableRemovedItem_shouldBeRemovedFromDB()
+ throws SQLException {
+ TableQuery query = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+ SQLContainer container = new SQLContainer(query);
+ Object last = container.lastItemId();
+ container.removeItem(last);
+ container.commit();
+ Assert.assertFalse(last.equals(container.lastItemId()));
+ }
+
+ @Test
+ public void commit_tableLastItemUpdated_shouldUpdateRowInDB()
+ throws SQLException {
+ TableQuery query = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+ 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());
+ }
+
+ @Test
+ public void rollback_tableItemAdded_discardsAddedItem() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ 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_tableItemRemoved_restoresRemovedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ 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_tableItemChanged_discardsChanges() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ 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 {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Assert.assertFalse(container.isModified());
+ RowItem last = (RowItem) container.getItem(container.lastItemId());
+ container.itemChangeNotification(last);
+ Assert.assertTrue(container.isModified());
+ }
+
+ @Test
+ public void itemSetChangeListeners_table_shouldFire() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ 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 {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ 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 {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ 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 {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Assert.assertFalse(container.isModified());
+ container.removeItem(container.lastItemId());
+ Assert.assertTrue(container.isModified());
+ }
+
+ @Test
+ public void isModified_tableAddedItem_returnsTrue() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Assert.assertFalse(container.isModified());
+ container.addItem();
+ Assert.assertTrue(container.isModified());
+ }
+
+ @Test
+ public void isModified_tableChangedItem_returnsTrue() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Assert.assertFalse(container.isModified());
+ container.getContainerProperty(container.lastItemId(), "NAME")
+ .setValue("foo");
+ Assert.assertTrue(container.isModified());
+ }
+
+ @Test
+ public void getSortableContainerPropertyIds_table_returnsAllPropertyIds()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ Collection<?> sortableIds = container.getSortableContainerPropertyIds();
+ Assert.assertTrue(sortableIds.contains("ID"));
+ Assert.assertTrue(sortableIds.contains("NAME"));
+ Assert.assertTrue(sortableIds.contains("AGE"));
+ Assert.assertEquals(3, sortableIds.size());
+ if (AllTests.db == DB.MSSQL || AllTests.db == DB.ORACLE) {
+ Assert.assertFalse(sortableIds.contains("rownum"));
+ }
+ }
+
+ @Test
+ public void addOrderBy_table_shouldReorderResults() throws SQLException {
+ TableQuery query = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+ 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());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void addOrderBy_tableIllegalColumn_shouldFail() throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, AllTests.sqlGen));
+ container.addOrderBy(new OrderBy("asdf", true));
+ }
+
+ @Test
+ public void sort_table_sortsByName() throws SQLException {
+ TableQuery query = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+ 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());
+ }
+
+ @Test
+ public void addFilter_table_filtersResults() throws SQLException {
+ TableQuery query = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+ 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());
+ }
+
+ @Test
+ public void addContainerFilter_filtersResults() throws SQLException {
+ TableQuery query = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+ 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());
+ }
+
+ @Test
+ public void addContainerFilter_ignoreCase_filtersResults()
+ throws SQLException {
+ TableQuery query = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+ SQLContainer container = new SQLContainer(query);
+ // Ville, Kalle, Pelle, Börje
+ Assert.assertEquals(4, container.size());
+
+ container.addContainerFilter("NAME", "vi", true, false);
+
+ // Ville
+ Assert.assertEquals(1, container.size());
+ Assert.assertEquals("Ville",
+ container.getContainerProperty(container.lastItemId(), "NAME")
+ .getValue());
+ }
+
+ @Test
+ public void removeAllContainerFilters_table_noFiltering()
+ throws SQLException {
+ TableQuery query = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+ 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());
+ }
+
+ @Test
+ public void removeContainerFilters_table_noFiltering() throws SQLException {
+ TableQuery query = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+ 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.removeContainerFilters("NAME");
+
+ Assert.assertEquals(4, container.size());
+ Assert.assertEquals("Börje",
+ container.getContainerProperty(container.lastItemId(), "NAME")
+ .getValue());
+ }
+
+ @Test
+ public void addFilter_tableBufferedItems_alsoFiltersBufferedItems()
+ throws SQLException {
+ TableQuery query = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+ 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());
+
+ Assert.assertNull(container.getIdByIndex(4));
+ Assert.assertNull(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());
+ }
+
+ @Test
+ public void sort_tableBufferedItems_sortsBufferedItemsLastInOrderAdded()
+ throws SQLException {
+ TableQuery query = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+ 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());
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTest.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTest.java
new file mode 100644
index 0000000000..6649bc16e8
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTest.java
@@ -0,0 +1,2458 @@
+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.AllTests.DB;
+import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool;
+import com.vaadin.data.util.sqlcontainer.connection.SimpleJDBCConnectionPool;
+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.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 = AllTests.offset;
+ private JDBCConnectionPool connectionPool;
+
+ @Before
+ public void setUp() throws SQLException {
+
+ try {
+ connectionPool = new SimpleJDBCConnectionPool(AllTests.dbDriver,
+ AllTests.dbURL, AllTests.dbUser, AllTests.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 (AllTests.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 (AllTests.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 getItem_freeform5000RowsWithParameter1337_returnsItemWithId1337()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Item item;
+ if (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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
+ @SuppressWarnings("deprecation")
+ 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
+ @SuppressWarnings("deprecation")
+ 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
+ @SuppressWarnings("deprecation")
+ 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
+ @SuppressWarnings("deprecation")
+ 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
+ @SuppressWarnings("deprecation")
+ 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());
+
+ Assert.assertNull(container.getIdByIndex(4));
+ Assert.assertNull(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 (AllTests.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 (AllTests.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/server/tests/src/com/vaadin/data/util/sqlcontainer/TicketTests.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/TicketTests.java
new file mode 100644
index 0000000000..a12786f13a
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/TicketTests.java
@@ -0,0 +1,186 @@
+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.SQLContainer;
+import com.vaadin.data.util.sqlcontainer.AllTests.DB;
+import com.vaadin.data.util.sqlcontainer.connection.SimpleJDBCConnectionPool;
+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.generator.StatementHelper;
+import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.Window;
+
+public class TicketTests {
+
+ private SimpleJDBCConnectionPool connectionPool;
+
+ @Before
+ public void setUp() throws SQLException {
+ connectionPool = new SimpleJDBCConnectionPool(AllTests.dbDriver,
+ AllTests.dbURL, AllTests.dbUser, AllTests.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.addComponent(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
+ @SuppressWarnings("deprecation")
+ 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 (AllTests.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,
+ AllTests.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 (AllTests.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, AllTests.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);
+ }
+}
diff --git a/server/tests/src/com/vaadin/data/util/sqlcontainer/UtilTest.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/UtilTest.java
new file mode 100644
index 0000000000..31bdf2b81b
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/UtilTest.java
@@ -0,0 +1,53 @@
+package com.vaadin.data.util.sqlcontainer;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+import com.vaadin.data.util.sqlcontainer.SQLUtil;
+
+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/server/tests/src/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPoolTest.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPoolTest.java
new file mode 100644
index 0000000000..65a995120e
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPoolTest.java
@@ -0,0 +1,108 @@
+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 junit.framework.Assert;
+
+import org.easymock.EasyMock;
+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/server/tests/src/com/vaadin/data/util/sqlcontainer/connection/MockInitialContextFactory.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/connection/MockInitialContextFactory.java
new file mode 100644
index 0000000000..324899e373
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/connection/MockInitialContextFactory.java
@@ -0,0 +1,33 @@
+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;
+
+ @Test
+ public void testDummy() {
+ // Added dummy test so JUnit will not complain about
+ // "No runnable methods".
+ }
+
+ 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/server/tests/src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPoolTest.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPoolTest.java
new file mode 100644
index 0000000000..147319643d
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPoolTest.java
@@ -0,0 +1,172 @@
+package com.vaadin.data.util.sqlcontainer.connection;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import junit.framework.Assert;
+
+import org.easymock.EasyMock;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.util.sqlcontainer.AllTests;
+import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool;
+import com.vaadin.data.util.sqlcontainer.connection.SimpleJDBCConnectionPool;
+
+public class SimpleJDBCConnectionPoolTest {
+ private JDBCConnectionPool connectionPool;
+
+ @Before
+ public void setUp() throws SQLException {
+ connectionPool = new SimpleJDBCConnectionPool(AllTests.dbDriver,
+ AllTests.dbURL, AllTests.dbUser, AllTests.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(
+ AllTests.dbDriver, null, null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void construct_onlyDriverNameAndUrlGiven_shouldFail()
+ throws SQLException {
+ SimpleJDBCConnectionPool cp = new SimpleJDBCConnectionPool(
+ AllTests.dbDriver, AllTests.dbURL, null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void construct_onlyDriverNameAndUrlAndUserGiven_shouldFail()
+ throws SQLException {
+ SimpleJDBCConnectionPool cp = new SimpleJDBCConnectionPool(
+ AllTests.dbDriver, AllTests.dbURL, AllTests.dbUser, null);
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void construct_nonExistingDriver_shouldFail() throws SQLException {
+ SimpleJDBCConnectionPool cp = new SimpleJDBCConnectionPool("foo",
+ AllTests.dbURL, AllTests.dbUser, AllTests.dbPwd);
+ }
+
+ @Test
+ public void reserveConnection_newConnectionOpened_shouldSucceed()
+ throws SQLException {
+ connectionPool = new SimpleJDBCConnectionPool(AllTests.dbDriver,
+ AllTests.dbURL, AllTests.dbUser, AllTests.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
+ connectionPool.reserveConnection();
+ connectionPool.releaseConnection(c);
+ EasyMock.verify(c);
+ }
+
+ @Test
+ public void destroy_shouldCloseAllConnections() throws SQLException {
+ Connection c1 = connectionPool.reserveConnection();
+ Connection c2 = connectionPool.reserveConnection();
+ connectionPool.destroy();
+ 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/server/tests/src/com/vaadin/data/util/sqlcontainer/filters/BetweenTest.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/filters/BetweenTest.java
new file mode 100644
index 0000000000..da4cfe4522
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/filters/BetweenTest.java
@@ -0,0 +1,122 @@
+package com.vaadin.data.util.sqlcontainer.filters;
+
+import junit.framework.Assert;
+
+import org.easymock.EasyMock;
+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));
+ }
+}
diff --git a/server/tests/src/com/vaadin/data/util/sqlcontainer/filters/LikeTest.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/filters/LikeTest.java
new file mode 100644
index 0000000000..f1130aad80
--- /dev/null
+++ b/server/tests/src/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/server/tests/src/com/vaadin/data/util/sqlcontainer/generator/SQLGeneratorsTest.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/generator/SQLGeneratorsTest.java
new file mode 100644
index 0000000000..e62a06e6e1
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/generator/SQLGeneratorsTest.java
@@ -0,0 +1,241 @@
+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.AllTests;
+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.connection.JDBCConnectionPool;
+import com.vaadin.data.util.sqlcontainer.connection.SimpleJDBCConnectionPool;
+import com.vaadin.data.util.sqlcontainer.query.OrderBy;
+import com.vaadin.data.util.sqlcontainer.query.TableQuery;
+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 SimpleJDBCConnectionPool(AllTests.dbDriver,
+ AllTests.dbURL, AllTests.dbUser, AllTests.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 (AllTests.sqlGen instanceof MSSQLGenerator
+ || AllTests.sqlGen instanceof OracleGenerator) {
+ return;
+ }
+ SQLGenerator sg = AllTests.sqlGen;
+ TableQuery query = new TableQuery("people", connectionPool,
+ AllTests.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 (AllTests.sqlGen instanceof MSSQLGenerator
+ || AllTests.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 (AllTests.sqlGen instanceof MSSQLGenerator
+ || AllTests.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/server/tests/src/com/vaadin/data/util/sqlcontainer/query/FreeformQueryTest.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/query/FreeformQueryTest.java
new file mode 100644
index 0000000000..9b38655186
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/query/FreeformQueryTest.java
@@ -0,0 +1,897 @@
+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.AllTests;
+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.AllTests.DB;
+import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool;
+import com.vaadin.data.util.sqlcontainer.connection.SimpleJDBCConnectionPool;
+import com.vaadin.data.util.sqlcontainer.query.FreeformQuery;
+import com.vaadin.data.util.sqlcontainer.query.FreeformQueryDelegate;
+import com.vaadin.data.util.sqlcontainer.query.OrderBy;
+
+public class FreeformQueryTest {
+
+ private static final int offset = AllTests.offset;
+ private JDBCConnectionPool connectionPool;
+
+ @Before
+ public void setUp() throws SQLException {
+
+ try {
+ connectionPool = new SimpleJDBCConnectionPool(AllTests.dbDriver,
+ AllTests.dbURL, AllTests.dbUser, AllTests.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 (AllTests.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();
+ Assert.assertNotNull(connectionPool.reserveConnection());
+ }
+
+ @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(expected = UnsupportedOperationException.class)
+ 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();
+ query.storeRow(new RowItem(container, new RowId(new Object[] { 1 }),
+ null));
+ query.commit();
+ EasyMock.verify(container);
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ 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();
+ query.removeRow(new RowItem(container, new RowId(new Object[] { 1 }),
+ null));
+ query.commit();
+ EasyMock.verify(container);
+ }
+
+ @Test
+ public void beginTransaction_readOnly_shouldSucceed() throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ query.beginTransaction();
+ }
+
+ @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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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 (AllTests.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(expected = UnsupportedOperationException.class)
+ 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);
+ query.storeRow(row);
+ query.commit();
+
+ EasyMock.verify(delegate, container);
+ }
+
+ @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(expected = UnsupportedOperationException.class)
+ 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);
+ query.removeRow(row);
+ query.commit();
+
+ EasyMock.verify(delegate, container);
+ }
+
+ @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();
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void beginTransaction_transactionAlreadyActive_shouldFail()
+ throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+
+ query.beginTransaction();
+ query.beginTransaction();
+ }
+
+ @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);
+ }
+
+ @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);
+ }
+}
diff --git a/server/tests/src/com/vaadin/data/util/sqlcontainer/query/QueryBuilderTest.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/query/QueryBuilderTest.java
new file mode 100644
index 0000000000..f635b23ebd
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/query/QueryBuilderTest.java
@@ -0,0 +1,311 @@
+package com.vaadin.data.util.sqlcontainer.query;
+
+import java.util.ArrayList;
+
+import junit.framework.Assert;
+
+import org.easymock.EasyMock;
+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/server/tests/src/com/vaadin/data/util/sqlcontainer/query/TableQueryTest.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/query/TableQueryTest.java
new file mode 100644
index 0000000000..e135894013
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/query/TableQueryTest.java
@@ -0,0 +1,663 @@
+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.AllTests;
+import com.vaadin.data.util.sqlcontainer.AllTests.DB;
+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.connection.JDBCConnectionPool;
+import com.vaadin.data.util.sqlcontainer.connection.SimpleJDBCConnectionPool;
+import com.vaadin.data.util.sqlcontainer.query.generator.DefaultSQLGenerator;
+
+public class TableQueryTest {
+ private static final int offset = AllTests.offset;
+ private JDBCConnectionPool connectionPool;
+
+ @Before
+ public void setUp() throws SQLException {
+
+ try {
+ connectionPool = new SimpleJDBCConnectionPool(AllTests.dbDriver,
+ AllTests.dbURL, AllTests.dbUser, AllTests.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,
+ AllTests.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,
+ AllTests.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 (AllTests.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,
+ AllTests.sqlGen);
+
+ Assert.assertEquals(6, tQuery.getCount());
+ }
+
+ @Test
+ public void getCount_normalState_releasesConnection() throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+ tQuery.getCount();
+ tQuery.getCount();
+ Assert.assertNotNull(connectionPool.reserveConnection());
+ }
+
+ /**********************************************************************
+ * TableQuery get results tests
+ **********************************************************************/
+ @Test
+ public void getResults_simpleQuery_returnsFourRecords() throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ AllTests.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,
+ AllTests.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_readOnly_shouldSucceed() throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+ tQuery.beginTransaction();
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void beginTransaction_transactionAlreadyActive_shouldFail()
+ throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+
+ tQuery.beginTransaction();
+ tQuery.beginTransaction();
+ }
+
+ @Test
+ public void commit_readOnly_shouldSucceed() throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+ tQuery.beginTransaction();
+ tQuery.commit();
+ }
+
+ @Test
+ public void rollback_readOnly_shouldSucceed() throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+ tQuery.beginTransaction();
+ tQuery.rollback();
+ }
+
+ @Test(expected = SQLException.class)
+ public void commit_noActiveTransaction_shouldFail() throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+ tQuery.commit();
+ }
+
+ @Test(expected = SQLException.class)
+ public void rollback_noActiveTransaction_shouldFail() throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+ tQuery.rollback();
+ }
+
+ /**********************************************************************
+ * TableQuery row query with given keys tests
+ **********************************************************************/
+ @Test
+ public void containsRowWithKeys_existingKeys_returnsTrue()
+ throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+ Assert.assertTrue(tQuery.containsRowWithKey(1));
+ }
+
+ @Test
+ public void containsRowWithKeys_nonexistingKeys_returnsTrue()
+ throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+
+ Assert.assertFalse(tQuery.containsRowWithKey(1337));
+ }
+
+ @Test
+ public void containsRowWithKeys_invalidKeys_shouldFail()
+ throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ AllTests.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,
+ AllTests.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
+ connectionPool.reserveConnection();
+ connectionPool.reserveConnection();
+ }
+ }
+
+ /**********************************************************************
+ * TableQuery filtering and ordering tests
+ **********************************************************************/
+ @Test
+ public void setFilters_shouldReturnCorrectCount() throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ AllTests.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,
+ AllTests.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,
+ AllTests.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,
+ AllTests.sqlGen);
+ tQuery.setFilters(null);
+ }
+
+ @Test
+ public void setOrderBy_nullParameter_shouldSucceed() {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ AllTests.sqlGen);
+ tQuery.setOrderBy(null);
+ }
+
+ /**********************************************************************
+ * TableQuery row removal tests
+ **********************************************************************/
+ @Test
+ public void removeRowThroughContainer_legalRowItem_shouldSucceed()
+ throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ AllTests.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,
+ AllTests.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,
+ AllTests.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,
+ AllTests.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,
+ AllTests.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,
+ AllTests.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 (AllTests.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,
+ AllTests.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,
+ AllTests.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 (AllTests.db == AllTests.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,
+ AllTests.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 (AllTests.db == AllTests.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,
+ AllTests.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();
+ }
+
+} \ No newline at end of file
diff --git a/server/tests/src/com/vaadin/server/JSONSerializerTest.java b/server/tests/src/com/vaadin/server/JSONSerializerTest.java
new file mode 100644
index 0000000000..05139e6f1a
--- /dev/null
+++ b/server/tests/src/com/vaadin/server/JSONSerializerTest.java
@@ -0,0 +1,140 @@
+package com.vaadin.server;
+
+/*
+ * Copyright 2011 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.
+ */
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import com.vaadin.server.JsonCodec.BeanProperty;
+import com.vaadin.shared.ui.splitpanel.AbstractSplitPanelState;
+
+/**
+ * Tests for {@link JsonCodec}
+ *
+ * @author Vaadin Ltd
+ * @since 7.0
+ *
+ */
+public class JSONSerializerTest extends TestCase {
+ HashMap<String, AbstractSplitPanelState> stringToStateMap;
+ HashMap<AbstractSplitPanelState, String> stateToStringMap;
+
+ public void testStringToBeanMapSerialization() throws Exception {
+ Type mapType = getClass().getDeclaredField("stringToStateMap")
+ .getGenericType();
+ stringToStateMap = new HashMap<String, AbstractSplitPanelState>();
+ AbstractSplitPanelState s = new AbstractSplitPanelState();
+ AbstractSplitPanelState s2 = new AbstractSplitPanelState();
+ s.setCaption("State 1");
+ s.setId("foo");
+ s2.setCaption("State 2");
+ s2.setId("bar");
+ stringToStateMap.put("string - state 1", s);
+ stringToStateMap.put("String - state 2", s2);
+
+ Object encodedMap = JsonCodec.encode(stringToStateMap, null, mapType,
+ null).getEncodedValue();
+
+ ensureDecodedCorrectly(stringToStateMap, encodedMap, mapType);
+ }
+
+ public void testBeanToStringMapSerialization() throws Exception {
+ Type mapType = getClass().getDeclaredField("stateToStringMap")
+ .getGenericType();
+ stateToStringMap = new HashMap<AbstractSplitPanelState, String>();
+ AbstractSplitPanelState s = new AbstractSplitPanelState();
+ AbstractSplitPanelState s2 = new AbstractSplitPanelState();
+ s.setCaption("State 1");
+ s2.setCaption("State 2");
+ stateToStringMap.put(s, "string - state 1");
+ stateToStringMap.put(s2, "String - state 2");
+
+ Object encodedMap = JsonCodec.encode(stateToStringMap, null, mapType,
+ null).getEncodedValue();
+
+ ensureDecodedCorrectly(stateToStringMap, encodedMap, mapType);
+ }
+
+ private void ensureDecodedCorrectly(Object original, Object encoded,
+ Type type) throws Exception {
+ Object serverSideDecoded = JsonCodec.decodeInternalOrCustomType(type,
+ encoded, null);
+ assertTrue("Server decoded", equals(original, serverSideDecoded));
+
+ }
+
+ private boolean equals(Object o1, Object o2) throws Exception {
+ if (o1 == null) {
+ return (o2 == null);
+ }
+ if (o2 == null) {
+ return false;
+ }
+
+ if (o1 instanceof Map) {
+ if (!(o2 instanceof Map)) {
+ return false;
+ }
+ return equalsMap((Map) o1, (Map) o2);
+ }
+
+ if (o1.getClass() != o2.getClass()) {
+ return false;
+ }
+
+ if (o1 instanceof Collection || o1 instanceof Number
+ || o1 instanceof String) {
+ return o1.equals(o2);
+ }
+
+ return equalsBean(o1, o2);
+ }
+
+ private boolean equalsBean(Object o1, Object o2) throws Exception {
+ for (BeanProperty property : JsonCodec.getProperties(o1.getClass())) {
+ Object c1 = property.getValue(o1);
+ Object c2 = property.getValue(o2);
+ if (!equals(c1, c2)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean equalsMap(Map o1, Map o2) throws Exception {
+ for (Object key1 : o1.keySet()) {
+ Object key2 = key1;
+ if (!(o2.containsKey(key2))) {
+ // Try to fins a key that is equal
+ for (Object k2 : o2.keySet()) {
+ if (equals(key1, k2)) {
+ key2 = k2;
+ break;
+ }
+ }
+ }
+ if (!equals(o1.get(key1), o2.get(key2))) {
+ return false;
+ }
+
+ }
+ return true;
+ }
+}
diff --git a/server/tests/src/com/vaadin/server/TestAbstractApplicationServletStaticFilesLocation.java b/server/tests/src/com/vaadin/server/TestAbstractApplicationServletStaticFilesLocation.java
new file mode 100644
index 0000000000..df16e98bba
--- /dev/null
+++ b/server/tests/src/com/vaadin/server/TestAbstractApplicationServletStaticFilesLocation.java
@@ -0,0 +1,205 @@
+package com.vaadin.server;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Properties;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+
+import com.vaadin.server.AbstractApplicationServlet;
+import com.vaadin.server.ApplicationServlet;
+
+import junit.framework.TestCase;
+
+public class TestAbstractApplicationServletStaticFilesLocation extends TestCase {
+
+ ApplicationServlet servlet;
+
+ private Method getStaticFilesLocationMethod;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ servlet = new ApplicationServlet();
+
+ // Workaround to avoid calling init and creating servlet config
+ Field f = AbstractApplicationServlet.class
+ .getDeclaredField("applicationProperties");
+ f.setAccessible(true);
+ f.set(servlet, new Properties());
+
+ getStaticFilesLocationMethod = AbstractApplicationServlet.class
+ .getDeclaredMethod(
+ "getStaticFilesLocation",
+ new Class[] { javax.servlet.http.HttpServletRequest.class });
+ getStaticFilesLocationMethod.setAccessible(true);
+
+ }
+
+ public class DummyServletConfig implements ServletConfig {
+
+ // public DummyServletConfig(Map<String,String> initParameters, )
+ @Override
+ public String getInitParameter(String name) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Enumeration<Object> getInitParameterNames() {
+ return new Enumeration<Object>() {
+
+ @Override
+ public boolean hasMoreElements() {
+ return false;
+ }
+
+ @Override
+ public Object nextElement() {
+ return null;
+ }
+ };
+ }
+
+ @Override
+ public ServletContext getServletContext() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getServletName() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ }
+
+ public void testWidgetSetLocation() throws Exception {
+ String location;
+
+ /* SERVLETS */
+ // http://dummy.host:8080/contextpath/servlet
+ // should return /contextpath
+ location = testLocation("http://dummy.host:8080", "/contextpath",
+ "/servlet", "");
+ assertEquals("/contextpath", location);
+
+ // http://dummy.host:8080/servlet
+ // should return ""
+ location = testLocation("http://dummy.host:8080", "", "/servlet", "");
+ assertEquals("", location);
+
+ // http://dummy.host/contextpath/servlet/extra/stuff
+ // should return /contextpath
+ location = testLocation("http://dummy.host", "/contextpath",
+ "/servlet", "/extra/stuff");
+ assertEquals("/contextpath", location);
+
+ // http://dummy.host/context/path/servlet/extra/stuff
+ // should return /context/path
+ location = testLocation("http://dummy.host", "/context/path",
+ "/servlet", "/extra/stuff");
+ assertEquals("/context/path", location);
+
+ /* Include requests */
+ location = testIncludedLocation("http://my.portlet.server", "/user",
+ "/tmpservletlocation1", "");
+ assertEquals("Wrong widgetset location", "/user", location);
+
+ }
+
+ private String testLocation(String base, String contextPath,
+ String servletPath, String pathInfo) throws Exception {
+
+ HttpServletRequest request = createNonIncludeRequest(base, contextPath,
+ servletPath, pathInfo);
+ // Set request into replay mode
+ replay(request);
+
+ String location = (String) getStaticFilesLocationMethod.invoke(servlet,
+ request);
+ return location;
+ }
+
+ private String testIncludedLocation(String base, String portletContextPath,
+ String servletPath, String pathInfo) throws Exception {
+
+ HttpServletRequest request = createIncludeRequest(base,
+ portletContextPath, servletPath, pathInfo);
+ // Set request into replay mode
+ replay(request);
+
+ String location = (String) getStaticFilesLocationMethod.invoke(servlet,
+ request);
+ return location;
+ }
+
+ private HttpServletRequest createIncludeRequest(String base,
+ String realContextPath, String realServletPath, String pathInfo)
+ throws Exception {
+ HttpServletRequest request = createRequest(base, "", "", pathInfo);
+ expect(request.getAttribute("javax.servlet.include.context_path"))
+ .andReturn(realContextPath).anyTimes();
+ expect(request.getAttribute("javax.servlet.include.servlet_path"))
+ .andReturn(realServletPath).anyTimes();
+
+ return request;
+ }
+
+ private HttpServletRequest createNonIncludeRequest(String base,
+ String realContextPath, String realServletPath, String pathInfo)
+ throws Exception {
+ HttpServletRequest request = createRequest(base, realContextPath,
+ realServletPath, pathInfo);
+ expect(request.getAttribute("javax.servlet.include.context_path"))
+ .andReturn(null).anyTimes();
+ expect(request.getAttribute("javax.servlet.include.servlet_path"))
+ .andReturn(null).anyTimes();
+
+ return request;
+ }
+
+ /**
+ * Creates a HttpServletRequest mock using the supplied parameters.
+ *
+ * @param base
+ * The base url, e.g. http://localhost:8080
+ * @param contextPath
+ * The context path where the application is deployed, e.g.
+ * /mycontext
+ * @param servletPath
+ * The servlet path to the servlet we are testing, e.g. /myapp
+ * @param pathInfo
+ * Any text following the servlet path in the request, not
+ * including query parameters, e.g. /UIDL/
+ * @return A mock HttpServletRequest object useful for testing
+ * @throws MalformedURLException
+ */
+ private HttpServletRequest createRequest(String base, String contextPath,
+ String servletPath, String pathInfo) throws MalformedURLException {
+ URL url = new URL(base + contextPath + pathInfo);
+ HttpServletRequest request = createMock(HttpServletRequest.class);
+ expect(request.isSecure()).andReturn(
+ url.getProtocol().equalsIgnoreCase("https")).anyTimes();
+ expect(request.getServerName()).andReturn(url.getHost()).anyTimes();
+ expect(request.getServerPort()).andReturn(url.getPort()).anyTimes();
+ expect(request.getRequestURI()).andReturn(url.getPath()).anyTimes();
+ expect(request.getContextPath()).andReturn(contextPath).anyTimes();
+ expect(request.getPathInfo()).andReturn(pathInfo).anyTimes();
+ expect(request.getServletPath()).andReturn(servletPath).anyTimes();
+
+ return request;
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/VaadinClasses.java b/server/tests/src/com/vaadin/tests/VaadinClasses.java
new file mode 100644
index 0000000000..15e1283e47
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/VaadinClasses.java
@@ -0,0 +1,257 @@
+package com.vaadin.tests;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.net.JarURLConnection;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.jar.JarEntry;
+
+import com.vaadin.Application;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.ComponentContainer;
+import com.vaadin.ui.CustomComponent;
+import com.vaadin.ui.DragAndDropWrapper;
+import com.vaadin.ui.Field;
+import com.vaadin.ui.HorizontalSplitPanel;
+import com.vaadin.ui.LoginForm;
+import com.vaadin.ui.PopupView;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalSplitPanel;
+import com.vaadin.ui.Window;
+import com.vaadin.ui.themes.BaseTheme;
+
+import org.junit.Test;
+
+@SuppressWarnings("deprecation")
+public class VaadinClasses {
+
+ public static void main(String[] args) {
+ System.out.println("ComponentContainers");
+ System.out.println("===================");
+ for (Class<? extends ComponentContainer> c : getComponentContainers()) {
+ System.out.println(c.getName());
+ }
+ System.out.println();
+ System.out.println("Components");
+ System.out.println("==========");
+ for (Class<? extends Component> c : getComponents()) {
+ System.out.println(c.getName());
+ }
+ System.out.println();
+ System.out.println("Server side classes");
+ System.out.println("===================");
+ for (Class<?> c : getAllServerSideClasses()) {
+ System.out.println(c.getName());
+ }
+ }
+
+ public static List<Class<? extends Component>> getComponents() {
+ try {
+ return findClasses(Component.class, "com.vaadin.ui");
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public static List<Class<? extends Field>> getFields() {
+ try {
+ return findClasses(Field.class, "com.vaadin.ui");
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public static List<Class<? extends BaseTheme>> getThemeClasses() {
+ try {
+ return findClasses(BaseTheme.class, "com.vaadin.ui.themes");
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public static List<Class<? extends Object>> getAllServerSideClasses() {
+ try {
+ return findClassesNoTests(Object.class, "com.vaadin", new String[] {
+ "com.vaadin.tests", "com.vaadin.client" });
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public static List<Class<? extends ComponentContainer>> getComponentContainers() {
+ try {
+ return findClasses(ComponentContainer.class, "com.vaadin.ui");
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public static List<Class<? extends ComponentContainer>> getComponentContainersSupportingAddRemoveComponent() {
+ List<Class<? extends ComponentContainer>> classes = getComponentContainers();
+ classes.remove(PopupView.class);
+ classes.remove(CustomComponent.class);
+ classes.remove(DragAndDropWrapper.class);
+ classes.remove(CustomComponent.class);
+ classes.remove(LoginForm.class);
+ classes.remove(UI.class);
+
+ return classes;
+ }
+
+ public static List<Class<? extends ComponentContainer>> getComponentContainersSupportingUnlimitedNumberOfComponents() {
+ List<Class<? extends ComponentContainer>> classes = getComponentContainersSupportingAddRemoveComponent();
+ classes.remove(VerticalSplitPanel.class);
+ classes.remove(HorizontalSplitPanel.class);
+ classes.remove(Window.class);
+
+ return classes;
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public static List<Class<?>> getBasicComponentTests() {
+ try {
+ // Given as name to avoid dependencies on testbench source folder
+ return (List) findClasses(
+ Class.forName("com.vaadin.tests.components.AbstractComponentTest"),
+ "com.vaadin.tests.components");
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+
+ }
+
+ private static <T> List<Class<? extends T>> findClasses(Class<T> baseClass,
+ String basePackage) throws IOException {
+ return findClasses(baseClass, basePackage, new String[] {});
+ }
+
+ private static <T> List<Class<? extends T>> findClasses(Class<T> baseClass,
+ String basePackage, String[] ignoredPackages) throws IOException {
+ List<Class<? extends T>> classes = new ArrayList<Class<? extends T>>();
+ String basePackageDirName = "/" + basePackage.replace('.', '/');
+ URL location = Application.class.getResource(basePackageDirName);
+ if (location.getProtocol().equals("file")) {
+ try {
+ File f = new File(location.toURI());
+ if (!f.exists()) {
+ throw new IOException("Directory " + f.toString()
+ + " does not exist");
+ }
+ findPackages(f, basePackage, baseClass, classes,
+ ignoredPackages);
+ } catch (URISyntaxException e) {
+ throw new IOException(e.getMessage());
+ }
+ } else if (location.getProtocol().equals("jar")) {
+ JarURLConnection juc = (JarURLConnection) location.openConnection();
+ findPackages(juc, basePackage, baseClass, classes);
+ }
+
+ Collections.sort(classes, new Comparator<Class<? extends T>>() {
+
+ @Override
+ public int compare(Class<? extends T> o1, Class<? extends T> o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+
+ });
+ return classes;
+ }
+
+ private static <T> List<Class<? extends T>> findClassesNoTests(
+ Class<T> baseClass, String basePackage, String[] ignoredPackages)
+ throws IOException {
+ List<Class<? extends T>> classes = findClasses(baseClass, basePackage,
+ ignoredPackages);
+ List<Class<? extends T>> classesNoTests = new ArrayList<Class<? extends T>>();
+ for (Class<? extends T> clazz : classes) {
+ if (!clazz.getName().contains("Test")) {
+ boolean testPresent = false;
+ for (Method method : clazz.getMethods()) {
+ if (method.isAnnotationPresent(Test.class)) {
+ testPresent = true;
+ break;
+ }
+ }
+ if (!testPresent) {
+ classesNoTests.add(clazz);
+ }
+ }
+ }
+ return classesNoTests;
+ }
+
+ private static <T> void findPackages(JarURLConnection juc,
+ String javaPackage, Class<T> baseClass,
+ Collection<Class<? extends T>> result) throws IOException {
+ String prefix = "com/vaadin/ui";
+ Enumeration<JarEntry> ent = juc.getJarFile().entries();
+ while (ent.hasMoreElements()) {
+ JarEntry e = ent.nextElement();
+ if (e.getName().endsWith(".class")
+ && e.getName().startsWith(prefix)) {
+ String fullyQualifiedClassName = e.getName().replace('/', '.')
+ .replace(".class", "");
+ addClassIfMatches(result, fullyQualifiedClassName, baseClass);
+ }
+ }
+ }
+
+ private static <T> void findPackages(File parent, String javaPackage,
+ Class<T> baseClass, Collection<Class<? extends T>> result,
+ String[] ignoredPackages) {
+ for (String ignoredPackage : ignoredPackages) {
+ if (javaPackage.equals(ignoredPackage)) {
+ return;
+ }
+ }
+
+ for (File file : parent.listFiles()) {
+ if (file.isDirectory()) {
+ findPackages(file, javaPackage + "." + file.getName(),
+ baseClass, result, ignoredPackages);
+ } else if (file.getName().endsWith(".class")) {
+ String fullyQualifiedClassName = javaPackage + "."
+ + file.getName().replace(".class", "");
+ addClassIfMatches(result, fullyQualifiedClassName, baseClass);
+ }
+ }
+
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <T> void addClassIfMatches(
+ Collection<Class<? extends T>> result,
+ String fullyQualifiedClassName, Class<T> baseClass) {
+ try {
+ // Try to load the class
+
+ Class<?> c = Class.forName(fullyQualifiedClassName);
+ if (baseClass.isAssignableFrom(c)
+ && !Modifier.isAbstract(c.getModifiers())) {
+ result.add((Class<? extends T>) c);
+ }
+ } catch (Exception e) {
+ // Could ignore that class cannot be loaded
+ e.printStackTrace();
+ } catch (LinkageError e) {
+ // Ignore. Client side classes will at least throw LinkageErrors
+ }
+
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/data/bean/Address.java b/server/tests/src/com/vaadin/tests/data/bean/Address.java
new file mode 100644
index 0000000000..15cdf34ae5
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/data/bean/Address.java
@@ -0,0 +1,63 @@
+package com.vaadin.tests.data.bean;
+
+import java.io.Serializable;
+
+@SuppressWarnings("serial")
+public class Address implements Serializable {
+
+ private String streetAddress = "";
+ private Integer postalCode = null;
+ private String city = "";
+ private Country country = null;
+
+ public Address() {
+
+ }
+
+ public Address(String streetAddress, int postalCode, String city,
+ Country country) {
+ setStreetAddress(streetAddress);
+ setPostalCode(postalCode);
+ setCity(city);
+ setCountry(country);
+ }
+
+ @Override
+ public String toString() {
+ return "Address [streetAddress=" + streetAddress + ", postalCode="
+ + postalCode + ", city=" + city + ", country=" + country + "]";
+ }
+
+ public String getStreetAddress() {
+ return streetAddress;
+ }
+
+ public void setStreetAddress(String streetAddress) {
+ this.streetAddress = streetAddress;
+ }
+
+ public Integer getPostalCode() {
+ return postalCode;
+ }
+
+ public void setPostalCode(Integer postalCode) {
+ this.postalCode = postalCode;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ public Country getCountry() {
+ return country;
+ }
+
+ public void setCountry(Country country) {
+ this.country = country;
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/data/bean/BeanToValidate.java b/server/tests/src/com/vaadin/tests/data/bean/BeanToValidate.java
new file mode 100644
index 0000000000..416563baba
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/data/bean/BeanToValidate.java
@@ -0,0 +1,56 @@
+package com.vaadin.tests.data.bean;
+
+import javax.validation.constraints.Digits;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+
+public class BeanToValidate {
+ @NotNull
+ @Size(min = 3, max = 16)
+ private String firstname;
+
+ @NotNull(message = "Last name must not be empty")
+ private String lastname;
+
+ @Min(value = 18, message = "Must be 18 or above")
+ @Max(150)
+ private int age;
+
+ @Digits(integer = 3, fraction = 2)
+ private String decimals;
+
+ public String getFirstname() {
+ return firstname;
+ }
+
+ public void setFirstname(String firstname) {
+ this.firstname = firstname;
+ }
+
+ public String getLastname() {
+ return lastname;
+ }
+
+ public void setLastname(String lastname) {
+ this.lastname = lastname;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public String getDecimals() {
+ return decimals;
+ }
+
+ public void setDecimals(String decimals) {
+ this.decimals = decimals;
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/data/bean/Country.java b/server/tests/src/com/vaadin/tests/data/bean/Country.java
new file mode 100644
index 0000000000..afdf8dcfa1
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/data/bean/Country.java
@@ -0,0 +1,18 @@
+package com.vaadin.tests.data.bean;
+
+public enum Country {
+
+ FINLAND("Finland"), SWEDEN("Sweden"), USA("USA"), RUSSIA("Russia"), NETHERLANDS(
+ "Netherlands"), SOUTH_AFRICA("South Africa");
+
+ private String name;
+
+ private Country(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/data/bean/Person.java b/server/tests/src/com/vaadin/tests/data/bean/Person.java
new file mode 100644
index 0000000000..f7bad31d0e
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/data/bean/Person.java
@@ -0,0 +1,143 @@
+package com.vaadin.tests.data.bean;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+public class Person {
+ private String firstName;
+ private String lastName;
+ private String email;
+ private int age;
+ private Sex sex;
+ private Address address;
+ private boolean deceased;
+ private Date birthDate;
+
+ private Integer salary; // null if unknown
+ private Double salaryDouble; // null if unknown
+
+ private BigDecimal rent;
+
+ public Person() {
+
+ }
+
+ @Override
+ public String toString() {
+ return "Person [firstName=" + firstName + ", lastName=" + lastName
+ + ", email=" + email + ", age=" + age + ", sex=" + sex
+ + ", address=" + address + ", deceased=" + deceased
+ + ", salary=" + salary + ", salaryDouble=" + salaryDouble
+ + ", rent=" + rent + "]";
+ }
+
+ public Person(String firstName, String lastName, String email, int age,
+ Sex sex, Address address) {
+ super();
+ this.firstName = firstName;
+ this.lastName = lastName;
+ this.email = email;
+ this.age = age;
+ this.sex = sex;
+ this.address = address;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public Address getAddress() {
+ return address;
+ }
+
+ public void setAddress(Address address) {
+ this.address = address;
+ }
+
+ public Sex getSex() {
+ return sex;
+ }
+
+ public void setSex(Sex sex) {
+ this.sex = sex;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public boolean getDeceased() {
+ return deceased;
+ }
+
+ public void setDeceased(boolean deceased) {
+ this.deceased = deceased;
+ }
+
+ public Integer getSalary() {
+ return salary;
+ }
+
+ public void setSalary(Integer salary) {
+ this.salary = salary;
+ }
+
+ public BigDecimal getRent() {
+ return rent;
+ }
+
+ public void setRent(BigDecimal rent) {
+ this.rent = rent;
+ }
+
+ public Double getSalaryDouble() {
+ return salaryDouble;
+ }
+
+ public void setSalaryDouble(Double salaryDouble) {
+ this.salaryDouble = salaryDouble;
+ }
+
+ public Date getBirthDate() {
+ return birthDate;
+ }
+
+ public void setBirthDate(Date birthDate) {
+ this.birthDate = birthDate;
+ }
+
+ public static Person createTestPerson1() {
+ return new Person("Foo", "Bar", "yeah@cool.com", 46, Sex.MALE,
+ new Address("Street", 1123, "Turku", Country.FINLAND));
+ }
+
+ public static Person createTestPerson2() {
+ return new Person("Maya", "Dinkelstein", "maya@foo.bar", 18,
+ Sex.FEMALE, new Address("Red street", 12, "Amsterdam",
+ Country.NETHERLANDS));
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/data/bean/PersonWithBeanValidationAnnotations.java b/server/tests/src/com/vaadin/tests/data/bean/PersonWithBeanValidationAnnotations.java
new file mode 100644
index 0000000000..93b2273263
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/data/bean/PersonWithBeanValidationAnnotations.java
@@ -0,0 +1,156 @@
+package com.vaadin.tests.data.bean;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+import javax.validation.constraints.Digits;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Past;
+import javax.validation.constraints.Size;
+
+public class PersonWithBeanValidationAnnotations {
+ @NotNull
+ @Size(min = 5, max = 20)
+ private String firstName;
+ @NotNull
+ private String lastName;
+
+ private String email;
+
+ @Min(0)
+ @Max(100)
+ private int age;
+
+ @NotNull
+ private Sex sex;
+
+ private Address address;
+ private boolean deceased;
+
+ @NotNull
+ @Past
+ private Date birthDate;
+
+ @Min(0)
+ private Integer salary; // null if unknown
+
+ @Digits(integer = 6, fraction = 2)
+ private Double salaryDouble; // null if unknown
+
+ private BigDecimal rent;
+
+ public PersonWithBeanValidationAnnotations() {
+
+ }
+
+ @Override
+ public String toString() {
+ return "Person [firstName=" + firstName + ", lastName=" + lastName
+ + ", email=" + email + ", age=" + age + ", sex=" + sex
+ + ", address=" + address + ", deceased=" + deceased
+ + ", salary=" + salary + ", salaryDouble=" + salaryDouble
+ + ", rent=" + rent + "]";
+ }
+
+ public PersonWithBeanValidationAnnotations(String firstName,
+ String lastName, String email, int age, Sex sex, Address address) {
+ super();
+ this.firstName = firstName;
+ this.lastName = lastName;
+ this.email = email;
+ this.age = age;
+ this.sex = sex;
+ this.address = address;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public Address getAddress() {
+ return address;
+ }
+
+ public void setAddress(Address address) {
+ this.address = address;
+ }
+
+ public Sex getSex() {
+ return sex;
+ }
+
+ public void setSex(Sex sex) {
+ this.sex = sex;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public boolean getDeceased() {
+ return deceased;
+ }
+
+ public void setDeceased(boolean deceased) {
+ this.deceased = deceased;
+ }
+
+ public Integer getSalary() {
+ return salary;
+ }
+
+ public void setSalary(Integer salary) {
+ this.salary = salary;
+ }
+
+ public BigDecimal getRent() {
+ return rent;
+ }
+
+ public void setRent(BigDecimal rent) {
+ this.rent = rent;
+ }
+
+ public Double getSalaryDouble() {
+ return salaryDouble;
+ }
+
+ public void setSalaryDouble(Double salaryDouble) {
+ this.salaryDouble = salaryDouble;
+ }
+
+ public Date getBirthDate() {
+ return birthDate;
+ }
+
+ public void setBirthDate(Date birthDate) {
+ this.birthDate = birthDate;
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/data/bean/Sex.java b/server/tests/src/com/vaadin/tests/data/bean/Sex.java
new file mode 100644
index 0000000000..a4e3f20a11
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/data/bean/Sex.java
@@ -0,0 +1,20 @@
+package com.vaadin.tests.data.bean;
+
+public enum Sex {
+ MALE("Male"), FEMALE("Female"), UNKNOWN("Unknown");
+
+ private String stringRepresentation;
+
+ private Sex(String stringRepresentation) {
+ this.stringRepresentation = stringRepresentation;
+ }
+
+ public String getStringRepresentation() {
+ return stringRepresentation;
+ }
+
+ @Override
+ public String toString() {
+ return getStringRepresentation();
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/data/converter/ConverterFactory.java b/server/tests/src/com/vaadin/tests/data/converter/ConverterFactory.java
new file mode 100644
index 0000000000..6393d61981
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/data/converter/ConverterFactory.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2011 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.data.converter;
+
+import java.util.Locale;
+
+import junit.framework.TestCase;
+
+import com.vaadin.Application;
+import com.vaadin.data.util.converter.Converter;
+import com.vaadin.data.util.converter.DefaultConverterFactory;
+import com.vaadin.ui.TextField;
+
+public class ConverterFactory extends TestCase {
+
+ public static class ConvertTo42 implements Converter<String, Integer> {
+
+ @Override
+ public Integer convertToModel(String value, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ return 42;
+ }
+
+ @Override
+ public String convertToPresentation(Integer value, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ return "42";
+ }
+
+ @Override
+ public Class<Integer> getModelType() {
+ return Integer.class;
+ }
+
+ @Override
+ public Class<String> getPresentationType() {
+ return String.class;
+ }
+
+ }
+
+ public static class ConverterFactory42 extends DefaultConverterFactory {
+ @Override
+ public <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> createConverter(
+ Class<PRESENTATION> presentationType, Class<MODEL> modelType) {
+ if (modelType == Integer.class) {
+ return (Converter<PRESENTATION, MODEL>) new ConvertTo42();
+ }
+
+ return super.createConverter(presentationType, modelType);
+ }
+ }
+
+ public void testApplicationConverterFactoryInBackgroundThread() {
+ Application.setCurrent(null);
+ final Application appWithCustomIntegerConverter = new Application();
+ appWithCustomIntegerConverter
+ .setConverterFactory(new ConverterFactory42());
+
+ TextField tf = new TextField("", "123") {
+ @Override
+ public Application getApplication() {
+ return appWithCustomIntegerConverter;
+ };
+ };
+ tf.setConverter(Integer.class);
+ // The application converter always returns 42. Current application is
+ // null
+ assertEquals(42, tf.getConvertedValue());
+ }
+
+ public void testApplicationConverterFactoryForDetachedComponent() {
+ final Application appWithCustomIntegerConverter = new Application();
+ appWithCustomIntegerConverter
+ .setConverterFactory(new ConverterFactory42());
+ Application.setCurrent(appWithCustomIntegerConverter);
+
+ TextField tf = new TextField("", "123");
+ tf.setConverter(Integer.class);
+ // The application converter always returns 42. Current application is
+ // null
+ assertEquals(42, tf.getConvertedValue());
+ }
+
+ public void testApplicationConverterFactoryForDifferentThanCurrentApplication() {
+ final Application fieldAppWithCustomIntegerConverter = new Application();
+ fieldAppWithCustomIntegerConverter
+ .setConverterFactory(new ConverterFactory42());
+ Application.setCurrent(new Application());
+
+ TextField tf = new TextField("", "123") {
+ @Override
+ public Application getApplication() {
+ return fieldAppWithCustomIntegerConverter;
+ }
+ };
+ tf.setConverter(Integer.class);
+
+ // The application converter always returns 42. Application.getCurrent()
+ // should not be used
+ assertEquals(42, tf.getConvertedValue());
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/IndexedContainerListeners.java b/server/tests/src/com/vaadin/tests/server/IndexedContainerListeners.java
new file mode 100644
index 0000000000..8334c7f183
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/IndexedContainerListeners.java
@@ -0,0 +1,20 @@
+package com.vaadin.tests.server;
+
+import com.vaadin.data.Container.PropertySetChangeEvent;
+import com.vaadin.data.Container.PropertySetChangeListener;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+
+public class IndexedContainerListeners extends AbstractListenerMethodsTest {
+ public void testValueChangeListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(IndexedContainer.class,
+ ValueChangeEvent.class, ValueChangeListener.class);
+ }
+
+ public void testPropertySetChangeListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(IndexedContainer.class,
+ PropertySetChangeEvent.class, PropertySetChangeListener.class);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/PropertysetItemListeners.java b/server/tests/src/com/vaadin/tests/server/PropertysetItemListeners.java
new file mode 100644
index 0000000000..d493f22779
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/PropertysetItemListeners.java
@@ -0,0 +1,13 @@
+package com.vaadin.tests.server;
+
+import com.vaadin.data.Item.PropertySetChangeEvent;
+import com.vaadin.data.Item.PropertySetChangeListener;
+import com.vaadin.data.util.PropertysetItem;
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+
+public class PropertysetItemListeners extends AbstractListenerMethodsTest {
+ public void testPropertySetChangeListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(PropertysetItem.class,
+ PropertySetChangeEvent.class, PropertySetChangeListener.class);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/SourceFileChecker.java b/server/tests/src/com/vaadin/tests/server/SourceFileChecker.java
new file mode 100644
index 0000000000..1ab742427d
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/SourceFileChecker.java
@@ -0,0 +1,217 @@
+package com.vaadin.tests.server;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.commons.io.IOUtils;
+
+public class SourceFileChecker extends TestCase {
+
+ /**
+ * The tests are run in the build directory.
+ */
+ public static String baseDirectory = null;
+ public static final String SRC_DIR = getBaseDir() + "src";
+ public static final String TESTBENCH_SRC_DIR = getBaseDir()
+ + "tests/testbench";
+ public static final String SERVERSIDE_SRC_DIR = getBaseDir()
+ + "tests/server-side";
+ public static final String CLIENTSIDE_SRC_DIR = getBaseDir()
+ + "tests/client-side";
+ private String externalJavaFiles = "com/vaadin/external";
+ private String buildFiles = "build";
+ private Set<String> alwaysIgnore = new HashSet<String>();
+ {
+ alwaysIgnore.add(".settings");
+ alwaysIgnore.add("eclipse");
+ }
+
+ public static String getBaseDir() {
+ if (baseDirectory != null) {
+ return baseDirectory;
+ }
+ // Run in the "build" directory by build, in the project root by Eclipse
+ for (File f : new File(".").listFiles()) {
+ if (f.getName().equals("buildhelpers")) {
+ // We are in "build"
+ baseDirectory = "../";
+ return baseDirectory;
+ }
+ }
+
+ baseDirectory = "./";
+ return baseDirectory;
+ }
+
+ private static final String[] ALL_SRC_DIRS = new String[] { SRC_DIR,
+ TESTBENCH_SRC_DIR, SERVERSIDE_SRC_DIR, CLIENTSIDE_SRC_DIR };
+
+ public void testJavaFilesContainsLicense() throws IOException {
+ Set<String> ignore = new HashSet<String>(alwaysIgnore);
+ ignore.add(externalJavaFiles);
+ validateFiles(SRC_DIR, new LicenseChecker(), ignore,
+ "The following files are missing license information:\n{0}",
+ ".java");
+ }
+
+ public void testNonJavaFilesUseUnixNewline() throws IOException {
+ Set<String> ignore = new HashSet<String>(alwaysIgnore);
+ ignore.add(buildFiles);
+
+ for (String suffix : new String[] { ".html", ".css", ".xml" }) {
+ validateFiles(getBaseDir(), new DosNewlineDetector(), ignore,
+ "The following files contain CRLF instead of LF:\n{0}",
+ suffix);
+ }
+ }
+
+ public void testJavaFilesUseUnixNewline() throws IOException {
+ Set<String> ignore = new HashSet<String>(alwaysIgnore);
+ ignore.add(externalJavaFiles);
+ for (String dir : ALL_SRC_DIRS) {
+ validateFiles(dir, new DosNewlineDetector(), ignore,
+ "The following files contain CRLF instead of LF:\n{0}",
+ ".java");
+ }
+ }
+
+ public void testGwtFilesUsingEntry() {
+ Set<String> ignore = new HashSet<String>(alwaysIgnore);
+ ignore.add(externalJavaFiles);
+ validateFiles(
+ SRC_DIR,
+ new GwtEntryChecker(),
+ ignore,
+ "The following files might export javscript callbacks without $entry:\n{0}",
+ ".java");
+ }
+
+ public interface FileValidator {
+ void validateFile(File f) throws Exception;
+ }
+
+ private void validateFiles(String directory, FileValidator validator,
+ Set<String> ignore, String errorMessage, String ending) {
+ File srcDir = new File(directory);
+ HashSet<String> missing = new HashSet<String>();
+ validateFiles(directory, srcDir, missing, validator, ending, ignore);
+ if (!missing.isEmpty()) {
+ throw new RuntimeException(errorMessage.replace("{0}", missing
+ .toString().replace(',', '\n')));
+ }
+
+ }
+
+ private void validateFiles(String baseDirectory, File directory,
+ HashSet<String> missing, FileValidator validator, String suffix,
+ Set<String> ignores) {
+ Assert.assertTrue("Directory " + directory + " does not exist",
+ directory.exists());
+
+ File[] files = directory.listFiles();
+ if (files == null) {
+ throw new RuntimeException("Listing of directory "
+ + directory.getPath() + " failed");
+ }
+ for (File f : files) {
+ boolean ignoreThis = false;
+ for (String ignore : ignores) {
+ if (new File(baseDirectory, ignore).equals(f)) {
+ ignoreThis = true;
+ continue;
+ }
+ }
+
+ if (ignoreThis) {
+ continue;
+ }
+
+ if (f.isDirectory()) {
+ validateFiles(baseDirectory, f, missing, validator, suffix,
+ ignores);
+ } else if (f.getName().endsWith(suffix)) {
+ try {
+ validator.validateFile(f);
+ } catch (Throwable t) {
+ missing.add(f.getPath());
+ }
+ }
+ }
+ }
+
+ abstract class FileContentsValidator implements FileValidator {
+ @Override
+ public void validateFile(File f) throws Exception {
+ FileInputStream fis = new FileInputStream(f);
+ String contents = IOUtils.toString(fis);
+ fis.close();
+ validateContents(f, contents);
+ }
+
+ protected abstract void validateContents(File f, String contents)
+ throws Exception;
+
+ }
+
+ class DosNewlineDetector extends FileContentsValidator {
+
+ @Override
+ protected void validateContents(File f, String contents)
+ throws Exception {
+ if (contents.contains("\r\n")) {
+ throw new IllegalArgumentException();
+ }
+
+ }
+
+ }
+
+ class LicenseChecker extends FileContentsValidator {
+
+ @Override
+ protected void validateContents(File f, String contents)
+ throws Exception {
+ if (!contents.contains("@" + "VaadinApache2LicenseForJavaFiles"
+ + "@")) {
+ throw new IllegalArgumentException();
+ }
+ }
+ }
+
+ class GwtEntryChecker extends FileContentsValidator {
+ // Matches e.g.
+ // @com.vaadin.client.HistoryImplIEVaadin::escapeHtml(
+ private final Matcher matcher = Pattern.compile("@[\\w.]+::\\w+\\(")
+ .matcher("");
+
+ @Override
+ protected void validateContents(File f, String contents)
+ throws Exception {
+ matcher.reset(contents);
+ while (matcher.find()) {
+ int start = matcher.start();
+
+ // Search backwards to find index of native block start
+ int nativeBlockStart = contents.lastIndexOf("/*-{", start);
+
+ // Get contents between block start and our match
+ String beforeMatchInBlock = contents.substring(
+ nativeBlockStart, start);
+
+ // Fail if there's no $entry
+ if (!beforeMatchInBlock.contains("$entry")) {
+ throw new IllegalArgumentException();
+ }
+ }
+ }
+
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/TestAbstractBeanContainerListeners.java b/server/tests/src/com/vaadin/tests/server/TestAbstractBeanContainerListeners.java
new file mode 100644
index 0000000000..0d8433d1c6
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/TestAbstractBeanContainerListeners.java
@@ -0,0 +1,16 @@
+package com.vaadin.tests.server;
+
+import com.vaadin.data.Container.PropertySetChangeEvent;
+import com.vaadin.data.Container.PropertySetChangeListener;
+import com.vaadin.data.util.BeanItemContainer;
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+
+public class TestAbstractBeanContainerListeners extends
+ AbstractListenerMethodsTest {
+ public void testPropertySetChangeListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(BeanItemContainer.class,
+ PropertySetChangeEvent.class, PropertySetChangeListener.class,
+ new BeanItemContainer<PropertySetChangeListener>(
+ PropertySetChangeListener.class));
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/TestAbstractContainerListeners.java b/server/tests/src/com/vaadin/tests/server/TestAbstractContainerListeners.java
new file mode 100644
index 0000000000..b63e4f809a
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/TestAbstractContainerListeners.java
@@ -0,0 +1,21 @@
+package com.vaadin.tests.server;
+
+import com.vaadin.data.Container.ItemSetChangeEvent;
+import com.vaadin.data.Container.ItemSetChangeListener;
+import com.vaadin.data.Container.PropertySetChangeEvent;
+import com.vaadin.data.Container.PropertySetChangeListener;
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+
+public class TestAbstractContainerListeners extends AbstractListenerMethodsTest {
+
+ public void testItemSetChangeListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(IndexedContainer.class,
+ ItemSetChangeEvent.class, ItemSetChangeListener.class);
+ }
+
+ public void testPropertySetChangeListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(IndexedContainer.class,
+ PropertySetChangeEvent.class, PropertySetChangeListener.class);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/TestAbstractInMemoryContainerListeners.java b/server/tests/src/com/vaadin/tests/server/TestAbstractInMemoryContainerListeners.java
new file mode 100644
index 0000000000..a8e2a4aa2a
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/TestAbstractInMemoryContainerListeners.java
@@ -0,0 +1,14 @@
+package com.vaadin.tests.server;
+
+import com.vaadin.data.Container.ItemSetChangeEvent;
+import com.vaadin.data.Container.ItemSetChangeListener;
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+
+public class TestAbstractInMemoryContainerListeners extends
+ AbstractListenerMethodsTest {
+ public void testItemSetChangeListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(IndexedContainer.class,
+ ItemSetChangeEvent.class, ItemSetChangeListener.class);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/TestAbstractPropertyListeners.java b/server/tests/src/com/vaadin/tests/server/TestAbstractPropertyListeners.java
new file mode 100644
index 0000000000..a1d01d1930
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/TestAbstractPropertyListeners.java
@@ -0,0 +1,24 @@
+package com.vaadin.tests.server;
+
+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.data.util.AbstractProperty;
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+
+public class TestAbstractPropertyListeners extends AbstractListenerMethodsTest {
+ public void testValueChangeListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(AbstractProperty.class,
+ ValueChangeEvent.class, ValueChangeListener.class,
+ new ObjectProperty<String>(""));
+ }
+
+ public void testReadOnlyStatusChangeListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(AbstractProperty.class,
+ ReadOnlyStatusChangeEvent.class,
+ ReadOnlyStatusChangeListener.class, new ObjectProperty<String>(
+ ""));
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java b/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java
new file mode 100644
index 0000000000..e98be99cbc
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java
@@ -0,0 +1,271 @@
+package com.vaadin.tests.server;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+import junit.framework.TestCase;
+
+import org.junit.Test;
+
+public class TestClassesSerializable extends TestCase {
+
+ /**
+ * JARs that will be scanned for classes to test, in addition to classpath
+ * directories.
+ */
+ private static String JAR_PATTERN = ".*vaadin.*\\.jar";
+
+ private static String[] BASE_PACKAGES = { "com.vaadin" };
+
+ private static String[] EXCLUDED_PATTERNS = {
+ "com\\.vaadin\\.demo\\..*", //
+ "com\\.vaadin\\.external\\.org\\.apache\\.commons\\.fileupload\\..*", //
+ "com\\.vaadin\\.launcher\\..*", //
+ "com\\.vaadin\\.client\\..*", //
+ "com\\.vaadin\\.server\\.widgetsetutils\\..*", //
+ "com\\.vaadin\\.tests\\..*", // exclude automated tests
+ "com\\.vaadin\\.tools\\..*", //
+ "com\\.vaadin\\.ui\\.themes\\..*", //
+ // exact class level filtering
+ "com\\.vaadin\\.event\\.FieldEvents", //
+ "com\\.vaadin\\.event\\.LayoutEvents", //
+ "com\\.vaadin\\.event\\.MouseEvents", //
+ "com\\.vaadin\\.server\\.AbstractApplicationPortlet", //
+ "com\\.vaadin\\.server\\.ApplicationPortlet2", //
+ "com\\.vaadin\\.server\\.Constants", //
+ "com\\.vaadin\\.util\\.SerializerHelper", // fully static
+ // class level filtering, also affecting nested classes and
+ // interfaces
+ "com\\.vaadin\\.server\\.AbstractCommunicationManager.*", //
+ "com\\.vaadin\\.server\\.CommunicationManager.*", //
+ "com\\.vaadin\\.server\\.PortletCommunicationManager.*", //
+ };
+
+ /**
+ * Tests that all the relevant classes and interfaces under
+ * {@link #BASE_PACKAGES} implement Serializable.
+ *
+ * @throws Exception
+ */
+ public void testClassesSerializable() throws Exception {
+ List<String> rawClasspathEntries = getRawClasspathEntries();
+
+ List<String> classes = new ArrayList<String>();
+ for (String location : rawClasspathEntries) {
+ classes.addAll(findServerClasses(location));
+ }
+
+ ArrayList<Class<?>> nonSerializableClasses = new ArrayList<Class<?>>();
+ for (String className : classes) {
+ Class<?> cls = Class.forName(className);
+ // skip annotations and synthetic classes
+ if (cls.isAnnotation() || cls.isSynthetic()) {
+ continue;
+ }
+ // Don't add classes that have a @Test annotation on any methods
+ boolean testPresent = false;
+ for (Method method : cls.getMethods()) {
+ if (method.isAnnotationPresent(Test.class)) {
+ testPresent = true;
+ break;
+ }
+ }
+ if (testPresent) {
+ continue;
+ }
+
+ // report non-serializable classes and interfaces
+ if (!Serializable.class.isAssignableFrom(cls)) {
+ nonSerializableClasses.add(cls);
+ // TODO easier to read when testing
+ // System.err.println(cls);
+ }
+ }
+
+ // useful failure message including all non-serializable classes and
+ // interfaces
+ if (!nonSerializableClasses.isEmpty()) {
+ String nonSerializableString = "";
+ Iterator<Class<?>> it = nonSerializableClasses.iterator();
+ while (it.hasNext()) {
+ Class c = it.next();
+ nonSerializableString += ", " + c.getName();
+ if (c.isAnonymousClass()) {
+ nonSerializableString += "(super: ";
+ nonSerializableString += c.getSuperclass().getName();
+ nonSerializableString += ", interfaces: ";
+ for (Class i : c.getInterfaces()) {
+ nonSerializableString += i.getName();
+ nonSerializableString += ",";
+ }
+ nonSerializableString += ")";
+ }
+ }
+ fail("Serializable not implemented by the following classes and interfaces: "
+ + nonSerializableString);
+ }
+ }
+
+ /**
+ * Lists all class path entries by splitting the class path string.
+ *
+ * Adapted from ClassPathExplorer.getRawClasspathEntries(), but without
+ * filtering.
+ *
+ * @return List of class path segment strings
+ */
+ //
+ private final static List<String> getRawClasspathEntries() {
+ // try to keep the order of the classpath
+ List<String> locations = new ArrayList<String>();
+
+ String pathSep = System.getProperty("path.separator");
+ String classpath = System.getProperty("java.class.path");
+
+ if (classpath.startsWith("\"")) {
+ classpath = classpath.substring(1);
+ }
+ if (classpath.endsWith("\"")) {
+ classpath = classpath.substring(0, classpath.length() - 1);
+ }
+
+ String[] split = classpath.split(pathSep);
+ for (int i = 0; i < split.length; i++) {
+ String classpathEntry = split[i];
+ locations.add(classpathEntry);
+ }
+
+ return locations;
+ }
+
+ /**
+ * Finds the server side classes/interfaces under a class path entry -
+ * either a directory or a JAR that matches {@link #JAR_PATTERN}.
+ *
+ * Only classes under {@link #BASE_PACKAGES} are considered, and those
+ * matching {@link #EXCLUDED_PATTERNS} are filtered out.
+ *
+ * @param classpathEntry
+ * @return
+ * @throws IOException
+ */
+ private List<String> findServerClasses(String classpathEntry)
+ throws IOException {
+ Collection<String> classes = new ArrayList<String>();
+
+ File file = new File(classpathEntry);
+ if (file.isDirectory()) {
+ classes = findClassesInDirectory(null, file);
+ } else if (file.getName().matches(JAR_PATTERN)) {
+ classes = findClassesInJar(file);
+ } else {
+ System.out.println("Ignoring " + classpathEntry);
+ return Collections.emptyList();
+ }
+
+ List<String> filteredClasses = new ArrayList<String>();
+ for (String className : classes) {
+ boolean ok = false;
+ for (String basePackage : BASE_PACKAGES) {
+ if (className.startsWith(basePackage + ".")) {
+ ok = true;
+ break;
+ }
+ }
+ for (String excludedPrefix : EXCLUDED_PATTERNS) {
+ if (className.matches(excludedPrefix)) {
+ ok = false;
+ break;
+ }
+ }
+
+ // Don't add test classes
+ if (className.contains("Test")) {
+ ok = false;
+ }
+
+ if (ok) {
+ filteredClasses.add(className);
+ }
+ }
+
+ return filteredClasses;
+ }
+
+ /**
+ * Lists class names (based on .class files) in a JAR file.
+ *
+ * @param file
+ * a valid JAR file
+ * @return collection of fully qualified class names in the JAR
+ * @throws IOException
+ */
+ private Collection<String> findClassesInJar(File file) throws IOException {
+ Collection<String> classes = new ArrayList<String>();
+
+ JarFile jar = new JarFile(file);
+ Enumeration<JarEntry> e = jar.entries();
+ while (e.hasMoreElements()) {
+ JarEntry entry = e.nextElement();
+ if (entry.getName().endsWith(".class")) {
+ String nameWithoutExtension = entry.getName().replaceAll(
+ "\\.class", "");
+ String className = nameWithoutExtension.replace('/', '.');
+ classes.add(className);
+ }
+ }
+ return classes;
+ }
+
+ /**
+ * Lists class names (based on .class files) in a directory (a package path
+ * root).
+ *
+ * @param parentPackage
+ * parent package name or null at root of hierarchy, used by
+ * recursion
+ * @param parent
+ * File representing the directory to scan
+ * @return collection of fully qualified class names in the directory
+ */
+ private final static Collection<String> findClassesInDirectory(
+ String parentPackage, File parent) {
+ if (parent.isHidden()
+ || parent.getPath().contains(File.separator + ".")) {
+ return Collections.emptyList();
+ }
+
+ if (parentPackage == null) {
+ parentPackage = "";
+ } else {
+ parentPackage += ".";
+ }
+
+ Collection<String> classNames = new ArrayList<String>();
+
+ // add all directories recursively
+ File[] files = parent.listFiles();
+ for (File child : files) {
+ if (child.isDirectory()) {
+ classNames.addAll(findClassesInDirectory(
+ parentPackage + child.getName(), child));
+ } else if (child.getName().endsWith(".class")) {
+ classNames.add(parentPackage.replace(File.separatorChar, '.')
+ + child.getName().replaceAll("\\.class", ""));
+ }
+ }
+
+ return classNames;
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/server/TestEventRouter.java b/server/tests/src/com/vaadin/tests/server/TestEventRouter.java
new file mode 100644
index 0000000000..a8f5039042
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/TestEventRouter.java
@@ -0,0 +1,39 @@
+package com.vaadin.tests.server;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.ui.TextField;
+
+public class TestEventRouter extends TestCase {
+
+ int innerListenerCalls = 0;
+
+ public void testAddInEventListener() {
+ final TextField tf = new TextField();
+
+ final ValueChangeListener outer = new ValueChangeListener() {
+
+ @Override
+ public void valueChange(ValueChangeEvent event) {
+ ValueChangeListener inner = new ValueChangeListener() {
+
+ @Override
+ public void valueChange(ValueChangeEvent event) {
+ innerListenerCalls++;
+ System.out.println("The inner listener was called");
+ }
+ };
+
+ tf.addListener(inner);
+ }
+ };
+
+ tf.addListener(outer);
+ tf.setValue("abc"); // No inner listener calls, adds one inner
+ tf.setValue("def"); // One inner listener call, adds one inner
+ tf.setValue("ghi"); // Two inner listener calls, adds one inner
+ assert (innerListenerCalls == 3);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/TestFileTypeResolver.java b/server/tests/src/com/vaadin/tests/server/TestFileTypeResolver.java
new file mode 100644
index 0000000000..8a368ead53
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/TestFileTypeResolver.java
@@ -0,0 +1,79 @@
+package com.vaadin.tests.server;
+
+import java.io.File;
+
+import junit.framework.TestCase;
+
+import com.vaadin.service.FileTypeResolver;
+
+public class TestFileTypeResolver extends TestCase {
+
+ private static final String FLASH_MIME_TYPE = "application/x-shockwave-flash";
+ private static final String TEXT_MIME_TYPE = "text/plain";
+ private static final String HTML_MIME_TYPE = "text/html";
+
+ public void testMimeTypes() {
+ File plainFlash = new File("MyFlash.swf");
+ File plainText = new File("/a/b/MyFlash.txt");
+ File plainHtml = new File("c:\\MyFlash.html");
+
+ // Flash
+ assertEquals(
+ FileTypeResolver.getMIMEType(plainFlash.getAbsolutePath()),
+ FLASH_MIME_TYPE);
+ assertEquals(
+ FileTypeResolver.getMIMEType(plainFlash.getAbsolutePath()
+ + "?param1=value1"), FLASH_MIME_TYPE);
+ assertEquals(
+ FileTypeResolver.getMIMEType(plainFlash.getAbsolutePath()
+ + "?param1=value1&param2=value2"), FLASH_MIME_TYPE);
+
+ // Plain text
+ assertEquals(FileTypeResolver.getMIMEType(plainText.getAbsolutePath()),
+ TEXT_MIME_TYPE);
+ assertEquals(
+ FileTypeResolver.getMIMEType(plainText.getAbsolutePath()
+ + "?param1=value1"), TEXT_MIME_TYPE);
+ assertEquals(
+ FileTypeResolver.getMIMEType(plainText.getAbsolutePath()
+ + "?param1=value1&param2=value2"), TEXT_MIME_TYPE);
+
+ // Plain text
+ assertEquals(FileTypeResolver.getMIMEType(plainHtml.getAbsolutePath()),
+ HTML_MIME_TYPE);
+ assertEquals(
+ FileTypeResolver.getMIMEType(plainHtml.getAbsolutePath()
+ + "?param1=value1"), HTML_MIME_TYPE);
+ assertEquals(
+ FileTypeResolver.getMIMEType(plainHtml.getAbsolutePath()
+ + "?param1=value1&param2=value2"), HTML_MIME_TYPE);
+
+ // Filename missing
+ assertEquals(FileTypeResolver.DEFAULT_MIME_TYPE,
+ FileTypeResolver.getMIMEType(""));
+ assertEquals(FileTypeResolver.DEFAULT_MIME_TYPE,
+ FileTypeResolver.getMIMEType("?param1"));
+
+ }
+
+ public void testExtensionCase() {
+ assertEquals("image/jpeg", FileTypeResolver.getMIMEType("abc.jpg"));
+ assertEquals("image/jpeg", FileTypeResolver.getMIMEType("abc.jPg"));
+ assertEquals("image/jpeg", FileTypeResolver.getMIMEType("abc.JPG"));
+ assertEquals("image/jpeg", FileTypeResolver.getMIMEType("abc.JPEG"));
+ assertEquals("image/jpeg", FileTypeResolver.getMIMEType("abc.Jpeg"));
+ assertEquals("image/jpeg", FileTypeResolver.getMIMEType("abc.JPE"));
+ }
+
+ public void testCustomMimeType() {
+ assertEquals(FileTypeResolver.DEFAULT_MIME_TYPE,
+ FileTypeResolver.getMIMEType("vaadin.foo"));
+
+ FileTypeResolver.addExtension("foo", "Vaadin Foo/Bar");
+ FileTypeResolver.addExtension("FOO2", "Vaadin Foo/Bar2");
+ assertEquals("Vaadin Foo/Bar",
+ FileTypeResolver.getMIMEType("vaadin.foo"));
+ assertEquals("Vaadin Foo/Bar2",
+ FileTypeResolver.getMIMEType("vaadin.Foo2"));
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/TestKeyMapper.java b/server/tests/src/com/vaadin/tests/server/TestKeyMapper.java
new file mode 100644
index 0000000000..1c1f9624c8
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/TestKeyMapper.java
@@ -0,0 +1,102 @@
+package com.vaadin.tests.server;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+
+import junit.framework.TestCase;
+
+import com.vaadin.server.KeyMapper;
+
+public class TestKeyMapper extends TestCase {
+
+ public void testAdd() {
+ KeyMapper<Object> mapper = new KeyMapper<Object>();
+ Object o1 = new Object();
+ Object o2 = new Object();
+ Object o3 = new Object();
+
+ // Create new ids
+ String key1 = mapper.key(o1);
+ String key2 = mapper.key(o2);
+ String key3 = mapper.key(o3);
+
+ assertEquals(mapper.get(key1), o1);
+ assertEquals(mapper.get(key2), o2);
+ assertEquals(mapper.get(key3), o3);
+ assertNotSame(key1, key2);
+ assertNotSame(key1, key3);
+ assertNotSame(key2, key3);
+
+ assertSize(mapper, 3);
+
+ // Key should not add if there already is a mapping
+ assertEquals(mapper.key(o3), key3);
+ assertSize(mapper, 3);
+
+ // Remove -> add should return a new key
+ mapper.remove(o1);
+ String newkey1 = mapper.key(o1);
+ assertNotSame(key1, newkey1);
+
+ }
+
+ public void testRemoveAll() {
+ KeyMapper<Object> mapper = new KeyMapper<Object>();
+ Object o1 = new Object();
+ Object o2 = new Object();
+ Object o3 = new Object();
+
+ // Create new ids
+ mapper.key(o1);
+ mapper.key(o2);
+ mapper.key(o3);
+
+ assertSize(mapper, 3);
+ mapper.removeAll();
+ assertSize(mapper, 0);
+
+ }
+
+ public void testRemove() {
+ KeyMapper<Object> mapper = new KeyMapper<Object>();
+ Object o1 = new Object();
+ Object o2 = new Object();
+ Object o3 = new Object();
+
+ // Create new ids
+ mapper.key(o1);
+ mapper.key(o2);
+ mapper.key(o3);
+
+ assertSize(mapper, 3);
+ mapper.remove(o1);
+ assertSize(mapper, 2);
+ mapper.key(o1);
+ assertSize(mapper, 3);
+ mapper.remove(o1);
+ assertSize(mapper, 2);
+
+ mapper.remove(o2);
+ mapper.remove(o3);
+ assertSize(mapper, 0);
+
+ }
+
+ private void assertSize(KeyMapper<?> mapper, int i) {
+ try {
+ Field f1 = KeyMapper.class.getDeclaredField("objectKeyMap");
+ Field f2 = KeyMapper.class.getDeclaredField("keyObjectMap");
+ f1.setAccessible(true);
+ f2.setAccessible(true);
+
+ HashMap<?, ?> h1 = (HashMap<?, ?>) f1.get(mapper);
+ HashMap<?, ?> h2 = (HashMap<?, ?>) f2.get(mapper);
+
+ assertEquals(i, h1.size());
+ assertEquals(i, h2.size());
+ } catch (Throwable t) {
+ t.printStackTrace();
+ fail();
+ }
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/TestMimeTypes.java b/server/tests/src/com/vaadin/tests/server/TestMimeTypes.java
new file mode 100644
index 0000000000..dc730f6cc4
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/TestMimeTypes.java
@@ -0,0 +1,26 @@
+package com.vaadin.tests.server;
+
+import junit.framework.TestCase;
+
+import com.vaadin.Application;
+import com.vaadin.server.ClassResource;
+import com.vaadin.ui.Embedded;
+
+public class TestMimeTypes extends TestCase {
+
+ public void testEmbeddedPDF() {
+ Application app = new Application() {
+
+ @Override
+ public void init() {
+ // TODO Auto-generated method stub
+
+ }
+ };
+ Embedded e = new Embedded("A pdf", new ClassResource("file.pddf"));
+ assertEquals("Invalid mimetype", "application/octet-stream",
+ e.getMimeType());
+ e = new Embedded("A pdf", new ClassResource("file.pdf"));
+ assertEquals("Invalid mimetype", "application/pdf", e.getMimeType());
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/TestPropertyFormatter.java b/server/tests/src/com/vaadin/tests/server/TestPropertyFormatter.java
new file mode 100644
index 0000000000..48c60c83c4
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/TestPropertyFormatter.java
@@ -0,0 +1,75 @@
+package com.vaadin.tests.server;
+
+import java.util.Date;
+
+import junit.framework.TestCase;
+
+import org.junit.Test;
+
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.data.util.PropertyFormatter;
+
+@SuppressWarnings("unchecked")
+public class TestPropertyFormatter extends TestCase {
+
+ class TestFormatter extends PropertyFormatter {
+
+ @Override
+ public String format(Object value) {
+ boolean isCorrectType = getExpectedClass().isAssignableFrom(
+ value.getClass());
+ assertTrue(isCorrectType);
+ return "FOO";
+ }
+
+ @Override
+ public Object parse(String formattedValue) throws Exception {
+ return getExpectedClass().newInstance();
+ }
+ };
+
+ @SuppressWarnings("rawtypes")
+ private Class expectedClass;
+
+ @SuppressWarnings("rawtypes")
+ private Class getExpectedClass() {
+ return expectedClass;
+ }
+
+ /**
+ * The object passed to format should be same as property's type.
+ *
+ * @throws IllegalAccessException
+ * @throws InstantiationException
+ */
+ @Test
+ @SuppressWarnings({ "rawtypes" })
+ public void testCorrectTypeForFormat() throws InstantiationException,
+ IllegalAccessException {
+ Class[] testedTypes = new Class[] { Integer.class, Boolean.class,
+ Double.class, String.class, Date.class };
+ Object[] testValues = new Object[] { new Integer(3), Boolean.FALSE,
+ new Double(3.3), "bar", new Date() };
+
+ int i = 0;
+ for (Class class1 : testedTypes) {
+ expectedClass = class1;
+
+ TestFormatter formatter = new TestFormatter();
+
+ // Should just return null, without formatting
+ Object value = formatter.getValue();
+
+ // test with property which value is null
+ formatter.setPropertyDataSource(new ObjectProperty(null,
+ expectedClass));
+ formatter.getValue(); // calls format
+
+ // test with a value
+ formatter.setPropertyDataSource(new ObjectProperty(testValues[i++],
+ expectedClass));
+ formatter.getValue(); // calls format
+ }
+
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/TestSerialization.java b/server/tests/src/com/vaadin/tests/server/TestSerialization.java
new file mode 100644
index 0000000000..84ff5ad6fa
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/TestSerialization.java
@@ -0,0 +1,126 @@
+package com.vaadin.tests.server;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.Item;
+import com.vaadin.data.Property;
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.data.util.MethodProperty;
+import com.vaadin.data.validator.RegexpValidator;
+import com.vaadin.ui.Form;
+
+public class TestSerialization extends TestCase {
+
+ public void testValidators() throws Exception {
+ RegexpValidator validator = new RegexpValidator(".*", "Error");
+ validator.validate("aaa");
+ RegexpValidator validator2 = (RegexpValidator) serializeAndDeserialize(validator);
+ validator2.validate("aaa");
+ }
+
+ public void testForm() throws Exception {
+ Form f = new Form();
+ String propertyId = "My property";
+ f.addItemProperty(propertyId, new MethodProperty<Object>(new Data(),
+ "dummyGetterAndSetter"));
+ f.replaceWithSelect(propertyId, new Object[] { "a", "b", null },
+ new String[] { "Item a", "ITem b", "Null item" });
+
+ serializeAndDeserialize(f);
+
+ }
+
+ public void testIndedexContainerItemIds() throws Exception {
+ IndexedContainer ic = new IndexedContainer();
+ ic.addContainerProperty("prop1", String.class, null);
+ Object id = ic.addItem();
+ ic.getItem(id).getItemProperty("prop1").setValue("1");
+
+ Item item2 = ic.addItem("item2");
+ item2.getItemProperty("prop1").setValue("2");
+
+ serializeAndDeserialize(ic);
+ }
+
+ public void testMethodPropertyGetter() throws Exception {
+ MethodProperty<?> mp = new MethodProperty<Object>(new Data(),
+ "dummyGetter");
+ serializeAndDeserialize(mp);
+ }
+
+ public void testMethodPropertyGetterAndSetter() throws Exception {
+ MethodProperty<?> mp = new MethodProperty<Object>(new Data(),
+ "dummyGetterAndSetter");
+ serializeAndDeserialize(mp);
+ }
+
+ public void testMethodPropertyInt() throws Exception {
+ MethodProperty<?> mp = new MethodProperty<Object>(new Data(),
+ "dummyInt");
+ serializeAndDeserialize(mp);
+ }
+
+ private static Serializable serializeAndDeserialize(Serializable s)
+ throws IOException, ClassNotFoundException {
+ // Serialize and deserialize
+
+ ByteArrayOutputStream bs = new ByteArrayOutputStream();
+ ObjectOutputStream out = new ObjectOutputStream(bs);
+ out.writeObject(s);
+ byte[] data = bs.toByteArray();
+ ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(
+ data));
+ Serializable s2 = (Serializable) in.readObject();
+
+ // using special toString(Object) method to avoid calling
+ // Property.toString(), which will be temporarily disabled
+ if (s.equals(s2)) {
+ System.out.println(toString(s) + " equals " + toString(s2));
+ } else {
+ System.out.println(toString(s) + " does NOT equal " + toString(s2));
+ }
+
+ return s2;
+ }
+
+ private static String toString(Object o) {
+ if (o instanceof Property) {
+ return String.valueOf(((Property<?>) o).getValue());
+ } else {
+ return String.valueOf(o);
+ }
+ }
+
+ public static class Data implements Serializable {
+ private String dummyGetter;
+ private String dummyGetterAndSetter;
+ private int dummyInt;
+
+ public String getDummyGetterAndSetter() {
+ return dummyGetterAndSetter;
+ }
+
+ public void setDummyGetterAndSetter(String dummyGetterAndSetter) {
+ this.dummyGetterAndSetter = dummyGetterAndSetter;
+ }
+
+ public int getDummyInt() {
+ return dummyInt;
+ }
+
+ public void setDummyInt(int dummyInt) {
+ this.dummyInt = dummyInt;
+ }
+
+ public String getDummyGetter() {
+ return dummyGetter;
+ }
+ }
+} \ No newline at end of file
diff --git a/server/tests/src/com/vaadin/tests/server/TestSimpleMultiPartInputStream.java b/server/tests/src/com/vaadin/tests/server/TestSimpleMultiPartInputStream.java
new file mode 100644
index 0000000000..84247c81c1
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/TestSimpleMultiPartInputStream.java
@@ -0,0 +1,138 @@
+package com.vaadin.tests.server;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Arrays;
+
+import junit.framework.TestCase;
+
+import com.vaadin.server.AbstractCommunicationManager.SimpleMultiPartInputStream;
+
+public class TestSimpleMultiPartInputStream extends TestCase {
+
+ /**
+ * Check that the output for a given stream until boundary is as expected.
+ *
+ * @param input
+ * @param boundary
+ * @param expected
+ * @throws Exception
+ */
+ protected void checkBoundaryDetection(byte[] input, String boundary,
+ byte[] expected) throws Exception {
+ ByteArrayInputStream bais = new ByteArrayInputStream(input);
+ SimpleMultiPartInputStream smpis = new SimpleMultiPartInputStream(bais,
+ boundary);
+ ByteArrayOutputStream resultStream = new ByteArrayOutputStream();
+ int outbyte;
+ try {
+ while ((outbyte = smpis.read()) != -1) {
+ resultStream.write(outbyte);
+ }
+ } catch (IOException e) {
+ throw new IOException(e.getMessage() + "; expected "
+ + new String(expected) + " but got "
+ + resultStream.toString());
+ }
+ if (!Arrays.equals(expected, resultStream.toByteArray())) {
+ throw new Exception("Mismatch: expected " + new String(expected)
+ + " but got " + resultStream.toString());
+ }
+ }
+
+ protected void checkBoundaryDetection(String input, String boundary,
+ String expected) throws Exception {
+ checkBoundaryDetection(input.getBytes(), boundary, expected.getBytes());
+ }
+
+ public void testSingleByteBoundaryAtEnd() throws Exception {
+ checkBoundaryDetection("xyz123" + getFullBoundary("a"), "a", "xyz123");
+ }
+
+ public void testSingleByteBoundaryInMiddle() throws Exception {
+ checkBoundaryDetection("xyz" + getFullBoundary("a") + "123", "a", "xyz");
+ }
+
+ public void testCorrectBoundaryAtEnd() throws Exception {
+ checkBoundaryDetection("xyz123" + getFullBoundary("abc"), "abc",
+ "xyz123");
+ }
+
+ public void testCorrectBoundaryNearEnd() throws Exception {
+ checkBoundaryDetection("xyz123" + getFullBoundary("abc") + "de", "abc",
+ "xyz123");
+ }
+
+ public void testCorrectBoundaryAtBeginning() throws Exception {
+ checkBoundaryDetection(getFullBoundary("abc") + "xyz123", "abc", "");
+ }
+
+ public void testRepeatingCharacterBoundary() throws Exception {
+ checkBoundaryDetection(getFullBoundary("aa") + "xyz123", "aa", "");
+ checkBoundaryDetection("axyz" + getFullBoundary("aa") + "123", "aa",
+ "axyz");
+ checkBoundaryDetection("xyz123" + getFullBoundary("aa"), "aa", "xyz123");
+ }
+
+ /**
+ * Note, the boundary in this test is invalid. Boundary strings don't
+ * contain CR/LF.
+ *
+ */
+ // public void testRepeatingNewlineBoundary() throws Exception {
+ // checkBoundaryDetection("1234567890" + getFullBoundary("\n\n")
+ // + "1234567890", "\n\n", "");
+ // }
+
+ public void testRepeatingStringBoundary() throws Exception {
+ checkBoundaryDetection(getFullBoundary("abab") + "xyz123", "abab", "");
+ checkBoundaryDetection("abaxyz" + getFullBoundary("abab") + "123",
+ "abab", "abaxyz");
+ checkBoundaryDetection("xyz123" + getFullBoundary("abab"), "abab",
+ "xyz123");
+ }
+
+ public void testOverlappingBoundary() throws Exception {
+ checkBoundaryDetection("abc" + getFullBoundary("abcabd") + "xyz123",
+ "abcabd", "abc");
+ checkBoundaryDetection("xyzabc" + getFullBoundary("abcabd") + "123",
+ "abcabd", "xyzabc");
+ checkBoundaryDetection("xyz123abc" + getFullBoundary("abcabd"),
+ "abcabd", "xyz123abc");
+ }
+
+ /*
+ * TODO fix these tests, they don't do what their method name says.
+ */
+
+ // public void testNoBoundaryInInput() throws Exception {
+ // try {
+ // checkBoundaryDetection("xyz123", "abc", "xyz123");
+ // fail();
+ // } catch (IOException e) {
+ // }
+ // }
+ //
+ // public void testPartialBoundaryAtInputEnd() throws Exception {
+ // try {
+ // // This should lead to IOException (stream end), not AIOOBE
+ // checkBoundaryDetection("xyz123ab", "abc", "xyz123ab");
+ // fail();
+ // } catch (IOException e) {
+ // }
+ // }
+ //
+ // public void testPartialBoundaryAtInputBeginning() throws Exception {
+ // try {
+ // checkBoundaryDetection("abxyz123", "abc", "abxyz123");
+ // fail();
+ // } catch (IOException e) {
+ // }
+ // }
+
+ public static String getFullBoundary(String str) {
+ return "\r\n--" + str + "--";
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/server/TestStreamVariableMapping.java b/server/tests/src/com/vaadin/tests/server/TestStreamVariableMapping.java
new file mode 100644
index 0000000000..f3b367483a
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/TestStreamVariableMapping.java
@@ -0,0 +1,77 @@
+package com.vaadin.tests.server;
+
+import junit.framework.TestCase;
+
+import org.easymock.EasyMock;
+
+import com.vaadin.Application;
+import com.vaadin.server.CommunicationManager;
+import com.vaadin.server.StreamVariable;
+import com.vaadin.server.WrappedRequest;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.Upload;
+
+public class TestStreamVariableMapping extends TestCase {
+ private static final String variableName = "myName";
+
+ private Upload owner;
+ private StreamVariable streamVariable;
+
+ private CommunicationManager cm;
+
+ @Override
+ protected void setUp() throws Exception {
+ final Application application = new Application();
+ final UI uI = new UI() {
+ @Override
+ protected void init(WrappedRequest request) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public Application getApplication() {
+ return application;
+ }
+ };
+ owner = new Upload() {
+ @Override
+ public UI getUI() {
+ return uI;
+ }
+ };
+ streamVariable = EasyMock.createMock(StreamVariable.class);
+ cm = createCommunicationManager();
+
+ super.setUp();
+ }
+
+ public void testAddStreamVariable() {
+ String targetUrl = cm.getStreamVariableTargetUrl(owner, variableName,
+ streamVariable);
+ assertTrue(targetUrl.startsWith("app://APP/UPLOAD/-1/1/myName/"));
+
+ StreamVariable streamVariable2 = cm.getStreamVariable(
+ owner.getConnectorId(), variableName);
+ assertSame(streamVariable, streamVariable2);
+ }
+
+ public void testRemoverVariable() {
+ cm.getStreamVariableTargetUrl(owner, variableName, streamVariable);
+ assertNotNull(cm
+ .getStreamVariable(owner.getConnectorId(), variableName));
+
+ cm.cleanStreamVariable(owner, variableName);
+ assertNull(cm.getStreamVariable(owner.getConnectorId(), variableName));
+ }
+
+ private CommunicationManager createCommunicationManager() {
+ return new CommunicationManager(new Application() {
+ @Override
+ public void init() {
+ // TODO Auto-generated method stub
+ }
+ });
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/server/TestThemeNames.java b/server/tests/src/com/vaadin/tests/server/TestThemeNames.java
new file mode 100644
index 0000000000..22fe315730
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/TestThemeNames.java
@@ -0,0 +1,38 @@
+package com.vaadin.tests.server;
+
+import java.io.File;
+import java.lang.reflect.Field;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import com.vaadin.tests.VaadinClasses;
+import com.vaadin.ui.themes.BaseTheme;
+
+public class TestThemeNames extends TestCase {
+ public void testThemeNames() {
+ File baseDir = new File(SourceFileChecker.getBaseDir()
+ + "WebContent/VAADIN/themes/");
+
+ List<Class<? extends BaseTheme>> themeClasses = VaadinClasses
+ .getThemeClasses();
+ for (Class<? extends BaseTheme> themeClass : themeClasses) {
+ try {
+ Field field = themeClass.getField("THEME_NAME");
+ String themeName = (String) field.get(null);
+
+ File themeDir = new File(baseDir, themeName);
+ File styleFile = new File(themeDir, "styles.css");
+
+ assertTrue("Can't find " + styleFile + " for theme "
+ + themeClass.getName(), styleFile.exists());
+
+ // Test that casing matches
+ assertEquals(themeDir.getCanonicalFile().getName(), themeName);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/server/TransactionListenersConcurrency.java b/server/tests/src/com/vaadin/tests/server/TransactionListenersConcurrency.java
new file mode 100644
index 0000000000..0cacccd08a
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/TransactionListenersConcurrency.java
@@ -0,0 +1,201 @@
+package com.vaadin.tests.server;
+
+import static org.easymock.EasyMock.createMock;
+
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import java.util.Random;
+
+import javax.servlet.http.HttpSession;
+
+import junit.framework.TestCase;
+
+import com.vaadin.Application;
+import com.vaadin.Application.ApplicationStartEvent;
+import com.vaadin.server.AbstractWebApplicationContext;
+import com.vaadin.server.DeploymentConfiguration;
+import com.vaadin.server.WebApplicationContext;
+import com.vaadin.service.ApplicationContext.TransactionListener;
+
+import org.easymock.EasyMock;
+
+public class TransactionListenersConcurrency extends TestCase {
+
+ /**
+ * This test starts N threads concurrently. Each thread creates an
+ * application which adds a transaction listener to the context. A
+ * transaction is then started for each application. Some semi-random delays
+ * are included so that calls to addTransactionListener and
+ * WebApplicationContext.startTransaction are mixed.
+ *
+ */
+ public void testTransactionListeners() throws Exception {
+ final List<Throwable> exceptions = new ArrayList<Throwable>();
+
+ HttpSession session = createSession();
+ final WebApplicationContext context = WebApplicationContext
+ .getApplicationContext(session);
+ List<Thread> threads = new ArrayList<Thread>();
+
+ for (int i = 0; i < 5; i++) {
+ Thread t = new Thread(new Runnable() {
+
+ @Override
+ public void run() {
+ Application app = new Application() {
+
+ @Override
+ public void init() {
+ // Sleep 0-1000ms so another transaction has time to
+ // start before we add the transaction listener.
+ try {
+ Thread.sleep((long) (1000 * new Random()
+ .nextDouble()));
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ getContext().addTransactionListener(
+ new DelayTransactionListener(2000));
+ }
+
+ };
+
+ // Start the application so the transaction listener is
+ // called later on.
+ try {
+ DeploymentConfiguration dc = EasyMock
+ .createMock(DeploymentConfiguration.class);
+ EasyMock.expect(dc.isProductionMode()).andReturn(true);
+ EasyMock.expect(dc.getInitParameters()).andReturn(
+ new Properties());
+ EasyMock.replay(dc);
+
+ app.start(new ApplicationStartEvent(new URL(
+ "http://localhost/"), dc, context));
+ } catch (MalformedURLException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ try {
+ // Call the transaction listener using reflection as
+ // startTransaction is protected.
+
+ Method m = AbstractWebApplicationContext.class
+ .getDeclaredMethod("startTransaction",
+ Application.class, Object.class);
+ m.setAccessible(true);
+ m.invoke(context, app, null);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ });
+
+ threads.add(t);
+ t.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
+
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ if (e.getCause() != null) {
+ e = e.getCause();
+ }
+ exceptions.add(e);
+ }
+ });
+ }
+
+ // Start the threads and wait for all of them to finish
+ for (Thread t : threads) {
+ t.start();
+ }
+ int running = threads.size();
+
+ while (running > 0) {
+ for (Iterator<Thread> i = threads.iterator(); i.hasNext();) {
+ Thread t = i.next();
+ if (!t.isAlive()) {
+ running--;
+ i.remove();
+ }
+ }
+ }
+
+ for (Throwable t : exceptions) {
+ if (t instanceof InvocationTargetException) {
+ t = t.getCause();
+ }
+ if (t != null) {
+ t.printStackTrace(System.err);
+ fail(t.getClass().getName());
+ }
+ }
+
+ System.out.println("Done, all ok");
+
+ }
+
+ /**
+ * Creates a HttpSession mock
+ *
+ */
+ private static HttpSession createSession() {
+ HttpSession session = createMock(HttpSession.class);
+ EasyMock.expect(
+ session.getAttribute(WebApplicationContext.class.getName()))
+ .andReturn(null).anyTimes();
+ session.setAttribute(
+ EasyMock.eq(WebApplicationContext.class.getName()),
+ EasyMock.anyObject());
+
+ EasyMock.replay(session);
+ return session;
+ }
+
+ /**
+ * A transaction listener that just sleeps for the given amount of time in
+ * transactionStart and transactionEnd.
+ *
+ */
+ public static class DelayTransactionListener implements TransactionListener {
+
+ private int delay;
+
+ public DelayTransactionListener(int delay) {
+ this.delay = delay;
+ }
+
+ @Override
+ public void transactionStart(Application application,
+ Object transactionData) {
+ try {
+ Thread.sleep(delay);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ @Override
+ public void transactionEnd(Application application,
+ Object transactionData) {
+ try {
+ Thread.sleep(delay);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ }
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/AbstractListenerMethodsTest.java b/server/tests/src/com/vaadin/tests/server/component/AbstractListenerMethodsTest.java
new file mode 100644
index 0000000000..e189ffc77d
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/AbstractListenerMethodsTest.java
@@ -0,0 +1,173 @@
+package com.vaadin.tests.server.component;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import org.easymock.EasyMock;
+import org.junit.Assert;
+
+import com.vaadin.tests.VaadinClasses;
+import com.vaadin.ui.Component;
+
+public abstract class AbstractListenerMethodsTest extends TestCase {
+
+ public static void main(String[] args) {
+ findAllListenerMethods();
+ }
+
+ private static void findAllListenerMethods() {
+ Set<Class<?>> classes = new HashSet<Class<?>>();
+ for (Class<?> c : VaadinClasses.getAllServerSideClasses()) {
+ while (c != null && c.getName().startsWith("com.vaadin.")) {
+ classes.add(c);
+ c = c.getSuperclass();
+ }
+ }
+
+ for (Class<?> c : classes) {
+ boolean found = false;
+ for (Method m : c.getDeclaredMethods()) {
+ if (m.getName().equals("addListener")) {
+ if (m.getParameterTypes().length != 1) {
+ continue;
+ }
+ String packageName = "com.vaadin.tests.server";
+ if (Component.class.isAssignableFrom(c)) {
+ packageName += ".component."
+ + c.getSimpleName().toLowerCase();
+ continue;
+ }
+
+ if (!found) {
+ found = true;
+ System.out.println("package " + packageName + ";");
+
+ System.out.println("import "
+ + AbstractListenerMethodsTest.class.getName()
+ + ";");
+ System.out.println("import " + c.getName() + ";");
+ System.out.println("public class "
+ + c.getSimpleName()
+ + "Listeners extends "
+ + AbstractListenerMethodsTest.class
+ .getSimpleName() + " {");
+ }
+
+ String listenerClassName = m.getParameterTypes()[0]
+ .getSimpleName();
+ String eventClassName = listenerClassName.replaceFirst(
+ "Listener$", "Event");
+ System.out.println("public void test" + listenerClassName
+ + "() throws Exception {");
+ System.out.println(" testListener(" + c.getSimpleName()
+ + ".class, " + eventClassName + ".class, "
+ + listenerClassName + ".class);");
+ System.out.println("}");
+ }
+ }
+ if (found) {
+ System.out.println("}");
+ System.out.println();
+ }
+ }
+ }
+
+ protected void testListenerAddGetRemove(Class<?> testClass,
+ Class<?> eventClass, Class<?> listenerClass) throws Exception {
+ // Create a component for testing
+ Object c = testClass.newInstance();
+ testListenerAddGetRemove(testClass, eventClass, listenerClass, c);
+
+ }
+
+ protected void testListenerAddGetRemove(Class<?> cls, Class<?> eventClass,
+ Class<?> listenerClass, Object c) throws Exception {
+
+ Object mockListener1 = EasyMock.createMock(listenerClass);
+ Object mockListener2 = EasyMock.createMock(listenerClass);
+
+ // Verify we start from no listeners
+ verifyListeners(c, eventClass);
+
+ // Add one listener and verify
+ addListener(c, mockListener1, listenerClass);
+ verifyListeners(c, eventClass, mockListener1);
+
+ // Add another listener and verify
+ addListener(c, mockListener2, listenerClass);
+ verifyListeners(c, eventClass, mockListener1, mockListener2);
+
+ // Ensure we can fetch using parent class also
+ if (eventClass.getSuperclass() != null) {
+ verifyListeners(c, eventClass.getSuperclass(), mockListener1,
+ mockListener2);
+ }
+
+ // Remove the first and verify
+ removeListener(c, mockListener1, listenerClass);
+ verifyListeners(c, eventClass, mockListener2);
+
+ // Remove the remaining and verify
+ removeListener(c, mockListener2, listenerClass);
+ verifyListeners(c, eventClass);
+
+ }
+
+ private void removeListener(Object c, Object listener,
+ Class<?> listenerClass) throws IllegalArgumentException,
+ IllegalAccessException, InvocationTargetException,
+ SecurityException, NoSuchMethodException {
+ Method method = getRemoveListenerMethod(c.getClass(), listenerClass);
+ method.invoke(c, listener);
+
+ }
+
+ private void addListener(Object c, Object listener1, Class<?> listenerClass)
+ throws IllegalArgumentException, IllegalAccessException,
+ InvocationTargetException, SecurityException, NoSuchMethodException {
+ Method method = getAddListenerMethod(c.getClass(), listenerClass);
+ method.invoke(c, listener1);
+ }
+
+ private Collection<?> getListeners(Object c, Class<?> eventType)
+ throws IllegalArgumentException, IllegalAccessException,
+ InvocationTargetException, SecurityException, NoSuchMethodException {
+ Method method = getGetListenersMethod(c.getClass());
+ return (Collection<?>) method.invoke(c, eventType);
+ }
+
+ private Method getGetListenersMethod(Class<? extends Object> cls)
+ throws SecurityException, NoSuchMethodException {
+ return cls.getMethod("getListeners", Class.class);
+ }
+
+ private Method getAddListenerMethod(Class<?> cls, Class<?> listenerClass)
+ throws SecurityException, NoSuchMethodException {
+ return cls.getMethod("addListener", listenerClass);
+
+ }
+
+ private Method getRemoveListenerMethod(Class<?> cls, Class<?> listenerClass)
+ throws SecurityException, NoSuchMethodException {
+ return cls.getMethod("removeListener", listenerClass);
+
+ }
+
+ private void verifyListeners(Object c, Class<?> eventClass,
+ Object... expectedListeners) throws IllegalArgumentException,
+ SecurityException, IllegalAccessException,
+ InvocationTargetException, NoSuchMethodException {
+ Collection<?> registeredListeners = getListeners(c, eventClass);
+ assertEquals("Number of listeners", expectedListeners.length,
+ registeredListeners.size());
+
+ Assert.assertArrayEquals(expectedListeners,
+ registeredListeners.toArray());
+
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/FinalMethodTest.java b/server/tests/src/com/vaadin/tests/server/component/FinalMethodTest.java
new file mode 100644
index 0000000000..ad80007882
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/FinalMethodTest.java
@@ -0,0 +1,68 @@
+package com.vaadin.tests.server.component;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.HashSet;
+
+import junit.framework.TestCase;
+
+import com.vaadin.tests.VaadinClasses;
+import com.vaadin.ui.Component;
+
+public class FinalMethodTest extends TestCase {
+
+ // public void testThatContainersHaveNoFinalMethods() {
+ // HashSet<Class<?>> tested = new HashSet<Class<?>>();
+ // for (Class<?> c : VaadinClasses.getAllServerSideClasses()) {
+ // if (Container.class.isAssignableFrom(c)) {
+ // ensureNoFinalMethods(c, tested);
+ // }
+ // }
+ // }
+
+ public void testThatComponentsHaveNoFinalMethods() {
+ HashSet<Class<?>> tested = new HashSet<Class<?>>();
+ for (Class<? extends Component> c : VaadinClasses.getComponents()) {
+ ensureNoFinalMethods(c, tested);
+ }
+ }
+
+ private void ensureNoFinalMethods(Class<?> c, HashSet<Class<?>> tested) {
+ if (tested.contains(c)) {
+ return;
+ }
+
+ tested.add(c);
+
+ if (c == Object.class) {
+ return;
+ }
+ System.out.println("Checking " + c.getName());
+ for (Method m : c.getDeclaredMethods()) {
+ if (isPrivate(m)) {
+ continue;
+ }
+ if (isFinal(m)) {
+ String error = "Class " + c.getName() + " contains a "
+ + (isPublic(m) ? "public" : "non-public")
+ + " final method: " + m.getName();
+ // System.err.println(error);
+ throw new RuntimeException(error);
+ }
+ }
+ ensureNoFinalMethods(c.getSuperclass(), tested);
+
+ }
+
+ private boolean isFinal(Method m) {
+ return Modifier.isFinal(m.getModifiers());
+ }
+
+ private boolean isPrivate(Method m) {
+ return Modifier.isPrivate(m.getModifiers());
+ }
+
+ private boolean isPublic(Method m) {
+ return Modifier.isPublic(m.getModifiers());
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/absolutelayout/AbsoluteLayoutListeners.java b/server/tests/src/com/vaadin/tests/server/component/absolutelayout/AbsoluteLayoutListeners.java
new file mode 100644
index 0000000000..7d6db42d1a
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/absolutelayout/AbsoluteLayoutListeners.java
@@ -0,0 +1,13 @@
+package com.vaadin.tests.server.component.absolutelayout;
+
+import com.vaadin.event.LayoutEvents.LayoutClickEvent;
+import com.vaadin.event.LayoutEvents.LayoutClickListener;
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+import com.vaadin.ui.AbsoluteLayout;
+
+public class AbsoluteLayoutListeners extends AbstractListenerMethodsTest {
+ public void testLayoutClickListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(AbsoluteLayout.class, LayoutClickEvent.class,
+ LayoutClickListener.class);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/absolutelayout/ComponentPosition.java b/server/tests/src/com/vaadin/tests/server/component/absolutelayout/ComponentPosition.java
new file mode 100644
index 0000000000..d76dcffa2f
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/absolutelayout/ComponentPosition.java
@@ -0,0 +1,204 @@
+package com.vaadin.tests.server.component.absolutelayout;
+
+import junit.framework.TestCase;
+
+import com.vaadin.server.Sizeable;
+import com.vaadin.server.Sizeable.Unit;
+import com.vaadin.ui.AbsoluteLayout;
+import com.vaadin.ui.Button;
+
+public class ComponentPosition extends TestCase {
+
+ private static final String CSS = "top:7.0px;right:7.0%;bottom:7.0pc;left:7.0em;z-index:7;";
+ private static final String PARTIAL_CSS = "top:7.0px;left:7.0em;";
+ private static final Float CSS_VALUE = Float.valueOf(7);
+
+ private static final Unit UNIT_UNSET = Sizeable.Unit.PIXELS;
+
+ /**
+ * Add component w/o giving positions, assert that everything is unset
+ */
+ public void testNoPosition() {
+ AbsoluteLayout layout = new AbsoluteLayout();
+ Button b = new Button();
+ layout.addComponent(b);
+
+ assertNull(layout.getPosition(b).getTopValue());
+ assertNull(layout.getPosition(b).getBottomValue());
+ assertNull(layout.getPosition(b).getLeftValue());
+ assertNull(layout.getPosition(b).getRightValue());
+
+ assertEquals(UNIT_UNSET, layout.getPosition(b).getTopUnits());
+ assertEquals(UNIT_UNSET, layout.getPosition(b).getBottomUnits());
+ assertEquals(UNIT_UNSET, layout.getPosition(b).getLeftUnits());
+ assertEquals(UNIT_UNSET, layout.getPosition(b).getRightUnits());
+
+ assertEquals(-1, layout.getPosition(b).getZIndex());
+
+ assertEquals("", layout.getPosition(b).getCSSString());
+
+ }
+
+ /**
+ * Add component, setting all attributes using CSS, assert getter agree
+ */
+ public void testFullCss() {
+ AbsoluteLayout layout = new AbsoluteLayout();
+ Button b = new Button();
+ layout.addComponent(b, CSS);
+
+ assertEquals(CSS_VALUE, layout.getPosition(b).getTopValue());
+ assertEquals(CSS_VALUE, layout.getPosition(b).getBottomValue());
+ assertEquals(CSS_VALUE, layout.getPosition(b).getLeftValue());
+ assertEquals(CSS_VALUE, layout.getPosition(b).getRightValue());
+
+ assertEquals(Sizeable.Unit.PIXELS, layout.getPosition(b).getTopUnits());
+ assertEquals(Sizeable.Unit.PICAS, layout.getPosition(b)
+ .getBottomUnits());
+ assertEquals(Sizeable.Unit.EM, layout.getPosition(b).getLeftUnits());
+ assertEquals(Sizeable.Unit.PERCENTAGE, layout.getPosition(b)
+ .getRightUnits());
+
+ assertEquals(7, layout.getPosition(b).getZIndex());
+
+ assertEquals(CSS, layout.getPosition(b).getCSSString());
+
+ }
+
+ /**
+ * Add component, setting some attributes using CSS, assert getters agree
+ */
+ public void testPartialCss() {
+ AbsoluteLayout layout = new AbsoluteLayout();
+ Button b = new Button();
+ layout.addComponent(b, PARTIAL_CSS);
+
+ assertEquals(CSS_VALUE, layout.getPosition(b).getTopValue());
+ assertNull(layout.getPosition(b).getBottomValue());
+ assertEquals(CSS_VALUE, layout.getPosition(b).getLeftValue());
+ assertNull(layout.getPosition(b).getRightValue());
+
+ assertEquals(Sizeable.Unit.PIXELS, layout.getPosition(b).getTopUnits());
+ assertEquals(UNIT_UNSET, layout.getPosition(b).getBottomUnits());
+ assertEquals(Sizeable.Unit.EM, layout.getPosition(b).getLeftUnits());
+ assertEquals(UNIT_UNSET, layout.getPosition(b).getRightUnits());
+
+ assertEquals(-1, layout.getPosition(b).getZIndex());
+
+ assertEquals(PARTIAL_CSS, layout.getPosition(b).getCSSString());
+
+ }
+
+ /**
+ * Add component setting all attributes using CSS, then reset using partial
+ * CSS; assert getters agree and the appropriate attributes are unset.
+ */
+ public void testPartialCssReset() {
+ AbsoluteLayout layout = new AbsoluteLayout();
+ Button b = new Button();
+ layout.addComponent(b, CSS);
+
+ layout.getPosition(b).setCSSString(PARTIAL_CSS);
+
+ assertEquals(CSS_VALUE, layout.getPosition(b).getTopValue());
+ assertNull(layout.getPosition(b).getBottomValue());
+ assertEquals(CSS_VALUE, layout.getPosition(b).getLeftValue());
+ assertNull(layout.getPosition(b).getRightValue());
+
+ assertEquals(Sizeable.Unit.PIXELS, layout.getPosition(b).getTopUnits());
+ assertEquals(UNIT_UNSET, layout.getPosition(b).getBottomUnits());
+ assertEquals(Sizeable.Unit.EM, layout.getPosition(b).getLeftUnits());
+ assertEquals(UNIT_UNSET, layout.getPosition(b).getRightUnits());
+
+ assertEquals(-1, layout.getPosition(b).getZIndex());
+
+ assertEquals(PARTIAL_CSS, layout.getPosition(b).getCSSString());
+
+ }
+
+ /**
+ * Add component, then set all position attributes with individual setters
+ * for value and units; assert getters agree.
+ */
+ public void testSetPosition() {
+ final Float SIZE = Float.valueOf(12);
+
+ AbsoluteLayout layout = new AbsoluteLayout();
+ Button b = new Button();
+ layout.addComponent(b);
+
+ layout.getPosition(b).setTopValue(SIZE);
+ layout.getPosition(b).setRightValue(SIZE);
+ layout.getPosition(b).setBottomValue(SIZE);
+ layout.getPosition(b).setLeftValue(SIZE);
+
+ layout.getPosition(b).setTopUnits(Sizeable.Unit.CM);
+ layout.getPosition(b).setRightUnits(Sizeable.Unit.EX);
+ layout.getPosition(b).setBottomUnits(Sizeable.Unit.INCH);
+ layout.getPosition(b).setLeftUnits(Sizeable.Unit.MM);
+
+ assertEquals(SIZE, layout.getPosition(b).getTopValue());
+ assertEquals(SIZE, layout.getPosition(b).getRightValue());
+ assertEquals(SIZE, layout.getPosition(b).getBottomValue());
+ assertEquals(SIZE, layout.getPosition(b).getLeftValue());
+
+ assertEquals(Sizeable.Unit.CM, layout.getPosition(b).getTopUnits());
+ assertEquals(Sizeable.Unit.EX, layout.getPosition(b).getRightUnits());
+ assertEquals(Sizeable.Unit.INCH, layout.getPosition(b).getBottomUnits());
+ assertEquals(Sizeable.Unit.MM, layout.getPosition(b).getLeftUnits());
+
+ }
+
+ /**
+ * Add component, then set all position attributes with combined setters for
+ * value and units; assert getters agree.
+ */
+ public void testSetPosition2() {
+ final Float SIZE = Float.valueOf(12);
+ AbsoluteLayout layout = new AbsoluteLayout();
+ Button b = new Button();
+ layout.addComponent(b);
+
+ layout.getPosition(b).setTop(SIZE, Sizeable.Unit.CM);
+ layout.getPosition(b).setRight(SIZE, Sizeable.Unit.EX);
+ layout.getPosition(b).setBottom(SIZE, Sizeable.Unit.INCH);
+ layout.getPosition(b).setLeft(SIZE, Sizeable.Unit.MM);
+
+ assertEquals(SIZE, layout.getPosition(b).getTopValue());
+ assertEquals(SIZE, layout.getPosition(b).getRightValue());
+ assertEquals(SIZE, layout.getPosition(b).getBottomValue());
+ assertEquals(SIZE, layout.getPosition(b).getLeftValue());
+
+ assertEquals(Sizeable.Unit.CM, layout.getPosition(b).getTopUnits());
+ assertEquals(Sizeable.Unit.EX, layout.getPosition(b).getRightUnits());
+ assertEquals(Sizeable.Unit.INCH, layout.getPosition(b).getBottomUnits());
+ assertEquals(Sizeable.Unit.MM, layout.getPosition(b).getLeftUnits());
+
+ }
+
+ /**
+ * Add component, set all attributes using CSS, unset some using method
+ * calls, assert getters agree.
+ */
+ public void testUnsetPosition() {
+ AbsoluteLayout layout = new AbsoluteLayout();
+ Button b = new Button();
+ layout.addComponent(b, CSS);
+
+ layout.getPosition(b).setTopValue(null);
+ layout.getPosition(b).setRightValue(null);
+ layout.getPosition(b).setBottomValue(null);
+ layout.getPosition(b).setLeftValue(null);
+
+ layout.getPosition(b).setZIndex(-1);
+
+ assertNull(layout.getPosition(b).getTopValue());
+ assertNull(layout.getPosition(b).getBottomValue());
+ assertNull(layout.getPosition(b).getLeftValue());
+ assertNull(layout.getPosition(b).getRightValue());
+
+ assertEquals("", layout.getPosition(b).getCSSString());
+
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractcomponent/TestAbstractComponentStyleNames.java b/server/tests/src/com/vaadin/tests/server/component/abstractcomponent/TestAbstractComponentStyleNames.java
new file mode 100644
index 0000000000..1903e66f92
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/abstractcomponent/TestAbstractComponentStyleNames.java
@@ -0,0 +1,61 @@
+package com.vaadin.tests.server.component.abstractcomponent;
+
+import junit.framework.TestCase;
+
+import com.vaadin.ui.AbstractComponent;
+
+public class TestAbstractComponentStyleNames extends TestCase {
+
+ public void testSetMultiple() {
+ AbstractComponent component = getComponent();
+ component.setStyleName("style1 style2");
+ assertEquals(component.getStyleName(), "style1 style2");
+ }
+
+ public void testSetAdd() {
+ AbstractComponent component = getComponent();
+ component.setStyleName("style1");
+ component.addStyleName("style2");
+ assertEquals(component.getStyleName(), "style1 style2");
+ }
+
+ public void testAddSame() {
+ AbstractComponent component = getComponent();
+ component.setStyleName("style1 style2");
+ component.addStyleName("style1");
+ assertEquals(component.getStyleName(), "style1 style2");
+ }
+
+ public void testSetRemove() {
+ AbstractComponent component = getComponent();
+ component.setStyleName("style1 style2");
+ component.removeStyleName("style1");
+ assertEquals(component.getStyleName(), "style2");
+ }
+
+ public void testAddRemove() {
+ AbstractComponent component = getComponent();
+ component.addStyleName("style1");
+ component.addStyleName("style2");
+ component.removeStyleName("style1");
+ assertEquals(component.getStyleName(), "style2");
+ }
+
+ public void testRemoveMultipleWithExtraSpaces() {
+ AbstractComponent component = getComponent();
+ component.setStyleName("style1 style2 style3");
+ component.removeStyleName(" style1 style3 ");
+ assertEquals(component.getStyleName(), "style2");
+ }
+
+ public void testSetWithExtraSpaces() {
+ AbstractComponent component = getComponent();
+ component.setStyleName(" style1 style2 ");
+ assertEquals(component.getStyleName(), "style1 style2");
+ }
+
+ private AbstractComponent getComponent() {
+ return new AbstractComponent() {
+ };
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractcomponentcontainer/TestAbstractComponentContainerListeners.java b/server/tests/src/com/vaadin/tests/server/component/abstractcomponentcontainer/TestAbstractComponentContainerListeners.java
new file mode 100644
index 0000000000..f9f170eb2a
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/abstractcomponentcontainer/TestAbstractComponentContainerListeners.java
@@ -0,0 +1,22 @@
+package com.vaadin.tests.server.component.abstractcomponentcontainer;
+
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+import com.vaadin.ui.ComponentContainer.ComponentAttachEvent;
+import com.vaadin.ui.ComponentContainer.ComponentAttachListener;
+import com.vaadin.ui.ComponentContainer.ComponentDetachEvent;
+import com.vaadin.ui.ComponentContainer.ComponentDetachListener;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.VerticalLayout;
+
+public class TestAbstractComponentContainerListeners extends
+ AbstractListenerMethodsTest {
+ public void testComponentDetachListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(HorizontalLayout.class,
+ ComponentDetachEvent.class, ComponentDetachListener.class);
+ }
+
+ public void testComponentAttachListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(VerticalLayout.class,
+ ComponentAttachEvent.class, ComponentAttachListener.class);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbstractFieldValueConversions.java b/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbstractFieldValueConversions.java
new file mode 100644
index 0000000000..57af748247
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbstractFieldValueConversions.java
@@ -0,0 +1,216 @@
+package com.vaadin.tests.server.component.abstractfield;
+
+import java.util.Locale;
+
+import junit.framework.TestCase;
+
+import com.vaadin.Application;
+import com.vaadin.data.util.MethodProperty;
+import com.vaadin.data.util.converter.Converter;
+import com.vaadin.data.util.converter.StringToIntegerConverter;
+import com.vaadin.tests.data.bean.Address;
+import com.vaadin.tests.data.bean.Country;
+import com.vaadin.tests.data.bean.Person;
+import com.vaadin.tests.data.bean.Sex;
+import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.TextField;
+
+public class AbstractFieldValueConversions extends TestCase {
+
+ Person paulaBean = new Person("Paula", "Brilliant", "paula@brilliant.com",
+ 34, Sex.FEMALE, new Address("Paula street 1", 12345, "P-town",
+ Country.FINLAND));
+
+ public void testWithoutConversion() {
+ TextField tf = new TextField();
+ tf.setPropertyDataSource(new MethodProperty<String>(paulaBean,
+ "firstName"));
+ assertEquals("Paula", tf.getValue());
+ assertEquals("Paula", tf.getPropertyDataSource().getValue());
+ tf.setValue("abc");
+ assertEquals("abc", tf.getValue());
+ assertEquals("abc", tf.getPropertyDataSource().getValue());
+ assertEquals("abc", paulaBean.getFirstName());
+ }
+
+ public void testStringIdentityConversion() {
+ TextField tf = new TextField();
+ tf.setConverter(new Converter<String, String>() {
+
+ @Override
+ public String convertToModel(String value, Locale locale) {
+ return value;
+ }
+
+ @Override
+ public String convertToPresentation(String value, Locale locale) {
+ return value;
+ }
+
+ @Override
+ public Class<String> getModelType() {
+ return String.class;
+ }
+
+ @Override
+ public Class<String> getPresentationType() {
+ return String.class;
+ }
+ });
+ tf.setPropertyDataSource(new MethodProperty<String>(paulaBean,
+ "firstName"));
+ assertEquals("Paula", tf.getValue());
+ assertEquals("Paula", tf.getPropertyDataSource().getValue());
+ tf.setValue("abc");
+ assertEquals("abc", tf.getValue());
+ assertEquals("abc", tf.getPropertyDataSource().getValue());
+ assertEquals("abc", paulaBean.getFirstName());
+ }
+
+ public void testFailingConversion() {
+ TextField tf = new TextField();
+ tf.setConverter(new Converter<String, Integer>() {
+
+ @Override
+ public Integer convertToModel(String value, Locale locale) {
+ throw new ConversionException("Failed");
+ }
+
+ @Override
+ public String convertToPresentation(Integer value, Locale locale) {
+ throw new ConversionException("Failed");
+ }
+
+ @Override
+ public Class<Integer> getModelType() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Class<String> getPresentationType() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ });
+ try {
+ tf.setValue(1);
+ fail("setValue(Integer) should throw an exception");
+ } catch (Converter.ConversionException e) {
+ // OK, expected
+ }
+ }
+
+ public void testIntegerStringConversion() {
+ TextField tf = new TextField();
+
+ tf.setConverter(new StringToIntegerConverter());
+ tf.setPropertyDataSource(new MethodProperty<Integer>(paulaBean, "age"));
+ assertEquals(34, tf.getPropertyDataSource().getValue());
+ assertEquals("34", tf.getValue());
+ tf.setValue("12");
+ assertEquals(12, tf.getPropertyDataSource().getValue());
+ assertEquals("12", tf.getValue());
+ tf.getPropertyDataSource().setValue(42);
+ assertEquals(42, tf.getPropertyDataSource().getValue());
+ assertEquals("42", tf.getValue());
+ }
+
+ public void testBooleanNullConversion() {
+ CheckBox cb = new CheckBox();
+ cb.setConverter(new Converter<Boolean, Boolean>() {
+
+ @Override
+ public Boolean convertToModel(Boolean value, Locale locale) {
+ // value from a CheckBox should never be null as long as it is
+ // not set to null (handled by conversion below).
+ assertNotNull(value);
+ return value;
+ }
+
+ @Override
+ public Boolean convertToPresentation(Boolean value, Locale locale) {
+ // Datamodel -> field
+ if (value == null) {
+ return false;
+ }
+
+ return value;
+ }
+
+ @Override
+ public Class<Boolean> getModelType() {
+ return Boolean.class;
+ }
+
+ @Override
+ public Class<Boolean> getPresentationType() {
+ return Boolean.class;
+ }
+
+ });
+ MethodProperty<Boolean> property = new MethodProperty<Boolean>(
+ paulaBean, "deceased");
+ cb.setPropertyDataSource(property);
+ assertEquals(Boolean.FALSE, property.getValue());
+ assertEquals(Boolean.FALSE, cb.getValue());
+ Boolean newDmValue = cb.getConverter().convertToPresentation(
+ cb.getValue(), new Locale("fi", "FI"));
+ assertEquals(Boolean.FALSE, newDmValue);
+
+ // FIXME: Should be able to set to false here to cause datamodel to be
+ // set to false but the change will not be propagated to the Property
+ // (field value is already false)
+
+ cb.setValue(true);
+ assertEquals(Boolean.TRUE, cb.getValue());
+ assertEquals(Boolean.TRUE, property.getValue());
+
+ cb.setValue(false);
+ assertEquals(Boolean.FALSE, cb.getValue());
+ assertEquals(Boolean.FALSE, property.getValue());
+
+ }
+
+ public static class NumberBean {
+ private Number number;
+
+ public Number getNumber() {
+ return number;
+ }
+
+ public void setNumber(Number number) {
+ this.number = number;
+ }
+
+ }
+
+ public void testNumberDoubleConverterChange() {
+ final Application a = new Application();
+ Application.setCurrent(a);
+ TextField tf = new TextField() {
+ @Override
+ public Application getApplication() {
+ return a;
+ }
+ };
+ NumberBean nb = new NumberBean();
+ nb.setNumber(490);
+
+ tf.setPropertyDataSource(new MethodProperty<Number>(nb, "number"));
+ assertEquals(490, tf.getPropertyDataSource().getValue());
+ assertEquals("490", tf.getValue());
+
+ Converter c1 = tf.getConverter();
+
+ tf.setPropertyDataSource(new MethodProperty<Number>(nb, "number"));
+ Converter c2 = tf.getConverter();
+ assertTrue(
+ "StringToNumber converter is ok for integer types and should stay even though property is changed",
+ c1 == c2);
+ assertEquals(490, tf.getPropertyDataSource().getValue());
+ assertEquals("490", tf.getValue());
+
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractfield/DefaultConverterFactory.java b/server/tests/src/com/vaadin/tests/server/component/abstractfield/DefaultConverterFactory.java
new file mode 100644
index 0000000000..25430fc9a5
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/abstractfield/DefaultConverterFactory.java
@@ -0,0 +1,48 @@
+package com.vaadin.tests.server.component.abstractfield;
+
+import java.math.BigDecimal;
+import java.util.Locale;
+
+import junit.framework.TestCase;
+
+import com.vaadin.Application;
+import com.vaadin.data.util.MethodProperty;
+import com.vaadin.tests.data.bean.Address;
+import com.vaadin.tests.data.bean.Country;
+import com.vaadin.tests.data.bean.Person;
+import com.vaadin.tests.data.bean.Sex;
+import com.vaadin.ui.TextField;
+
+public class DefaultConverterFactory extends TestCase {
+
+ Person paulaBean = new Person("Paula", "Brilliant", "paula@brilliant.com",
+ 34, Sex.FEMALE, new Address("Paula street 1", 12345, "P-town",
+ Country.FINLAND));
+ {
+ paulaBean.setSalary(49000);
+ BigDecimal rent = new BigDecimal(57223);
+ rent = rent.scaleByPowerOfTen(-2);
+ paulaBean.setRent(rent);
+ }
+
+ public void testDefaultNumberConversion() {
+ Application app = new Application();
+ Application.setCurrent(app);
+ TextField tf = new TextField();
+ tf.setLocale(new Locale("en", "US"));
+ tf.setPropertyDataSource(new MethodProperty<Integer>(paulaBean,
+ "salary"));
+ assertEquals("49,000", tf.getValue());
+
+ tf.setLocale(new Locale("fi", "FI"));
+ // FIXME: The following line should not be necessary and should be
+ // removed
+ tf.setPropertyDataSource(new MethodProperty<Integer>(paulaBean,
+ "salary"));
+ String value = tf.getValue();
+ // Java uses a non-breaking space (ascii 160) instead of space when
+ // formatting
+ String expected = "49" + (char) 160 + "000";
+ assertEquals(expected, value);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractfield/RemoveListenersOnDetach.java b/server/tests/src/com/vaadin/tests/server/component/abstractfield/RemoveListenersOnDetach.java
new file mode 100644
index 0000000000..5dbab8467e
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/abstractfield/RemoveListenersOnDetach.java
@@ -0,0 +1,101 @@
+package com.vaadin.tests.server.component.abstractfield;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import com.vaadin.Application;
+import com.vaadin.data.Property;
+import com.vaadin.data.util.AbstractProperty;
+import com.vaadin.data.util.converter.Converter.ConversionException;
+import com.vaadin.server.WrappedRequest;
+import com.vaadin.ui.AbstractField;
+import com.vaadin.ui.UI;
+
+public class RemoveListenersOnDetach {
+
+ int numValueChanges = 0;
+ int numReadOnlyChanges = 0;
+
+ AbstractField field = new AbstractField() {
+ private UI uI = new UI() {
+
+ @Override
+ protected void init(WrappedRequest request) {
+
+ }
+
+ };
+ private Application application = new Application() {
+
+ };
+
+ @Override
+ public Class<?> getType() {
+ return String.class;
+ }
+
+ @Override
+ public void valueChange(Property.ValueChangeEvent event) {
+ super.valueChange(event);
+ numValueChanges++;
+ }
+
+ @Override
+ public void readOnlyStatusChange(
+ Property.ReadOnlyStatusChangeEvent event) {
+ super.readOnlyStatusChange(event);
+ numReadOnlyChanges++;
+ }
+
+ @Override
+ public com.vaadin.ui.UI getUI() {
+ return uI;
+ };
+
+ @Override
+ public Application getApplication() {
+ return application;
+ };
+ };
+
+ Property property = new AbstractProperty() {
+ @Override
+ public Object getValue() {
+ return null;
+ }
+
+ @Override
+ public void setValue(Object newValue) throws ReadOnlyException,
+ ConversionException {
+ fireValueChange();
+ }
+
+ @Override
+ public Class<?> getType() {
+ return String.class;
+ }
+ };
+
+ @Test
+ public void testAttachDetach() {
+ field.setPropertyDataSource(property);
+
+ property.setValue(null);
+ property.setReadOnly(true);
+ assertEquals(1, numValueChanges);
+ assertEquals(1, numReadOnlyChanges);
+
+ field.attach();
+ property.setValue(null);
+ property.setReadOnly(false);
+ assertEquals(2, numValueChanges);
+ assertEquals(2, numReadOnlyChanges);
+
+ field.detach();
+ property.setValue(null);
+ property.setReadOnly(true);
+ assertEquals(2, numValueChanges);
+ assertEquals(2, numReadOnlyChanges);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractfield/TestAbstractFieldListeners.java b/server/tests/src/com/vaadin/tests/server/component/abstractfield/TestAbstractFieldListeners.java
new file mode 100644
index 0000000000..9937bf92d5
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/abstractfield/TestAbstractFieldListeners.java
@@ -0,0 +1,21 @@
+package com.vaadin.tests.server.component.abstractfield;
+
+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.AbstractListenerMethodsTest;
+import com.vaadin.ui.CheckBox;
+
+public class TestAbstractFieldListeners extends AbstractListenerMethodsTest {
+ public void testReadOnlyStatusChangeListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(CheckBox.class,
+ ReadOnlyStatusChangeEvent.class,
+ ReadOnlyStatusChangeListener.class);
+ }
+
+ public void testValueChangeListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(CheckBox.class, ValueChangeEvent.class,
+ ValueChangeListener.class);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractorderedlayout/AddComponentsTest.java b/server/tests/src/com/vaadin/tests/server/component/abstractorderedlayout/AddComponentsTest.java
new file mode 100644
index 0000000000..1971fb6d0e
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/abstractorderedlayout/AddComponentsTest.java
@@ -0,0 +1,115 @@
+package com.vaadin.tests.server.component.abstractorderedlayout;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
+
+import com.vaadin.ui.AbstractOrderedLayout;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Layout;
+import com.vaadin.ui.VerticalLayout;
+
+public class AddComponentsTest {
+
+ Component[] children = new Component[] { new Label("A"), new Label("B"),
+ new Label("C"), new Label("D") };
+
+ @Test
+ public void moveComponentsBetweenLayouts() {
+ AbstractOrderedLayout layout1 = new HorizontalLayout();
+ AbstractOrderedLayout layout2 = new VerticalLayout();
+
+ layout1.addComponent(children[0]);
+ layout1.addComponent(children[1]);
+
+ layout2.addComponent(children[2]);
+ layout2.addComponent(children[3]);
+
+ layout2.addComponent(children[1], 1);
+ assertOrder(layout1, new int[] { 0 });
+ assertOrder(layout2, new int[] { 2, 1, 3 });
+
+ layout1.addComponent(children[3], 0);
+ assertOrder(layout1, new int[] { 3, 0 });
+ assertOrder(layout2, new int[] { 2, 1 });
+
+ layout2.addComponent(children[0]);
+ assertOrder(layout1, new int[] { 3 });
+ assertOrder(layout2, new int[] { 2, 1, 0 });
+
+ layout1.addComponentAsFirst(children[1]);
+ assertOrder(layout1, new int[] { 1, 3 });
+ assertOrder(layout2, new int[] { 2, 0 });
+ }
+
+ @Test
+ public void shuffleChildComponents() {
+ shuffleChildComponents(new HorizontalLayout());
+ shuffleChildComponents(new VerticalLayout());
+ }
+
+ private void shuffleChildComponents(AbstractOrderedLayout layout) {
+
+ for (int i = 0; i < children.length; ++i) {
+ layout.addComponent(children[i], i);
+ }
+
+ assertOrder(layout, new int[] { 0, 1, 2, 3 });
+
+ // Move C from #2 to #1
+ // Exhibits defect #7668
+ layout.addComponent(children[2], 1);
+ assertOrder(layout, new int[] { 0, 2, 1, 3 });
+
+ // Move C from #1 to #4 (which becomes #3 when #1 is erased)
+ layout.addComponent(children[2], 4);
+ assertOrder(layout, new int[] { 0, 1, 3, 2 });
+
+ // Keep everything in place
+ layout.addComponent(children[1], 1);
+ assertOrder(layout, new int[] { 0, 1, 3, 2 });
+
+ // Move D from #2 to #0
+ layout.addComponent(children[3], 0);
+ assertOrder(layout, new int[] { 3, 0, 1, 2 });
+
+ // Move A from #1 to end (#4 which becomes #3)
+ layout.addComponent(children[0]);
+ assertOrder(layout, new int[] { 3, 1, 2, 0 });
+
+ // Keep everything in place
+ layout.addComponent(children[0]);
+ assertOrder(layout, new int[] { 3, 1, 2, 0 });
+
+ // Move C from #2 to #0
+ layout.addComponentAsFirst(children[2]);
+ assertOrder(layout, new int[] { 2, 3, 1, 0 });
+
+ // Keep everything in place
+ layout.addComponentAsFirst(children[2]);
+ assertOrder(layout, new int[] { 2, 3, 1, 0 });
+ }
+
+ /**
+ * Asserts that layout has the components in children in the order specified
+ * by indices.
+ */
+ private void assertOrder(Layout layout, int[] indices) {
+ Iterator<?> i = layout.getComponentIterator();
+ try {
+ for (int index : indices) {
+ assertSame(children[index], i.next());
+ }
+ assertFalse("Too many components in layout", i.hasNext());
+ } catch (NoSuchElementException e) {
+ fail("Too few components in layout");
+ }
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractorderedlayout/TestAbstractOrderedLayoutListeners.java b/server/tests/src/com/vaadin/tests/server/component/abstractorderedlayout/TestAbstractOrderedLayoutListeners.java
new file mode 100644
index 0000000000..a0b34aca78
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/abstractorderedlayout/TestAbstractOrderedLayoutListeners.java
@@ -0,0 +1,14 @@
+package com.vaadin.tests.server.component.abstractorderedlayout;
+
+import com.vaadin.event.LayoutEvents.LayoutClickEvent;
+import com.vaadin.event.LayoutEvents.LayoutClickListener;
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+import com.vaadin.ui.VerticalLayout;
+
+public class TestAbstractOrderedLayoutListeners extends
+ AbstractListenerMethodsTest {
+ public void testLayoutClickListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(VerticalLayout.class, LayoutClickEvent.class,
+ LayoutClickListener.class);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractselect/TestAbstractSelectListeners.java b/server/tests/src/com/vaadin/tests/server/component/abstractselect/TestAbstractSelectListeners.java
new file mode 100644
index 0000000000..75c19b0517
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/abstractselect/TestAbstractSelectListeners.java
@@ -0,0 +1,20 @@
+package com.vaadin.tests.server.component.abstractselect;
+
+import com.vaadin.data.Container.ItemSetChangeEvent;
+import com.vaadin.data.Container.ItemSetChangeListener;
+import com.vaadin.data.Container.PropertySetChangeEvent;
+import com.vaadin.data.Container.PropertySetChangeListener;
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+import com.vaadin.ui.ComboBox;
+
+public class TestAbstractSelectListeners extends AbstractListenerMethodsTest {
+ public void testItemSetChangeListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(ComboBox.class, ItemSetChangeEvent.class,
+ ItemSetChangeListener.class);
+ }
+
+ public void testPropertySetChangeListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(ComboBox.class, PropertySetChangeEvent.class,
+ PropertySetChangeListener.class);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractsplitpanel/TestAbstractSplitPanelListeners.java b/server/tests/src/com/vaadin/tests/server/component/abstractsplitpanel/TestAbstractSplitPanelListeners.java
new file mode 100644
index 0000000000..2b6cdaa6cc
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/abstractsplitpanel/TestAbstractSplitPanelListeners.java
@@ -0,0 +1,14 @@
+package com.vaadin.tests.server.component.abstractsplitpanel;
+
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+import com.vaadin.ui.AbstractSplitPanel.SplitterClickEvent;
+import com.vaadin.ui.AbstractSplitPanel.SplitterClickListener;
+import com.vaadin.ui.HorizontalSplitPanel;
+
+public class TestAbstractSplitPanelListeners extends
+ AbstractListenerMethodsTest {
+ public void testSplitterClickListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(HorizontalSplitPanel.class,
+ SplitterClickEvent.class, SplitterClickListener.class);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/abstracttextfield/TestAbstractTextFieldListeners.java b/server/tests/src/com/vaadin/tests/server/component/abstracttextfield/TestAbstractTextFieldListeners.java
new file mode 100644
index 0000000000..9868d6ebfd
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/abstracttextfield/TestAbstractTextFieldListeners.java
@@ -0,0 +1,27 @@
+package com.vaadin.tests.server.component.abstracttextfield;
+
+import com.vaadin.event.FieldEvents.BlurEvent;
+import com.vaadin.event.FieldEvents.BlurListener;
+import com.vaadin.event.FieldEvents.FocusEvent;
+import com.vaadin.event.FieldEvents.FocusListener;
+import com.vaadin.event.FieldEvents.TextChangeEvent;
+import com.vaadin.event.FieldEvents.TextChangeListener;
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+import com.vaadin.ui.TextField;
+
+public class TestAbstractTextFieldListeners extends AbstractListenerMethodsTest {
+ public void testTextChangeListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(TextField.class, TextChangeEvent.class,
+ TextChangeListener.class);
+ }
+
+ public void testFocusListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(TextField.class, FocusEvent.class,
+ FocusListener.class);
+ }
+
+ public void testBlurListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(TextField.class, BlurEvent.class,
+ BlurListener.class);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/button/ButtonClick.java b/server/tests/src/com/vaadin/tests/server/component/button/ButtonClick.java
new file mode 100644
index 0000000000..4fe499a0a0
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/button/ButtonClick.java
@@ -0,0 +1,48 @@
+package com.vaadin.tests.server.component.button;
+
+import static org.junit.Assert.assertEquals;
+
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+
+import org.junit.Test;
+
+/**
+ * Tests the public click() method.
+ */
+public class ButtonClick {
+ private boolean clicked = false;
+
+ @Test
+ public void testClick() {
+ getButton().click();
+ assertEquals(clicked, true);
+ }
+
+ @Test
+ public void testClickDisabled() {
+ Button b = getButton();
+ b.setEnabled(false);
+ b.click();
+ assertEquals(clicked, false);
+ }
+
+ @Test
+ public void testClickReadOnly() {
+ Button b = getButton();
+ b.setReadOnly(true);
+ b.click();
+ assertEquals(clicked, false);
+ }
+
+ private Button getButton() {
+ Button b = new Button();
+ b.addListener(new Button.ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent ev) {
+ clicked = true;
+ }
+ });
+ return b;
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/button/ButtonListeners.java b/server/tests/src/com/vaadin/tests/server/component/button/ButtonListeners.java
new file mode 100644
index 0000000000..dc37312eea
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/button/ButtonListeners.java
@@ -0,0 +1,27 @@
+package com.vaadin.tests.server.component.button;
+
+import com.vaadin.event.FieldEvents.BlurEvent;
+import com.vaadin.event.FieldEvents.BlurListener;
+import com.vaadin.event.FieldEvents.FocusEvent;
+import com.vaadin.event.FieldEvents.FocusListener;
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+
+public class ButtonListeners extends AbstractListenerMethodsTest {
+ public void testFocusListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Button.class, FocusEvent.class,
+ FocusListener.class);
+ }
+
+ public void testBlurListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Button.class, BlurEvent.class,
+ BlurListener.class);
+ }
+
+ public void testClickListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Button.class, ClickEvent.class,
+ ClickListener.class);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/csslayout/AddComponentsTest.java b/server/tests/src/com/vaadin/tests/server/component/csslayout/AddComponentsTest.java
new file mode 100644
index 0000000000..c0d739b597
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/csslayout/AddComponentsTest.java
@@ -0,0 +1,109 @@
+package com.vaadin.tests.server.component.csslayout;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
+
+import com.vaadin.ui.Component;
+import com.vaadin.ui.CssLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Layout;
+
+public class AddComponentsTest {
+
+ private Component[] children = new Component[] { new Label("A"),
+ new Label("B"), new Label("C"), new Label("D") };
+
+ @Test
+ public void moveComponentsBetweenLayouts() {
+ CssLayout layout1 = new CssLayout();
+ CssLayout layout2 = new CssLayout();
+
+ layout1.addComponent(children[0]);
+ layout1.addComponent(children[1]);
+
+ layout2.addComponent(children[2]);
+ layout2.addComponent(children[3]);
+
+ layout2.addComponent(children[1], 1);
+ assertOrder(layout1, new int[] { 0 });
+ assertOrder(layout2, new int[] { 2, 1, 3 });
+
+ layout1.addComponent(children[3], 0);
+ assertOrder(layout1, new int[] { 3, 0 });
+ assertOrder(layout2, new int[] { 2, 1 });
+
+ layout2.addComponent(children[0]);
+ assertOrder(layout1, new int[] { 3 });
+ assertOrder(layout2, new int[] { 2, 1, 0 });
+
+ layout1.addComponentAsFirst(children[1]);
+ assertOrder(layout1, new int[] { 1, 3 });
+ assertOrder(layout2, new int[] { 2, 0 });
+ }
+
+ @Test
+ public void shuffleChildComponents() {
+ CssLayout layout = new CssLayout();
+
+ for (int i = 0; i < children.length; ++i) {
+ layout.addComponent(children[i], i);
+ }
+
+ assertOrder(layout, new int[] { 0, 1, 2, 3 });
+
+ // Move C from #2 to #1
+ // Exhibits defect #7668
+ layout.addComponent(children[2], 1);
+ assertOrder(layout, new int[] { 0, 2, 1, 3 });
+
+ // Move C from #1 to #4 (which becomes #3 when #1 is erased)
+ layout.addComponent(children[2], 4);
+ assertOrder(layout, new int[] { 0, 1, 3, 2 });
+
+ // Keep everything in place
+ layout.addComponent(children[1], 1);
+ assertOrder(layout, new int[] { 0, 1, 3, 2 });
+
+ // Move D from #2 to #0
+ layout.addComponent(children[3], 0);
+ assertOrder(layout, new int[] { 3, 0, 1, 2 });
+
+ // Move A from #1 to end (#4 which becomes #3)
+ layout.addComponent(children[0]);
+ assertOrder(layout, new int[] { 3, 1, 2, 0 });
+
+ // Keep everything in place
+ layout.addComponent(children[0]);
+ assertOrder(layout, new int[] { 3, 1, 2, 0 });
+
+ // Move C from #2 to #0
+ layout.addComponentAsFirst(children[2]);
+ assertOrder(layout, new int[] { 2, 3, 1, 0 });
+
+ // Keep everything in place
+ layout.addComponentAsFirst(children[2]);
+ assertOrder(layout, new int[] { 2, 3, 1, 0 });
+ }
+
+ /**
+ * Asserts that layout has the components in children in the order specified
+ * by indices.
+ */
+ private void assertOrder(Layout layout, int[] indices) {
+ Iterator<?> i = layout.getComponentIterator();
+ try {
+ for (int index : indices) {
+ assertSame(children[index], i.next());
+ }
+ assertFalse("Too many components in layout", i.hasNext());
+ } catch (NoSuchElementException e) {
+ fail("Too few components in layout");
+ }
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/csslayout/CssLayoutListeners.java b/server/tests/src/com/vaadin/tests/server/component/csslayout/CssLayoutListeners.java
new file mode 100644
index 0000000000..21a48888d6
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/csslayout/CssLayoutListeners.java
@@ -0,0 +1,13 @@
+package com.vaadin.tests.server.component.csslayout;
+
+import com.vaadin.event.LayoutEvents.LayoutClickEvent;
+import com.vaadin.event.LayoutEvents.LayoutClickListener;
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+import com.vaadin.ui.CssLayout;
+
+public class CssLayoutListeners extends AbstractListenerMethodsTest {
+ public void testLayoutClickListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(CssLayout.class, LayoutClickEvent.class,
+ LayoutClickListener.class);
+ }
+} \ No newline at end of file
diff --git a/server/tests/src/com/vaadin/tests/server/component/datefield/DateFieldListeners.java b/server/tests/src/com/vaadin/tests/server/component/datefield/DateFieldListeners.java
new file mode 100644
index 0000000000..0f4aee35c7
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/datefield/DateFieldListeners.java
@@ -0,0 +1,20 @@
+package com.vaadin.tests.server.component.datefield;
+
+import com.vaadin.event.FieldEvents.BlurEvent;
+import com.vaadin.event.FieldEvents.BlurListener;
+import com.vaadin.event.FieldEvents.FocusEvent;
+import com.vaadin.event.FieldEvents.FocusListener;
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+import com.vaadin.ui.DateField;
+
+public class DateFieldListeners extends AbstractListenerMethodsTest {
+ public void testFocusListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(DateField.class, FocusEvent.class,
+ FocusListener.class);
+ }
+
+ public void testBlurListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(DateField.class, BlurEvent.class,
+ BlurListener.class);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/datefield/ResolutionTest.java b/server/tests/src/com/vaadin/tests/server/component/datefield/ResolutionTest.java
new file mode 100644
index 0000000000..00b5c60dad
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/datefield/ResolutionTest.java
@@ -0,0 +1,61 @@
+package com.vaadin.tests.server.component.datefield;
+
+import java.util.ArrayList;
+
+import junit.framework.TestCase;
+
+import com.vaadin.tests.util.TestUtil;
+import com.vaadin.ui.DateField.Resolution;
+
+public class ResolutionTest extends TestCase {
+
+ public void testResolutionHigherOrEqualToYear() {
+ Iterable<Resolution> higherOrEqual = Resolution
+ .getResolutionsHigherOrEqualTo(Resolution.YEAR);
+ ArrayList<Resolution> expected = new ArrayList<Resolution>();
+ expected.add(Resolution.YEAR);
+ TestUtil.assertIterableEquals(expected, higherOrEqual);
+ }
+
+ public void testResolutionHigherOrEqualToDay() {
+ Iterable<Resolution> higherOrEqual = Resolution
+ .getResolutionsHigherOrEqualTo(Resolution.DAY);
+ ArrayList<Resolution> expected = new ArrayList<Resolution>();
+ expected.add(Resolution.DAY);
+ expected.add(Resolution.MONTH);
+ expected.add(Resolution.YEAR);
+ TestUtil.assertIterableEquals(expected, higherOrEqual);
+
+ }
+
+ public void testResolutionLowerThanDay() {
+ Iterable<Resolution> higherOrEqual = Resolution
+ .getResolutionsLowerThan(Resolution.DAY);
+ ArrayList<Resolution> expected = new ArrayList<Resolution>();
+ expected.add(Resolution.HOUR);
+ expected.add(Resolution.MINUTE);
+ expected.add(Resolution.SECOND);
+ TestUtil.assertIterableEquals(expected, higherOrEqual);
+
+ }
+
+ public void testResolutionLowerThanSecond() {
+ Iterable<Resolution> higherOrEqual = Resolution
+ .getResolutionsLowerThan(Resolution.SECOND);
+ ArrayList<Resolution> expected = new ArrayList<Resolution>();
+ TestUtil.assertIterableEquals(expected, higherOrEqual);
+ }
+
+ public void testResolutionLowerThanYear() {
+ Iterable<Resolution> higherOrEqual = Resolution
+ .getResolutionsLowerThan(Resolution.YEAR);
+ ArrayList<Resolution> expected = new ArrayList<Resolution>();
+ expected.add(Resolution.MONTH);
+ expected.add(Resolution.DAY);
+ expected.add(Resolution.HOUR);
+ expected.add(Resolution.MINUTE);
+ expected.add(Resolution.SECOND);
+ TestUtil.assertIterableEquals(expected, higherOrEqual);
+
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/embedded/EmbeddedListeners.java b/server/tests/src/com/vaadin/tests/server/component/embedded/EmbeddedListeners.java
new file mode 100644
index 0000000000..7512f0f499
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/embedded/EmbeddedListeners.java
@@ -0,0 +1,13 @@
+package com.vaadin.tests.server.component.embedded;
+
+import com.vaadin.event.MouseEvents.ClickEvent;
+import com.vaadin.event.MouseEvents.ClickListener;
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+import com.vaadin.ui.Embedded;
+
+public class EmbeddedListeners extends AbstractListenerMethodsTest {
+ public void testClickListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Embedded.class, ClickEvent.class,
+ ClickListener.class);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/gridlayout/GridLayoutListeners.java b/server/tests/src/com/vaadin/tests/server/component/gridlayout/GridLayoutListeners.java
new file mode 100644
index 0000000000..ce3a9faa65
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/gridlayout/GridLayoutListeners.java
@@ -0,0 +1,13 @@
+package com.vaadin.tests.server.component.gridlayout;
+
+import com.vaadin.event.LayoutEvents.LayoutClickEvent;
+import com.vaadin.event.LayoutEvents.LayoutClickListener;
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+import com.vaadin.ui.GridLayout;
+
+public class GridLayoutListeners extends AbstractListenerMethodsTest {
+ public void testLayoutClickListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(GridLayout.class, LayoutClickEvent.class,
+ LayoutClickListener.class);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/label/LabelConverters.java b/server/tests/src/com/vaadin/tests/server/component/label/LabelConverters.java
new file mode 100644
index 0000000000..48279c7c88
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/label/LabelConverters.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2011 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.label;
+
+import junit.framework.TestCase;
+
+import com.vaadin.Application;
+import com.vaadin.data.Property;
+import com.vaadin.data.util.MethodProperty;
+import com.vaadin.tests.data.bean.Person;
+import com.vaadin.ui.Label;
+
+public class LabelConverters extends TestCase {
+
+ public void testLabelSetDataSourceLaterOn() {
+ Person p = Person.createTestPerson1();
+ Label l = new Label("My label");
+ assertEquals("My label", l.getValue());
+ assertNull(l.getConverter());
+ l.setPropertyDataSource(new MethodProperty<String>(p, "firstName"));
+ assertEquals(p.getFirstName(), l.getValue());
+ p.setFirstName("123");
+ assertEquals("123", l.getValue());
+ }
+
+ public void testIntegerDataSource() {
+ Application.setCurrent(new Application());
+ Label l = new Label("Foo");
+ Property ds = new MethodProperty<Integer>(Person.createTestPerson1(),
+ "age");
+ l.setPropertyDataSource(ds);
+ assertEquals(String.valueOf(Person.createTestPerson1().getAge()),
+ l.getValue());
+ }
+
+ public void testSetValueWithDataSource() {
+ try {
+ MethodProperty<String> property = new MethodProperty<String>(
+ Person.createTestPerson1(), "firstName");
+ Label l = new Label(property);
+ l.setValue("Foo");
+ fail("setValue should throw an exception when a data source is set");
+ } catch (Exception e) {
+ }
+
+ }
+
+ public void testLabelWithoutDataSource() {
+ Label l = new Label("My label");
+ assertEquals("My label", l.getValue());
+ assertNull(l.getConverter());
+ assertNull(l.getPropertyDataSource());
+ l.setValue("New value");
+ assertEquals("New value", l.getValue());
+ assertNull(l.getConverter());
+ assertNull(l.getPropertyDataSource());
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/label/LabelListeners.java b/server/tests/src/com/vaadin/tests/server/component/label/LabelListeners.java
new file mode 100644
index 0000000000..3ed79f5010
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/label/LabelListeners.java
@@ -0,0 +1,13 @@
+package com.vaadin.tests.server.component.label;
+
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Label.ValueChangeEvent;
+
+public class LabelListeners extends AbstractListenerMethodsTest {
+ public void testValueChangeListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Label.class, ValueChangeEvent.class,
+ ValueChangeListener.class);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/loginform/LoginFormListeners.java b/server/tests/src/com/vaadin/tests/server/component/loginform/LoginFormListeners.java
new file mode 100644
index 0000000000..fd3e02994c
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/loginform/LoginFormListeners.java
@@ -0,0 +1,13 @@
+package com.vaadin.tests.server.component.loginform;
+
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+import com.vaadin.ui.LoginForm;
+import com.vaadin.ui.LoginForm.LoginEvent;
+import com.vaadin.ui.LoginForm.LoginListener;
+
+public class LoginFormListeners extends AbstractListenerMethodsTest {
+ public void testLoginListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(LoginForm.class, LoginEvent.class,
+ LoginListener.class);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/menubar/MenuBarIds.java b/server/tests/src/com/vaadin/tests/server/component/menubar/MenuBarIds.java
new file mode 100644
index 0000000000..f304315ebc
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/menubar/MenuBarIds.java
@@ -0,0 +1,98 @@
+package com.vaadin.tests.server.component.menubar;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import com.vaadin.ui.MenuBar;
+import com.vaadin.ui.MenuBar.Command;
+import com.vaadin.ui.MenuBar.MenuItem;
+
+public class MenuBarIds extends TestCase implements Command {
+
+ private MenuItem lastSelectedItem;
+ private MenuItem menuFile;
+ private MenuItem menuEdit;
+ private MenuItem menuEditCopy;
+ private MenuItem menuEditCut;
+ private MenuItem menuEditPaste;
+ private MenuItem menuEditFind;
+ private MenuItem menuFileOpen;
+ private MenuItem menuFileSave;
+ private MenuItem menuFileExit;
+ private Set<MenuItem> menuItems = new HashSet<MenuItem>();
+
+ private MenuBar menuBar;
+
+ @Override
+ public void setUp() {
+ menuBar = new MenuBar();
+ menuFile = menuBar.addItem("File", this);
+ menuEdit = menuBar.addItem("Edit", this);
+ menuEditCopy = menuEdit.addItem("Copy", this);
+ menuEditCut = menuEdit.addItem("Cut", this);
+ menuEditPaste = menuEdit.addItem("Paste", this);
+ menuEdit.addSeparator();
+ menuEditFind = menuEdit.addItem("Find...", this);
+ menuFileOpen = menuFile.addItem("Open", this);
+ menuFileSave = menuFile.addItem("Save", this);
+ menuFile.addSeparator();
+ menuFileExit = menuFile.addItem("Exit", this);
+
+ menuItems.add(menuFile);
+ menuItems.add(menuEdit);
+ menuItems.add(menuEditCopy);
+ menuItems.add(menuEditCut);
+ menuItems.add(menuEditPaste);
+ menuItems.add(menuEditFind);
+ menuItems.add(menuFileOpen);
+ menuItems.add(menuFileSave);
+ menuItems.add(menuFileExit);
+ }
+
+ public void testMenubarIdUniqueness() {
+ // Ids within a menubar must be unique
+ assertUniqueIds(menuBar);
+
+ menuBar.removeItem(menuFile);
+ MenuItem file2 = menuBar.addItem("File2", this);
+ MenuItem file3 = menuBar.addItem("File3", this);
+ MenuItem file2sub = file2.addItem("File2 sub menu", this);
+ menuItems.add(file2);
+ menuItems.add(file2sub);
+ menuItems.add(file3);
+
+ assertUniqueIds(menuBar);
+ }
+
+ private static void assertUniqueIds(MenuBar menuBar) {
+
+ Set<Object> ids = new HashSet<Object>();
+
+ for (MenuItem item : menuBar.getItems()) {
+ assertUniqueIds(ids, item);
+ }
+ }
+
+ private static void assertUniqueIds(Set<Object> ids, MenuItem item) {
+ int id = item.getId();
+ System.out.println("Item " + item.getText() + ", id: " + id);
+ assertFalse(ids.contains(id));
+ ids.add(id);
+ if (item.getChildren() != null) {
+ for (MenuItem subItem : item.getChildren()) {
+ assertUniqueIds(ids, subItem);
+ }
+ }
+ }
+
+ @Override
+ public void menuSelected(MenuItem selectedItem) {
+ assertNull("lastSelectedItem was not cleared before selecting an item",
+ lastSelectedItem);
+
+ lastSelectedItem = selectedItem;
+
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/optiongroup/OptionGroupListeners.java b/server/tests/src/com/vaadin/tests/server/component/optiongroup/OptionGroupListeners.java
new file mode 100644
index 0000000000..7eb35c3882
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/optiongroup/OptionGroupListeners.java
@@ -0,0 +1,20 @@
+package com.vaadin.tests.server.component.optiongroup;
+
+import com.vaadin.event.FieldEvents.BlurEvent;
+import com.vaadin.event.FieldEvents.BlurListener;
+import com.vaadin.event.FieldEvents.FocusEvent;
+import com.vaadin.event.FieldEvents.FocusListener;
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+import com.vaadin.ui.OptionGroup;
+
+public class OptionGroupListeners extends AbstractListenerMethodsTest {
+ public void testFocusListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(OptionGroup.class, FocusEvent.class,
+ FocusListener.class);
+ }
+
+ public void testBlurListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(OptionGroup.class, BlurEvent.class,
+ BlurListener.class);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/orderedlayout/TestOrderedLayout.java b/server/tests/src/com/vaadin/tests/server/component/orderedlayout/TestOrderedLayout.java
new file mode 100644
index 0000000000..6a9d55d7e4
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/orderedlayout/TestOrderedLayout.java
@@ -0,0 +1,49 @@
+package com.vaadin.tests.server.component.orderedlayout;
+
+import java.util.Iterator;
+
+import junit.framework.TestCase;
+
+import com.vaadin.ui.AbstractOrderedLayout;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.VerticalLayout;
+
+public class TestOrderedLayout extends TestCase {
+
+ public void testVLIteration() {
+ testIndexing(new VerticalLayout(), 10);
+ }
+
+ public void testHLIteration() {
+ testIndexing(new HorizontalLayout(), 12);
+ }
+
+ public void testIndexing(AbstractOrderedLayout aol, int nrComponents) {
+ Component[] components = generateComponents(nrComponents);
+ for (Component c : components) {
+ aol.addComponent(c);
+ }
+ for (int i = 0; i < nrComponents; i++) {
+ assert (aol.getComponent(i) == components[i]);
+ assert (aol.getComponentIndex(components[i]) == i);
+ }
+
+ // Iteration should be in indexed order
+ int idx = 0;
+ for (Iterator<Component> i = aol.getComponentIterator(); i.hasNext();) {
+ Component c = i.next();
+ assert (aol.getComponentIndex(c) == idx++);
+ }
+ }
+
+ private Component[] generateComponents(int nr) {
+ Component[] components = new Component[nr];
+ for (int i = 0; i < nr; i++) {
+ components[i] = new Label("" + i);
+ }
+
+ return components;
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/panel/PanelListeners.java b/server/tests/src/com/vaadin/tests/server/component/panel/PanelListeners.java
new file mode 100644
index 0000000000..275e90f5d1
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/panel/PanelListeners.java
@@ -0,0 +1,13 @@
+package com.vaadin.tests.server.component.panel;
+
+import com.vaadin.event.MouseEvents.ClickEvent;
+import com.vaadin.event.MouseEvents.ClickListener;
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+import com.vaadin.ui.Panel;
+
+public class PanelListeners extends AbstractListenerMethodsTest {
+ public void testClickListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Panel.class, ClickEvent.class,
+ ClickListener.class);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/popupview/PopupViewListeners.java b/server/tests/src/com/vaadin/tests/server/component/popupview/PopupViewListeners.java
new file mode 100644
index 0000000000..12a5a0f520
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/popupview/PopupViewListeners.java
@@ -0,0 +1,14 @@
+package com.vaadin.tests.server.component.popupview;
+
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.PopupView;
+import com.vaadin.ui.PopupView.PopupVisibilityEvent;
+import com.vaadin.ui.PopupView.PopupVisibilityListener;
+
+public class PopupViewListeners extends AbstractListenerMethodsTest {
+ public void testPopupVisibilityListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(PopupView.class, PopupVisibilityEvent.class,
+ PopupVisibilityListener.class, new PopupView("", new Label()));
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/root/CustomUIClassLoader.java b/server/tests/src/com/vaadin/tests/server/component/root/CustomUIClassLoader.java
new file mode 100644
index 0000000000..906d6ccebd
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/root/CustomUIClassLoader.java
@@ -0,0 +1,137 @@
+package com.vaadin.tests.server.component.root;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import junit.framework.TestCase;
+
+import org.easymock.EasyMock;
+
+import com.vaadin.Application;
+import com.vaadin.Application.ApplicationStartEvent;
+import com.vaadin.UIRequiresMoreInformationException;
+import com.vaadin.server.DefaultUIProvider;
+import com.vaadin.server.DeploymentConfiguration;
+import com.vaadin.server.WrappedRequest;
+import com.vaadin.ui.UI;
+
+public class CustomUIClassLoader extends TestCase {
+
+ /**
+ * Stub root
+ */
+ public static class MyUI extends UI {
+ @Override
+ protected void init(WrappedRequest request) {
+ // Nothing to see here
+ }
+ }
+
+ /**
+ * Dummy ClassLoader that just saves the name of the requested class before
+ * delegating to the default implementation.
+ */
+ public class LoggingClassLoader extends ClassLoader {
+
+ private List<String> requestedClasses = new ArrayList<String>();
+
+ @Override
+ protected synchronized Class<?> loadClass(String name, boolean resolve)
+ throws ClassNotFoundException {
+ requestedClasses.add(name);
+ return super.loadClass(name, resolve);
+ }
+ }
+
+ /**
+ * Tests that a UI class can be loaded even if no classloader has been
+ * provided.
+ *
+ * @throws Exception
+ * if thrown
+ */
+ public void testWithNullClassLoader() throws Exception {
+ Application application = createStubApplication();
+ application.start(new ApplicationStartEvent(null,
+ createConfigurationMock(), null));
+
+ UI uI = application.getUIForRequest(createRequestMock(null));
+ assertTrue(uI instanceof MyUI);
+ }
+
+ private static DeploymentConfiguration createConfigurationMock() {
+ DeploymentConfiguration configurationMock = EasyMock
+ .createMock(DeploymentConfiguration.class);
+ EasyMock.expect(configurationMock.isProductionMode()).andReturn(false);
+ EasyMock.expect(configurationMock.getInitParameters()).andReturn(
+ new Properties());
+
+ EasyMock.replay(configurationMock);
+ return configurationMock;
+ }
+
+ private static WrappedRequest createRequestMock(ClassLoader classloader) {
+ // Mock a DeploymentConfiguration to give the passed classloader
+ DeploymentConfiguration configurationMock = EasyMock
+ .createMock(DeploymentConfiguration.class);
+ EasyMock.expect(configurationMock.getClassLoader()).andReturn(
+ classloader);
+
+ // Mock a WrappedRequest to give the mocked deployment configuration
+ WrappedRequest requestMock = EasyMock.createMock(WrappedRequest.class);
+ EasyMock.expect(requestMock.getDeploymentConfiguration()).andReturn(
+ configurationMock);
+
+ EasyMock.replay(configurationMock, requestMock);
+ return requestMock;
+ }
+
+ /**
+ * Tests that the ClassLoader passed in the ApplicationStartEvent is used to
+ * load UI classes.
+ *
+ * @throws Exception
+ * if thrown
+ */
+ public void testWithClassLoader() throws Exception {
+ LoggingClassLoader loggingClassLoader = new LoggingClassLoader();
+
+ Application application = createStubApplication();
+ application.start(new ApplicationStartEvent(null,
+ createConfigurationMock(), null));
+
+ UI uI = application
+ .getUIForRequest(createRequestMock(loggingClassLoader));
+ assertTrue(uI instanceof MyUI);
+ assertEquals(1, loggingClassLoader.requestedClasses.size());
+ assertEquals(MyUI.class.getName(),
+ loggingClassLoader.requestedClasses.get(0));
+
+ }
+
+ private Application createStubApplication() {
+ return new Application() {
+ {
+ addUIProvider(new DefaultUIProvider());
+ }
+
+ @Override
+ public String getProperty(String name) {
+ if (name.equals(UI_PARAMETER)) {
+ return MyUI.class.getName();
+ } else {
+ return super.getProperty(name);
+ }
+ }
+
+ @Override
+ public UI getUIForRequest(WrappedRequest request)
+ throws UIRequiresMoreInformationException {
+ // Always create a new root for testing (can't directly use
+ // getRoot as it's protected)
+ return getUI(request);
+ }
+ };
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/select/SelectListeners.java b/server/tests/src/com/vaadin/tests/server/component/select/SelectListeners.java
new file mode 100644
index 0000000000..c7703303d3
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/select/SelectListeners.java
@@ -0,0 +1,20 @@
+package com.vaadin.tests.server.component.select;
+
+import com.vaadin.event.FieldEvents.BlurEvent;
+import com.vaadin.event.FieldEvents.BlurListener;
+import com.vaadin.event.FieldEvents.FocusEvent;
+import com.vaadin.event.FieldEvents.FocusListener;
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+import com.vaadin.ui.Select;
+
+public class SelectListeners extends AbstractListenerMethodsTest {
+ public void testFocusListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Select.class, FocusEvent.class,
+ FocusListener.class);
+ }
+
+ public void testBlurListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Select.class, BlurEvent.class,
+ BlurListener.class);
+ }
+} \ No newline at end of file
diff --git a/server/tests/src/com/vaadin/tests/server/component/slider/SliderTest.java b/server/tests/src/com/vaadin/tests/server/component/slider/SliderTest.java
new file mode 100644
index 0000000000..b969bf5e53
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/slider/SliderTest.java
@@ -0,0 +1,25 @@
+package com.vaadin.tests.server.component.slider;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import com.vaadin.ui.Slider;
+import com.vaadin.ui.Slider.ValueOutOfBoundsException;
+
+public class SliderTest extends TestCase {
+
+ public void testOutOfBounds() {
+ Slider s = new Slider(0, 10);
+ s.setValue(0);
+ Assert.assertEquals(0.0, s.getValue());
+ s.setValue(10);
+ Assert.assertEquals(10.0, s.getValue());
+ try {
+ s.setValue(20);
+ fail("Should throw out of bounds exception");
+ } catch (ValueOutOfBoundsException e) {
+ // TODO: handle exception
+ }
+
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/table/TableColumnAlignments.java b/server/tests/src/com/vaadin/tests/server/component/table/TableColumnAlignments.java
new file mode 100644
index 0000000000..299f9c79d4
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/table/TableColumnAlignments.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 TableColumnAlignments {
+
+ @Test
+ public void defaultColumnAlignments() {
+ for (int properties = 0; properties < 10; properties++) {
+ Table t = TableGenerator.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 = TableGenerator
+ .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 = TableGenerator.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 = TableGenerator.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 = TableGenerator.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 = TableGenerator
+ .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/server/tests/src/com/vaadin/tests/server/component/table/TableGenerator.java b/server/tests/src/com/vaadin/tests/server/component/table/TableGenerator.java
new file mode 100644
index 0000000000..0e63049944
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/table/TableGenerator.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 TableGenerator {
+ 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/server/tests/src/com/vaadin/tests/server/component/table/TableListeners.java b/server/tests/src/com/vaadin/tests/server/component/table/TableListeners.java
new file mode 100644
index 0000000000..6cc522f8c7
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/table/TableListeners.java
@@ -0,0 +1,41 @@
+package com.vaadin.tests.server.component.table;
+
+import com.vaadin.event.ItemClickEvent;
+import com.vaadin.event.ItemClickEvent.ItemClickListener;
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+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 TableListeners extends AbstractListenerMethodsTest {
+ public void testColumnResizeListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Table.class, ColumnResizeEvent.class,
+ ColumnResizeListener.class);
+ }
+
+ public void testItemClickListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Table.class, ItemClickEvent.class,
+ ItemClickListener.class);
+ }
+
+ public void testFooterClickListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Table.class, FooterClickEvent.class,
+ FooterClickListener.class);
+ }
+
+ public void testHeaderClickListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Table.class, HeaderClickEvent.class,
+ HeaderClickListener.class);
+ }
+
+ public void testColumnReorderListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Table.class, ColumnReorderEvent.class,
+ ColumnReorderListener.class);
+ }
+} \ No newline at end of file
diff --git a/server/tests/src/com/vaadin/tests/server/component/table/TableSerialization.java b/server/tests/src/com/vaadin/tests/server/component/table/TableSerialization.java
new file mode 100644
index 0000000000..ee6349093c
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/table/TableSerialization.java
@@ -0,0 +1,25 @@
+package com.vaadin.tests.server.component.table;
+
+import junit.framework.TestCase;
+
+import org.apache.commons.lang.SerializationUtils;
+
+import com.vaadin.ui.Table;
+
+public class TableSerialization extends TestCase {
+
+ public void testSerialization() {
+ Table t = new Table();
+ byte[] ser = SerializationUtils.serialize(t);
+ Table t2 = (Table) SerializationUtils.deserialize(ser);
+
+ }
+
+ 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/server/tests/src/com/vaadin/tests/server/component/table/TableVisibleColumns.java b/server/tests/src/com/vaadin/tests/server/component/table/TableVisibleColumns.java
new file mode 100644
index 0000000000..be312044db
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/table/TableVisibleColumns.java
@@ -0,0 +1,75 @@
+package com.vaadin.tests.server.component.table;
+
+import static org.junit.Assert.assertArrayEquals;
+
+import org.junit.Test;
+
+import com.vaadin.ui.Table;
+
+public class TableVisibleColumns {
+
+ String[] defaultColumns3 = new String[] { "Property 0", "Property 1",
+ "Property 2" };
+
+ @Test
+ public void defaultVisibleColumns() {
+ for (int properties = 0; properties < 10; properties++) {
+ Table t = TableGenerator.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 = TableGenerator.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 = TableGenerator.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 = TableGenerator.createTableWithDefaultContainer(3, 10);
+ try {
+ t.setVisibleColumns(new Object[] { "Property 0", "Property 1",
+ "Property 2", "Property 1" });
+ // FIXME: Multiple properties in the Object array should be detected
+ // (#6476)
+ // junit.framework.Assert.fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ // OK, expected
+ }
+ // FIXME: Multiple properties in the Object array should be detected
+ // (#6476)
+ // assertArrayEquals(defaultColumns3, t.getVisibleColumns());
+ }
+
+ @Test
+ public void noVisibleColumns() {
+ Table t = TableGenerator.createTableWithDefaultContainer(3, 10);
+ t.setVisibleColumns(new Object[] {});
+ assertArrayEquals(new Object[] {}, t.getVisibleColumns());
+
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/table/TestFooter.java b/server/tests/src/com/vaadin/tests/server/component/table/TestFooter.java
new file mode 100644
index 0000000000..647d13855b
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/table/TestFooter.java
@@ -0,0 +1,94 @@
+package com.vaadin.tests.server.component.table;
+
+import junit.framework.TestCase;
+
+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 TestFooter extends TestCase {
+
+ /**
+ * Tests if setting the footer visibility works properly
+ */
+ 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
+ */
+ 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
+ */
+ 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/server/tests/src/com/vaadin/tests/server/component/table/TestMultipleSelection.java b/server/tests/src/com/vaadin/tests/server/component/table/TestMultipleSelection.java
new file mode 100644
index 0000000000..767b651b68
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/table/TestMultipleSelection.java
@@ -0,0 +1,57 @@
+package com.vaadin.tests.server.component.table;
+
+import java.util.Arrays;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.Container;
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.ui.AbstractSelect.MultiSelectMode;
+import com.vaadin.ui.Table;
+
+public class TestMultipleSelection extends TestCase {
+
+ /**
+ * Tests weather the multiple select mode is set when using Table.set
+ */
+ @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.
+ */
+ 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/server/tests/src/com/vaadin/tests/server/component/tabsheet/TabSheetListeners.java b/server/tests/src/com/vaadin/tests/server/component/tabsheet/TabSheetListeners.java
new file mode 100644
index 0000000000..5c01a1c99f
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/tabsheet/TabSheetListeners.java
@@ -0,0 +1,13 @@
+package com.vaadin.tests.server.component.tabsheet;
+
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+import com.vaadin.ui.TabSheet;
+import com.vaadin.ui.TabSheet.SelectedTabChangeEvent;
+import com.vaadin.ui.TabSheet.SelectedTabChangeListener;
+
+public class TabSheetListeners extends AbstractListenerMethodsTest {
+ public void testSelectedTabChangeListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(TabSheet.class, SelectedTabChangeEvent.class,
+ SelectedTabChangeListener.class);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/tabsheet/TestTabSheet.java b/server/tests/src/com/vaadin/tests/server/component/tabsheet/TestTabSheet.java
new file mode 100644
index 0000000000..0ef8ae5a76
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/tabsheet/TestTabSheet.java
@@ -0,0 +1,224 @@
+package com.vaadin.tests.server.component.tabsheet;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+
+import java.util.Iterator;
+
+import org.junit.Test;
+
+import com.vaadin.ui.Component;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.TabSheet;
+import com.vaadin.ui.TabSheet.Tab;
+
+public class TestTabSheet {
+
+ @Test
+ public void addExistingComponent() {
+ Component c = new Label("abc");
+ TabSheet tabSheet = new TabSheet();
+ tabSheet.addComponent(c);
+ tabSheet.addComponent(c);
+
+ Iterator<Component> iter = tabSheet.getComponentIterator();
+
+ assertEquals(c, iter.next());
+ assertEquals(false, iter.hasNext());
+ assertNotNull(tabSheet.getTab(c));
+ }
+
+ @Test
+ public void getComponentFromTab() {
+ Component c = new Label("abc");
+ TabSheet tabSheet = new TabSheet();
+ Tab tab = tabSheet.addTab(c);
+ assertEquals(c, tab.getComponent());
+ }
+
+ @Test
+ public void addTabWithComponentOnly() {
+ TabSheet tabSheet = new TabSheet();
+ Tab tab1 = tabSheet.addTab(new Label("aaa"));
+ Tab tab2 = tabSheet.addTab(new Label("bbb"));
+ Tab tab3 = tabSheet.addTab(new Label("ccc"));
+
+ // Check right order of tabs
+ assertEquals(0, tabSheet.getTabPosition(tab1));
+ assertEquals(1, tabSheet.getTabPosition(tab2));
+ assertEquals(2, tabSheet.getTabPosition(tab3));
+
+ // Calling addTab with existing component does not move tab
+ tabSheet.addTab(tab1.getComponent());
+
+ // Check right order of tabs
+ assertEquals(0, tabSheet.getTabPosition(tab1));
+ assertEquals(1, tabSheet.getTabPosition(tab2));
+ assertEquals(2, tabSheet.getTabPosition(tab3));
+ }
+
+ @Test
+ public void addTabWithComponentAndIndex() {
+ TabSheet tabSheet = new TabSheet();
+ Tab tab1 = tabSheet.addTab(new Label("aaa"));
+ Tab tab2 = tabSheet.addTab(new Label("bbb"));
+ Tab tab3 = tabSheet.addTab(new Label("ccc"));
+
+ Tab tab4 = tabSheet.addTab(new Label("ddd"), 1);
+ Tab tab5 = tabSheet.addTab(new Label("eee"), 3);
+
+ assertEquals(0, tabSheet.getTabPosition(tab1));
+ assertEquals(1, tabSheet.getTabPosition(tab4));
+ assertEquals(2, tabSheet.getTabPosition(tab2));
+ assertEquals(3, tabSheet.getTabPosition(tab5));
+ assertEquals(4, tabSheet.getTabPosition(tab3));
+
+ // Calling addTab with existing component does not move tab
+ tabSheet.addTab(tab1.getComponent(), 3);
+
+ assertEquals(0, tabSheet.getTabPosition(tab1));
+ assertEquals(1, tabSheet.getTabPosition(tab4));
+ assertEquals(2, tabSheet.getTabPosition(tab2));
+ assertEquals(3, tabSheet.getTabPosition(tab5));
+ assertEquals(4, tabSheet.getTabPosition(tab3));
+ }
+
+ @Test
+ public void addTabWithAllParameters() {
+ TabSheet tabSheet = new TabSheet();
+ Tab tab1 = tabSheet.addTab(new Label("aaa"));
+ Tab tab2 = tabSheet.addTab(new Label("bbb"));
+ Tab tab3 = tabSheet.addTab(new Label("ccc"));
+
+ Tab tab4 = tabSheet.addTab(new Label("ddd"), "ddd", null, 1);
+ Tab tab5 = tabSheet.addTab(new Label("eee"), "eee", null, 3);
+
+ assertEquals(0, tabSheet.getTabPosition(tab1));
+ assertEquals(1, tabSheet.getTabPosition(tab4));
+ assertEquals(2, tabSheet.getTabPosition(tab2));
+ assertEquals(3, tabSheet.getTabPosition(tab5));
+ assertEquals(4, tabSheet.getTabPosition(tab3));
+
+ // Calling addTab with existing component does not move tab
+ tabSheet.addTab(tab1.getComponent(), "xxx", null, 3);
+
+ assertEquals(0, tabSheet.getTabPosition(tab1));
+ assertEquals(1, tabSheet.getTabPosition(tab4));
+ assertEquals(2, tabSheet.getTabPosition(tab2));
+ assertEquals(3, tabSheet.getTabPosition(tab5));
+ assertEquals(4, tabSheet.getTabPosition(tab3));
+ }
+
+ @Test
+ public void getTabByPosition() {
+ TabSheet tabSheet = new TabSheet();
+ Tab tab1 = tabSheet.addTab(new Label("aaa"));
+ Tab tab2 = tabSheet.addTab(new Label("bbb"));
+ Tab tab3 = tabSheet.addTab(new Label("ccc"));
+
+ assertEquals(tab1, tabSheet.getTab(0));
+ assertEquals(tab2, tabSheet.getTab(1));
+ assertEquals(tab3, tabSheet.getTab(2));
+
+ assertEquals(null, tabSheet.getTab(3));
+ }
+
+ @Test
+ public void selectTab() {
+ TabSheet tabSheet = new TabSheet();
+ Tab tab1 = tabSheet.addTab(new Label("aaa"));
+ Tab tab2 = tabSheet.addTab(new Label("bbb"));
+ Tab tab3 = tabSheet.addTab(new Label("ccc"));
+ Label componentNotInSheet = new Label("ddd");
+ Tab tabNotInSheet = new TabSheet().addTab(new Label("eee"));
+
+ assertEquals(tab1.getComponent(), tabSheet.getSelectedTab());
+
+ // Select tab by component...
+ tabSheet.setSelectedTab(tab2.getComponent());
+ assertEquals(tab2.getComponent(), tabSheet.getSelectedTab());
+
+ // by tab instance
+ tabSheet.setSelectedTab(tab3);
+ assertEquals(tab3.getComponent(), tabSheet.getSelectedTab());
+
+ // by index
+ tabSheet.setSelectedTab(0);
+ assertEquals(tab1.getComponent(), tabSheet.getSelectedTab());
+
+ // Should be no-op...
+ tabSheet.setSelectedTab(componentNotInSheet);
+ assertEquals(tab1.getComponent(), tabSheet.getSelectedTab());
+
+ // this as well
+ tabSheet.setSelectedTab(tabNotInSheet);
+ assertEquals(tab1.getComponent(), tabSheet.getSelectedTab());
+
+ // and this
+ tabSheet.setSelectedTab(123);
+ assertEquals(tab1.getComponent(), tabSheet.getSelectedTab());
+ }
+
+ @Test
+ public void replaceComponent() {
+ TabSheet tabSheet = new TabSheet();
+ Label lbl1 = new Label("aaa");
+ Label lbl2 = new Label("bbb");
+ Label lbl3 = new Label("ccc");
+ Label lbl4 = new Label("ddd");
+
+ Tab tab1 = tabSheet.addTab(lbl1);
+ tab1.setCaption("tab1");
+ tab1.setClosable(true);
+ Tab tab2 = tabSheet.addTab(lbl2);
+ tab2.setDescription("description");
+ tab2.setEnabled(false);
+
+ // Replace component not in tabsheet with one already in tabsheet -
+ // should be no-op
+ tabSheet.replaceComponent(lbl3, lbl2);
+ assertEquals(2, tabSheet.getComponentCount());
+ assertSame(tab1, tabSheet.getTab(lbl1));
+ assertSame(tab2, tabSheet.getTab(lbl2));
+ assertNull(tabSheet.getTab(lbl3));
+
+ // Replace component not in tabsheet with one not in tabsheet either
+ // should add lbl4 as last tab
+ tabSheet.replaceComponent(lbl3, lbl4);
+ assertEquals(3, tabSheet.getComponentCount());
+ assertSame(tab1, tabSheet.getTab(lbl1));
+ assertSame(tab2, tabSheet.getTab(lbl2));
+ assertEquals(2, tabSheet.getTabPosition(tabSheet.getTab(lbl4)));
+
+ // Replace component in tabsheet with another
+ // should swap places, tab association should stay the same but tabs
+ // should swap metadata
+ tabSheet.replaceComponent(lbl1, lbl2);
+ assertSame(tab1, tabSheet.getTab(lbl1));
+ assertSame(tab2, tabSheet.getTab(lbl2));
+ assertEquals(false, tab1.isClosable());
+ assertEquals(true, tab2.isClosable());
+ assertEquals(false, tab1.isEnabled());
+ assertEquals(true, tab2.isEnabled());
+ assertEquals("description", tab1.getDescription());
+ assertEquals(null, tab2.getDescription());
+ assertEquals(3, tabSheet.getComponentCount());
+ assertEquals(1, tabSheet.getTabPosition(tabSheet.getTab(lbl1)));
+ assertEquals(0, tabSheet.getTabPosition(tabSheet.getTab(lbl2)));
+
+ // Replace component in tabsheet with one not in tabsheet
+ // should create a new tab instance for the new component, old tab
+ // instance should become unattached
+ // tab metadata should be copied from old to new
+ tabSheet.replaceComponent(lbl1, lbl3);
+ assertEquals(3, tabSheet.getComponentCount());
+ assertNull(tabSheet.getTab(lbl1));
+ assertNull(tab1.getComponent());
+ assertNotNull(tabSheet.getTab(lbl3));
+ assertEquals(false, tabSheet.getTab(lbl3).isEnabled());
+ assertEquals("description", tab1.getDescription());
+ assertEquals(1, tabSheet.getTabPosition(tabSheet.getTab(lbl3)));
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/textfield/TextFieldWithPropertyFormatter.java b/server/tests/src/com/vaadin/tests/server/component/textfield/TextFieldWithPropertyFormatter.java
new file mode 100644
index 0000000000..4bb0177a18
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/textfield/TextFieldWithPropertyFormatter.java
@@ -0,0 +1,108 @@
+package com.vaadin.tests.server.component.textfield;
+
+import java.util.Collections;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.Property;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.data.util.PropertyFormatter;
+import com.vaadin.ui.TextField;
+
+public class TextFieldWithPropertyFormatter extends TestCase {
+
+ private static final String INPUT_VALUE = "foo";
+ private static final String PARSED_VALUE = "BAR";
+ private static final String FORMATTED_VALUE = "FOOBAR";
+ private static final String ORIGINAL_VALUE = "Original";
+ private TextField field;
+ private PropertyFormatter<String> formatter;
+ private ObjectProperty<String> property;
+ private ValueChangeListener listener;
+ private int listenerCalled;
+ private int repainted;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ field = new TextField() {
+ @Override
+ public void markAsDirty() {
+ repainted++;
+ super.markAsDirty();
+ }
+ };
+
+ formatter = new PropertyFormatter<String>() {
+
+ @Override
+ public String parse(String formattedValue) throws Exception {
+ assertEquals(INPUT_VALUE, formattedValue);
+ return PARSED_VALUE;
+ }
+
+ @Override
+ public String format(String value) {
+ return FORMATTED_VALUE;
+ }
+ };
+
+ property = new ObjectProperty<String>(ORIGINAL_VALUE);
+
+ formatter.setPropertyDataSource(property);
+ field.setPropertyDataSource(formatter);
+
+ listener = new Property.ValueChangeListener() {
+
+ @Override
+ public void valueChange(ValueChangeEvent event) {
+ listenerCalled++;
+ assertEquals(1, listenerCalled);
+ assertEquals(FORMATTED_VALUE, event.getProperty().getValue());
+ }
+ };
+
+ field.addListener(listener);
+ listenerCalled = 0;
+ repainted = 0;
+ }
+
+ public void testWithServerApi() {
+ checkInitialState();
+
+ field.setValue(INPUT_VALUE);
+
+ checkEndState();
+
+ }
+
+ private void checkEndState() {
+ assertEquals(1, listenerCalled);
+ // setModified triggers repaint, this is done 2 times. A
+ // ValueChangeEvent triggers the third
+ assertEquals(3, repainted);
+ assertEquals(FORMATTED_VALUE, field.getValue());
+ assertEquals(FORMATTED_VALUE, formatter.getValue());
+ assertEquals(PARSED_VALUE, property.getValue());
+ }
+
+ private void checkInitialState() {
+ assertEquals(ORIGINAL_VALUE, property.getValue());
+ assertEquals(FORMATTED_VALUE, formatter.getValue());
+ assertEquals(FORMATTED_VALUE, field.getValue());
+ }
+
+ public void testWithSimulatedClientSideChange() {
+ checkInitialState();
+
+ field.changeVariables(null,
+ Collections.singletonMap("text", (Object) INPUT_VALUE));
+
+ checkEndState();
+
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/tree/TestHasChildren.java b/server/tests/src/com/vaadin/tests/server/component/tree/TestHasChildren.java
new file mode 100644
index 0000000000..66535d3ffb
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/tree/TestHasChildren.java
@@ -0,0 +1,25 @@
+package com.vaadin.tests.server.component.tree;
+
+import junit.framework.TestCase;
+
+import com.vaadin.ui.Tree;
+
+public class TestHasChildren extends TestCase {
+
+ private Tree tree;
+
+ @Override
+ protected void setUp() {
+ tree = new Tree();
+ tree.addItem("parent");
+ tree.addItem("child");
+ tree.setChildrenAllowed("parent", true);
+ tree.setParent("child", "parent");
+ }
+
+ public void testRemoveChildren() {
+ assertTrue(tree.hasChildren("parent"));
+ tree.removeItem("child");
+ assertFalse(tree.hasChildren("parent"));
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/tree/TestListeners.java b/server/tests/src/com/vaadin/tests/server/component/tree/TestListeners.java
new file mode 100644
index 0000000000..4984cf161b
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/tree/TestListeners.java
@@ -0,0 +1,137 @@
+package com.vaadin.tests.server.component.tree;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import com.vaadin.ui.Tree;
+import com.vaadin.ui.Tree.CollapseEvent;
+import com.vaadin.ui.Tree.CollapseListener;
+import com.vaadin.ui.Tree.ExpandEvent;
+import com.vaadin.ui.Tree.ExpandListener;
+
+public class TestListeners extends TestCase implements ExpandListener,
+ CollapseListener {
+ private int expandCalled;
+ private int collapseCalled;
+ private Object lastExpanded;
+ private Object lastCollapsed;
+
+ @Override
+ protected void setUp() {
+ expandCalled = 0;
+ }
+
+ public void testExpandListener() {
+ Tree tree = createTree(10, 20, false);
+ tree.addListener((ExpandListener) this);
+ List<Object> rootIds = new ArrayList<Object>(tree.rootItemIds());
+
+ assertEquals(10, rootIds.size());
+ assertEquals(10 + 10 * 20 + 10, tree.size());
+
+ // Expanding should send one expand event for the root item id
+ tree.expandItem(rootIds.get(0));
+ assertEquals(1, expandCalled);
+ assertEquals(rootIds.get(0), lastExpanded);
+
+ // Expand should send one event for each expanded item id.
+ // In this case root + child 4
+ expandCalled = 0;
+ tree.expandItemsRecursively(rootIds.get(1));
+ assertEquals(2, expandCalled);
+ List<Object> c = new ArrayList<Object>(tree.getChildren(rootIds.get(1)));
+
+ assertEquals(c.get(4), lastExpanded);
+
+ // Expanding an already expanded item should send no expand event
+ expandCalled = 0;
+ tree.expandItem(rootIds.get(0));
+ assertEquals(0, expandCalled);
+ }
+
+ /**
+ * Creates a tree with "rootItems" roots, each with "children" children,
+ * each with 1 child.
+ *
+ * @param rootItems
+ * @param children
+ * @param expand
+ * @return
+ */
+ private Tree createTree(int rootItems, int children, boolean expand) {
+ Tree tree = new Tree();
+ for (int i = 0; i < rootItems; i++) {
+ String rootId = "root " + i;
+ tree.addItem(rootId);
+ if (expand) {
+ tree.expandItemsRecursively(rootId);
+ } else {
+ tree.collapseItemsRecursively(rootId);
+
+ }
+ for (int j = 0; j < children; j++) {
+ String childId = "child " + i + "/" + j;
+ tree.addItem(childId);
+ tree.setParent(childId, rootId);
+ tree.setChildrenAllowed(childId, false);
+ if (j == 4) {
+ tree.setChildrenAllowed(childId, true);
+ Object grandChildId = tree.addItem();
+ tree.setParent(grandChildId, childId);
+ tree.setChildrenAllowed(grandChildId, false);
+ if (expand) {
+ tree.expandItemsRecursively(childId);
+ } else {
+ tree.collapseItemsRecursively(childId);
+ }
+ }
+ }
+ }
+
+ return tree;
+ }
+
+ public void testCollapseListener() {
+ Tree tree = createTree(7, 15, true);
+ tree.addListener((CollapseListener) this);
+
+ List<Object> rootIds = new ArrayList<Object>(tree.rootItemIds());
+
+ assertEquals(7, rootIds.size());
+ assertEquals(7 + 7 * 15 + 7, tree.size());
+
+ // Expanding should send one expand event for the root item id
+ tree.collapseItem(rootIds.get(0));
+ assertEquals(1, collapseCalled);
+ assertEquals(rootIds.get(0), lastCollapsed);
+
+ // Collapse sends one event for each collapsed node.
+ // In this case root + child 4
+ collapseCalled = 0;
+ tree.collapseItemsRecursively(rootIds.get(1));
+ assertEquals(2, collapseCalled);
+ List<Object> c = new ArrayList<Object>(tree.getChildren(rootIds.get(1)));
+ assertEquals(c.get(4), lastCollapsed);
+
+ // Collapsing an already expanded item should send no expand event
+ collapseCalled = 0;
+ tree.collapseItem(rootIds.get(0));
+ assertEquals(0, collapseCalled);
+ }
+
+ @Override
+ public void nodeExpand(ExpandEvent event) {
+ lastExpanded = event.getItemId();
+ expandCalled++;
+
+ }
+
+ @Override
+ public void nodeCollapse(CollapseEvent event) {
+ lastCollapsed = event.getItemId();
+ collapseCalled++;
+
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/tree/TreeListeners.java b/server/tests/src/com/vaadin/tests/server/component/tree/TreeListeners.java
new file mode 100644
index 0000000000..e14ebe739d
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/tree/TreeListeners.java
@@ -0,0 +1,27 @@
+package com.vaadin.tests.server.component.tree;
+
+import com.vaadin.event.ItemClickEvent;
+import com.vaadin.event.ItemClickEvent.ItemClickListener;
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+import com.vaadin.ui.Tree;
+import com.vaadin.ui.Tree.CollapseEvent;
+import com.vaadin.ui.Tree.CollapseListener;
+import com.vaadin.ui.Tree.ExpandEvent;
+import com.vaadin.ui.Tree.ExpandListener;
+
+public class TreeListeners extends AbstractListenerMethodsTest {
+ public void testExpandListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Tree.class, ExpandEvent.class,
+ ExpandListener.class);
+ }
+
+ public void testItemClickListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Tree.class, ItemClickEvent.class,
+ ItemClickListener.class);
+ }
+
+ public void testCollapseListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Tree.class, CollapseEvent.class,
+ CollapseListener.class);
+ }
+} \ No newline at end of file
diff --git a/server/tests/src/com/vaadin/tests/server/component/treetable/EmptyTreeTable.java b/server/tests/src/com/vaadin/tests/server/component/treetable/EmptyTreeTable.java
new file mode 100644
index 0000000000..535ed8e860
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/treetable/EmptyTreeTable.java
@@ -0,0 +1,13 @@
+package com.vaadin.tests.server.component.treetable;
+
+import junit.framework.TestCase;
+
+import com.vaadin.ui.TreeTable;
+
+public class EmptyTreeTable extends TestCase {
+ public void testLastId() {
+ TreeTable treeTable = new TreeTable();
+
+ assertFalse(treeTable.isLastId(treeTable.getValue()));
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/upload/UploadListeners.java b/server/tests/src/com/vaadin/tests/server/component/upload/UploadListeners.java
new file mode 100644
index 0000000000..265e5382d4
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/upload/UploadListeners.java
@@ -0,0 +1,41 @@
+package com.vaadin.tests.server.component.upload;
+
+import com.vaadin.server.StreamVariable.StreamingProgressEvent;
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+import com.vaadin.ui.Upload;
+import com.vaadin.ui.Upload.FailedEvent;
+import com.vaadin.ui.Upload.FailedListener;
+import com.vaadin.ui.Upload.FinishedEvent;
+import com.vaadin.ui.Upload.FinishedListener;
+import com.vaadin.ui.Upload.ProgressListener;
+import com.vaadin.ui.Upload.StartedEvent;
+import com.vaadin.ui.Upload.StartedListener;
+import com.vaadin.ui.Upload.SucceededEvent;
+import com.vaadin.ui.Upload.SucceededListener;
+
+public class UploadListeners extends AbstractListenerMethodsTest {
+ public void testProgressListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Upload.class, StreamingProgressEvent.class,
+ ProgressListener.class);
+ }
+
+ public void testSucceededListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Upload.class, SucceededEvent.class,
+ SucceededListener.class);
+ }
+
+ public void testStartedListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Upload.class, StartedEvent.class,
+ StartedListener.class);
+ }
+
+ public void testFailedListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Upload.class, FailedEvent.class,
+ FailedListener.class);
+ }
+
+ public void testFinishedListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Upload.class, FinishedEvent.class,
+ FinishedListener.class);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/window/AddRemoveSubWindow.java b/server/tests/src/com/vaadin/tests/server/component/window/AddRemoveSubWindow.java
new file mode 100644
index 0000000000..88bc28bbc8
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/window/AddRemoveSubWindow.java
@@ -0,0 +1,79 @@
+package com.vaadin.tests.server.component.window;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import com.vaadin.Application;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.UI.LegacyWindow;
+import com.vaadin.ui.Window;
+
+public class AddRemoveSubWindow {
+
+ public class TestApp extends Application.LegacyApplication {
+
+ @Override
+ public void init() {
+ LegacyWindow w = new LegacyWindow("Main window");
+ setMainWindow(w);
+ }
+ }
+
+ @Test
+ public void addSubWindow() {
+ TestApp app = new TestApp();
+ app.init();
+ Window subWindow = new Window("Sub window");
+ UI mainWindow = app.getMainWindow();
+
+ mainWindow.addWindow(subWindow);
+ // Added to main window so the parent of the sub window should be the
+ // main window
+ assertEquals(subWindow.getParent(), mainWindow);
+
+ try {
+ mainWindow.addWindow(subWindow);
+ assertTrue("Window.addWindow did not throw the expected exception",
+ false);
+ } catch (IllegalArgumentException e) {
+ // Should throw an exception as it has already been added to the
+ // main window
+ }
+
+ // Try to add the same sub window to another window
+ try {
+ LegacyWindow w = new LegacyWindow();
+ w.addWindow(subWindow);
+ assertTrue("Window.addWindow did not throw the expected exception",
+ false);
+ } catch (IllegalArgumentException e) {
+ // Should throw an exception as it has already been added to the
+ // main window
+ }
+
+ }
+
+ @Test
+ public void removeSubWindow() {
+ TestApp app = new TestApp();
+ app.init();
+ Window subWindow = new Window("Sub window");
+ UI mainWindow = app.getMainWindow();
+ mainWindow.addWindow(subWindow);
+
+ // Added to main window so the parent of the sub window should be the
+ // main window
+ assertEquals(subWindow.getParent(), mainWindow);
+
+ // Parent should still be set
+ assertEquals(subWindow.getParent(), mainWindow);
+
+ // Remove from the main window and assert it has been removed
+ boolean removed = mainWindow.removeWindow(subWindow);
+ assertTrue("Window was not removed correctly", removed);
+ assertNull(subWindow.getParent());
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/window/AttachDetachWindow.java b/server/tests/src/com/vaadin/tests/server/component/window/AttachDetachWindow.java
new file mode 100644
index 0000000000..0fb0765c9f
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/window/AttachDetachWindow.java
@@ -0,0 +1,254 @@
+package com.vaadin.tests.server.component.window;
+
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import com.vaadin.Application;
+import com.vaadin.server.WrappedRequest;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+
+public class AttachDetachWindow {
+
+ private Application testApp = new Application();
+
+ private interface TestContainer {
+ public boolean attachCalled();
+
+ public boolean detachCalled();
+
+ public TestContent getTestContent();
+
+ public Application getApplication();
+ }
+
+ private class TestWindow extends Window implements TestContainer {
+ boolean windowAttachCalled = false;
+ boolean windowDetachCalled = false;
+ private TestContent testContent = new TestContent();;
+
+ TestWindow() {
+ setContent(testContent);
+ }
+
+ @Override
+ public void attach() {
+ super.attach();
+ windowAttachCalled = true;
+ }
+
+ @Override
+ public void detach() {
+ super.detach();
+ windowDetachCalled = true;
+ }
+
+ @Override
+ public boolean attachCalled() {
+ return windowAttachCalled;
+ }
+
+ @Override
+ public boolean detachCalled() {
+ return windowDetachCalled;
+ }
+
+ @Override
+ public TestContent getTestContent() {
+ return testContent;
+ }
+ }
+
+ private class TestContent extends VerticalLayout {
+ boolean contentDetachCalled = false;
+ boolean childDetachCalled = false;
+ boolean contentAttachCalled = false;
+ boolean childAttachCalled = false;
+
+ private Label child = new Label() {
+ @Override
+ public void attach() {
+ super.attach();
+ childAttachCalled = true;
+ }
+
+ @Override
+ public void detach() {
+ super.detach();
+ childDetachCalled = true;
+ }
+ };
+
+ public TestContent() {
+ addComponent(child);
+ }
+
+ @Override
+ public void attach() {
+ super.attach();
+ contentAttachCalled = true;
+ }
+
+ @Override
+ public void detach() {
+ super.detach();
+ contentDetachCalled = true;
+ }
+ }
+
+ private class TestUI extends UI implements TestContainer {
+ boolean rootAttachCalled = false;
+ boolean rootDetachCalled = false;
+ private TestContent testContent = new TestContent();;
+
+ public TestUI() {
+ setContent(testContent);
+ }
+
+ @Override
+ protected void init(WrappedRequest request) {
+ // Do nothing
+ }
+
+ @Override
+ public boolean attachCalled() {
+ return rootAttachCalled;
+ }
+
+ @Override
+ public boolean detachCalled() {
+ return rootDetachCalled;
+ }
+
+ @Override
+ public TestContent getTestContent() {
+ return testContent;
+ }
+
+ @Override
+ public void attach() {
+ super.attach();
+ rootAttachCalled = true;
+ }
+
+ @Override
+ public void detach() {
+ super.detach();
+ rootDetachCalled = true;
+ }
+ }
+
+ TestUI main = new TestUI();
+ TestWindow sub = new TestWindow();
+
+ @Test
+ public void addSubWindowBeforeAttachingMainWindow() {
+ assertUnattached(main);
+ assertUnattached(sub);
+
+ main.addWindow(sub);
+ assertUnattached(main);
+ assertUnattached(sub);
+
+ // attaching main should recurse to sub
+ main.setApplication(testApp);
+ assertAttached(main);
+ assertAttached(sub);
+ }
+
+ @Test
+ public void addSubWindowAfterAttachingMainWindow() {
+ assertUnattached(main);
+ assertUnattached(sub);
+
+ main.setApplication(testApp);
+ assertAttached(main);
+ assertUnattached(sub);
+
+ // main is already attached, so attach should be called for sub
+ main.addWindow(sub);
+ assertAttached(main);
+ assertAttached(sub);
+ }
+
+ @Test
+ public void removeSubWindowBeforeDetachingMainWindow() {
+ main.setApplication(testApp);
+ main.addWindow(sub);
+
+ // sub should be detached when removing from attached main
+ main.removeWindow(sub);
+ assertAttached(main);
+ assertDetached(sub);
+
+ // main detach should recurse to sub
+ main.setApplication(null);
+ assertDetached(main);
+ assertDetached(sub);
+ }
+
+ @Test
+ public void removeSubWindowAfterDetachingMainWindow() {
+ main.setApplication(testApp);
+ main.addWindow(sub);
+
+ // main detach should recurse to sub
+ main.setApplication(null);
+ assertDetached(main);
+ assertDetached(sub);
+
+ main.removeWindow(sub);
+ assertDetached(main);
+ assertDetached(sub);
+ }
+
+ /**
+ * Asserts that win and its children are attached to testApp and their
+ * attach() methods have been called.
+ */
+ private void assertAttached(TestContainer win) {
+ TestContent testContent = win.getTestContent();
+
+ assertTrue("window attach not called", win.attachCalled());
+ assertTrue("window content attach not called",
+ testContent.contentAttachCalled);
+ assertTrue("window child attach not called",
+ testContent.childAttachCalled);
+
+ assertSame("window not attached", win.getApplication(), testApp);
+ assertSame("window content not attached", testContent.getApplication(),
+ testApp);
+ assertSame("window children not attached",
+ testContent.child.getApplication(), testApp);
+ }
+
+ /**
+ * Asserts that win and its children are not attached.
+ */
+ private void assertUnattached(TestContainer win) {
+ assertSame("window not detached", win.getApplication(), null);
+ assertSame("window content not detached", win.getTestContent()
+ .getApplication(), null);
+ assertSame("window children not detached",
+ win.getTestContent().child.getApplication(), null);
+ }
+
+ /**
+ * Asserts that win and its children are unattached and their detach()
+ * methods have been been called.
+ *
+ * @param win
+ */
+ private void assertDetached(TestContainer win) {
+ assertUnattached(win);
+ assertTrue("window detach not called", win.detachCalled());
+ assertTrue("window content detach not called",
+ win.getTestContent().contentDetachCalled);
+ assertTrue("window child detach not called",
+ win.getTestContent().childDetachCalled);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/window/WindowListeners.java b/server/tests/src/com/vaadin/tests/server/component/window/WindowListeners.java
new file mode 100644
index 0000000000..c33871cbd8
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/window/WindowListeners.java
@@ -0,0 +1,34 @@
+package com.vaadin.tests.server.component.window;
+
+import com.vaadin.event.FieldEvents.BlurEvent;
+import com.vaadin.event.FieldEvents.BlurListener;
+import com.vaadin.event.FieldEvents.FocusEvent;
+import com.vaadin.event.FieldEvents.FocusListener;
+import com.vaadin.tests.server.component.AbstractListenerMethodsTest;
+import com.vaadin.ui.Window;
+import com.vaadin.ui.Window.CloseEvent;
+import com.vaadin.ui.Window.CloseListener;
+import com.vaadin.ui.Window.ResizeEvent;
+import com.vaadin.ui.Window.ResizeListener;
+
+public class WindowListeners extends AbstractListenerMethodsTest {
+ public void testFocusListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Window.class, FocusEvent.class,
+ FocusListener.class);
+ }
+
+ public void testBlurListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Window.class, BlurEvent.class,
+ BlurListener.class);
+ }
+
+ public void testResizeListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Window.class, ResizeEvent.class,
+ ResizeListener.class);
+ }
+
+ public void testCloseListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Window.class, CloseEvent.class,
+ CloseListener.class);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/componentcontainer/AbstractIndexedLayoutTest.java b/server/tests/src/com/vaadin/tests/server/componentcontainer/AbstractIndexedLayoutTest.java
new file mode 100644
index 0000000000..e3e743d02a
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/componentcontainer/AbstractIndexedLayoutTest.java
@@ -0,0 +1,84 @@
+package com.vaadin.tests.server.componentcontainer;
+
+import junit.framework.TestCase;
+
+import com.vaadin.ui.Component;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Layout;
+
+public abstract class AbstractIndexedLayoutTest extends TestCase {
+
+ private Layout layout;
+
+ protected abstract Layout createLayout();
+
+ @Override
+ protected void setUp() throws Exception {
+ layout = createLayout();
+ }
+
+ public Layout getLayout() {
+ return layout;
+ }
+
+ public void testAddRemoveComponent() {
+ Label c1 = new Label();
+ Label c2 = new Label();
+
+ layout.addComponent(c1);
+
+ assertEquals(c1, getComponent(0));
+ assertEquals(1, getComponentCount());
+ layout.addComponent(c2);
+ assertEquals(c1, getComponent(0));
+ assertEquals(c2, getComponent(1));
+ assertEquals(2, getComponentCount());
+ layout.removeComponent(c1);
+ assertEquals(c2, getComponent(0));
+ assertEquals(1, getComponentCount());
+ layout.removeComponent(c2);
+ assertEquals(0, getComponentCount());
+ }
+
+ protected abstract int getComponentCount();
+
+ protected abstract Component getComponent(int index);
+
+ protected abstract int getComponentIndex(Component c);
+
+ public void testGetComponentIndex() {
+ Label c1 = new Label();
+ Label c2 = new Label();
+
+ layout.addComponent(c1);
+ assertEquals(0, getComponentIndex(c1));
+ layout.addComponent(c2);
+ assertEquals(0, getComponentIndex(c1));
+ assertEquals(1, getComponentIndex(c2));
+ layout.removeComponent(c1);
+ assertEquals(0, getComponentIndex(c2));
+ layout.removeComponent(c2);
+ assertEquals(-1, getComponentIndex(c2));
+ assertEquals(-1, getComponentIndex(c1));
+ }
+
+ public void testGetComponent() {
+ Label c1 = new Label();
+ Label c2 = new Label();
+
+ layout.addComponent(c1);
+ assertEquals(c1, getComponent(0));
+ layout.addComponent(c2);
+ assertEquals(c1, getComponent(0));
+ assertEquals(c2, getComponent(1));
+ layout.removeComponent(c1);
+ assertEquals(c2, getComponent(0));
+ layout.removeComponent(c2);
+ try {
+ getComponent(0);
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/componentcontainer/AddRemoveComponentTest.java b/server/tests/src/com/vaadin/tests/server/componentcontainer/AddRemoveComponentTest.java
new file mode 100644
index 0000000000..828404bd5a
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/componentcontainer/AddRemoveComponentTest.java
@@ -0,0 +1,40 @@
+package com.vaadin.tests.server.componentcontainer;
+
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import com.vaadin.tests.VaadinClasses;
+import com.vaadin.ui.ComponentContainer;
+import com.vaadin.ui.CustomLayout;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Label;
+
+public class AddRemoveComponentTest extends TestCase {
+
+ public void testRemoveComponentFromWrongContainer()
+ throws InstantiationException, IllegalAccessException {
+ List<Class<? extends ComponentContainer>> containerClasses = VaadinClasses
+ .getComponentContainersSupportingAddRemoveComponent();
+
+ // No default constructor, special case
+ containerClasses.remove(CustomLayout.class);
+ testRemoveComponentFromWrongContainer(new CustomLayout("dummy"));
+
+ for (Class<? extends ComponentContainer> c : containerClasses) {
+ testRemoveComponentFromWrongContainer(c.newInstance());
+ }
+ }
+
+ private void testRemoveComponentFromWrongContainer(
+ ComponentContainer componentContainer) {
+ HorizontalLayout hl = new HorizontalLayout();
+ Label label = new Label();
+ hl.addComponent(label);
+
+ componentContainer.removeComponent(label);
+ assertEquals(
+ "Parent no longer correct for " + componentContainer.getClass(),
+ hl, label.getParent());
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/componentcontainer/CssLayoutTest.java b/server/tests/src/com/vaadin/tests/server/componentcontainer/CssLayoutTest.java
new file mode 100644
index 0000000000..dc9667c38e
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/componentcontainer/CssLayoutTest.java
@@ -0,0 +1,34 @@
+package com.vaadin.tests.server.componentcontainer;
+
+import com.vaadin.ui.Component;
+import com.vaadin.ui.CssLayout;
+import com.vaadin.ui.Layout;
+
+public class CssLayoutTest extends AbstractIndexedLayoutTest {
+
+ @Override
+ protected Layout createLayout() {
+ return new CssLayout();
+ }
+
+ @Override
+ public CssLayout getLayout() {
+ return (CssLayout) super.getLayout();
+ }
+
+ @Override
+ protected Component getComponent(int index) {
+ return getLayout().getComponent(index);
+ }
+
+ @Override
+ protected int getComponentIndex(Component c) {
+ return getLayout().getComponentIndex(c);
+ }
+
+ @Override
+ protected int getComponentCount() {
+ return getLayout().getComponentCount();
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/server/componentcontainer/FormLayoutTest.java b/server/tests/src/com/vaadin/tests/server/componentcontainer/FormLayoutTest.java
new file mode 100644
index 0000000000..71a813d423
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/componentcontainer/FormLayoutTest.java
@@ -0,0 +1,34 @@
+package com.vaadin.tests.server.componentcontainer;
+
+import com.vaadin.ui.Component;
+import com.vaadin.ui.FormLayout;
+import com.vaadin.ui.Layout;
+
+public class FormLayoutTest extends AbstractIndexedLayoutTest {
+
+ @Override
+ protected Layout createLayout() {
+ return new FormLayout();
+ }
+
+ @Override
+ public FormLayout getLayout() {
+ return (FormLayout) super.getLayout();
+ }
+
+ @Override
+ protected Component getComponent(int index) {
+ return getLayout().getComponent(index);
+ }
+
+ @Override
+ protected int getComponentIndex(Component c) {
+ return getLayout().getComponentIndex(c);
+ }
+
+ @Override
+ protected int getComponentCount() {
+ return getLayout().getComponentCount();
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/server/componentcontainer/VerticalLayoutTest.java b/server/tests/src/com/vaadin/tests/server/componentcontainer/VerticalLayoutTest.java
new file mode 100644
index 0000000000..0e3a1d5734
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/componentcontainer/VerticalLayoutTest.java
@@ -0,0 +1,34 @@
+package com.vaadin.tests.server.componentcontainer;
+
+import com.vaadin.ui.Component;
+import com.vaadin.ui.Layout;
+import com.vaadin.ui.VerticalLayout;
+
+public class VerticalLayoutTest extends AbstractIndexedLayoutTest {
+
+ @Override
+ protected Layout createLayout() {
+ return new VerticalLayout();
+ }
+
+ @Override
+ public VerticalLayout getLayout() {
+ return (VerticalLayout) super.getLayout();
+ }
+
+ @Override
+ protected Component getComponent(int index) {
+ return getLayout().getComponent(index);
+ }
+
+ @Override
+ protected int getComponentIndex(Component c) {
+ return getLayout().getComponentIndex(c);
+ }
+
+ @Override
+ protected int getComponentCount() {
+ return getLayout().getComponentCount();
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/server/components/AbstractTestFieldValueChange.java b/server/tests/src/com/vaadin/tests/server/components/AbstractTestFieldValueChange.java
new file mode 100644
index 0000000000..f2de4f3c04
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/components/AbstractTestFieldValueChange.java
@@ -0,0 +1,129 @@
+package com.vaadin.tests.server.components;
+
+import junit.framework.TestCase;
+
+import org.easymock.EasyMock;
+
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.data.Property.ValueChangeNotifier;
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.ui.AbstractField;
+
+/**
+ * Base class for tests for checking that value change listeners for fields are
+ * not called exactly once when they should be, and not at other times.
+ *
+ * Does not check all cases (e.g. properties that do not implement
+ * {@link ValueChangeNotifier}).
+ *
+ * Subclasses should implement {@link #setValue()} and call
+ * <code>super.setValue(AbstractField)</code>. Also, subclasses should typically
+ * override {@link #setValue(AbstractField)} to set the field value via
+ * <code>changeVariables()</code>.
+ */
+public abstract class AbstractTestFieldValueChange<T> extends TestCase {
+
+ private AbstractField<T> field;
+ private ValueChangeListener listener;
+
+ protected void setUp(AbstractField<T> field) throws Exception {
+ this.field = field;
+ listener = EasyMock.createStrictMock(ValueChangeListener.class);
+
+ }
+
+ protected ValueChangeListener getListener() {
+ return listener;
+ }
+
+ /**
+ * Test that listeners are not called when they have been unregistered.
+ */
+ public void testRemoveListener() {
+ getField().setPropertyDataSource(new ObjectProperty<String>(""));
+ getField().setBuffered(false);
+
+ // Expectations and start test
+ listener.valueChange(EasyMock.isA(ValueChangeEvent.class));
+ EasyMock.replay(listener);
+
+ // Add listener and set the value -> should end up in listener once
+ getField().addListener(listener);
+ setValue(getField());
+
+ // Ensure listener was called once
+ EasyMock.verify(listener);
+
+ // Remove the listener and set the value -> should not end up in
+ // listener
+ getField().removeListener(listener);
+ setValue(getField());
+
+ // Ensure listener still has been called only once
+ EasyMock.verify(listener);
+ }
+
+ /**
+ * Common unbuffered case: both writeThrough (auto-commit) and readThrough
+ * are on. Calling commit() should not cause notifications.
+ *
+ * Using the readThrough mode allows changes made to the property value to
+ * be seen in some cases also when there is no notification of value change
+ * from the property.
+ *
+ * Field value change notifications closely mirror value changes of the data
+ * source behind the field.
+ */
+ public void testNonBuffered() {
+ getField().setPropertyDataSource(new ObjectProperty<String>(""));
+ getField().setBuffered(false);
+
+ expectValueChangeFromSetValueNotCommit();
+ }
+
+ /**
+ * Fully buffered use where the data source is neither read nor modified
+ * during editing, and is updated at commit().
+ *
+ * Field value change notifications reflect the buffered value in the field,
+ * not the original data source value changes.
+ */
+ public void testBuffered() {
+ getField().setPropertyDataSource(new ObjectProperty<String>(""));
+ getField().setBuffered(true);
+
+ expectValueChangeFromSetValueNotCommit();
+ }
+
+ protected void expectValueChangeFromSetValueNotCommit() {
+ // Expectations and start test
+ listener.valueChange(EasyMock.isA(ValueChangeEvent.class));
+ EasyMock.replay(listener);
+
+ // Add listener and set the value -> should end up in listener once
+ getField().addListener(listener);
+ setValue(getField());
+
+ // Ensure listener was called once
+ EasyMock.verify(listener);
+
+ // commit
+ getField().commit();
+
+ // Ensure listener was not called again
+ EasyMock.verify(listener);
+ }
+
+ protected AbstractField<T> getField() {
+ return field;
+ }
+
+ /**
+ * Override in subclasses to set value with changeVariables().
+ */
+ protected void setValue(AbstractField<T> field) {
+ field.setValue("newValue");
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/server/components/ComponentAttachDetachListenerTest.java b/server/tests/src/com/vaadin/tests/server/components/ComponentAttachDetachListenerTest.java
new file mode 100644
index 0000000000..3ba1c4c7f1
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/components/ComponentAttachDetachListenerTest.java
@@ -0,0 +1,345 @@
+package com.vaadin.tests.server.components;
+
+import java.util.Iterator;
+
+import junit.framework.TestCase;
+
+import com.vaadin.ui.AbsoluteLayout;
+import com.vaadin.ui.AbsoluteLayout.ComponentPosition;
+import com.vaadin.ui.AbstractOrderedLayout;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.ComponentContainer;
+import com.vaadin.ui.ComponentContainer.ComponentAttachEvent;
+import com.vaadin.ui.ComponentContainer.ComponentAttachListener;
+import com.vaadin.ui.ComponentContainer.ComponentDetachEvent;
+import com.vaadin.ui.ComponentContainer.ComponentDetachListener;
+import com.vaadin.ui.CssLayout;
+import com.vaadin.ui.GridLayout;
+import com.vaadin.ui.GridLayout.Area;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Label;
+
+public class ComponentAttachDetachListenerTest extends TestCase {
+
+ private AbstractOrderedLayout olayout;
+ private GridLayout gridlayout;
+ private AbsoluteLayout absolutelayout;
+ private CssLayout csslayout;
+
+ // General variables
+ private int attachCounter = 0;
+ private Component attachedComponent = null;
+ private ComponentContainer attachTarget = null;
+ private boolean foundInContainer = false;
+
+ private int detachCounter = 0;
+ private Component detachedComponent = null;
+ private ComponentContainer detachedTarget = null;
+
+ // Ordered layout specific variables
+ private int indexOfComponent = -1;
+
+ // Grid layout specific variables
+ private Area componentArea = null;
+
+ // Absolute layout specific variables
+ private ComponentPosition componentPosition = null;
+
+ private class MyAttachListener implements ComponentAttachListener {
+ @Override
+ public void componentAttachedToContainer(ComponentAttachEvent event) {
+ attachCounter++;
+ attachedComponent = event.getAttachedComponent();
+ attachTarget = event.getContainer();
+
+ // Search for component in container (should be found)
+ Iterator<Component> iter = attachTarget.getComponentIterator();
+ while (iter.hasNext()) {
+ if (iter.next() == attachedComponent) {
+ foundInContainer = true;
+ break;
+ }
+ }
+
+ // Get layout specific variables
+ if (attachTarget instanceof AbstractOrderedLayout) {
+ indexOfComponent = ((AbstractOrderedLayout) attachTarget)
+ .getComponentIndex(attachedComponent);
+ } else if (attachTarget instanceof GridLayout) {
+ componentArea = ((GridLayout) attachTarget)
+ .getComponentArea(attachedComponent);
+ } else if (attachTarget instanceof AbsoluteLayout) {
+ componentPosition = ((AbsoluteLayout) attachTarget)
+ .getPosition(attachedComponent);
+ }
+ }
+ }
+
+ private class MyDetachListener implements ComponentDetachListener {
+ @Override
+ public void componentDetachedFromContainer(ComponentDetachEvent event) {
+ detachCounter++;
+ detachedComponent = event.getDetachedComponent();
+ detachedTarget = event.getContainer();
+
+ // Search for component in container (should NOT be found)
+ Iterator<Component> iter = detachedTarget.getComponentIterator();
+ while (iter.hasNext()) {
+ if (iter.next() == detachedComponent) {
+ foundInContainer = true;
+ break;
+ }
+ }
+
+ // Get layout specific variables
+ if (detachedTarget instanceof AbstractOrderedLayout) {
+ indexOfComponent = ((AbstractOrderedLayout) detachedTarget)
+ .getComponentIndex(detachedComponent);
+ } else if (detachedTarget instanceof GridLayout) {
+ componentArea = ((GridLayout) detachedTarget)
+ .getComponentArea(detachedComponent);
+ } else if (detachedTarget instanceof AbsoluteLayout) {
+ componentPosition = ((AbsoluteLayout) detachedTarget)
+ .getPosition(detachedComponent);
+ }
+
+ }
+ }
+
+ private void resetVariables() {
+ // Attach
+ attachCounter = 0;
+ attachedComponent = null;
+ attachTarget = null;
+ foundInContainer = false;
+
+ // Detach
+ detachCounter = 0;
+ detachedComponent = null;
+ detachedTarget = null;
+
+ // Common
+ indexOfComponent = -1;
+ componentArea = null;
+ componentPosition = null;
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ olayout = new HorizontalLayout();
+ olayout.addListener(new MyAttachListener());
+ olayout.addListener(new MyDetachListener());
+
+ gridlayout = new GridLayout();
+ gridlayout.addListener(new MyAttachListener());
+ gridlayout.addListener(new MyDetachListener());
+
+ absolutelayout = new AbsoluteLayout();
+ absolutelayout.addListener(new MyAttachListener());
+ absolutelayout.addListener(new MyDetachListener());
+
+ csslayout = new CssLayout();
+ csslayout.addListener(new MyAttachListener());
+ csslayout.addListener(new MyDetachListener());
+ }
+
+ public void testOrderedLayoutAttachListener() {
+ // Reset state variables
+ resetVariables();
+
+ // Add component -> Should trigger attach listener
+ Component comp = new Label();
+ olayout.addComponent(comp);
+
+ // Attach counter should get incremented
+ assertEquals(1, attachCounter);
+
+ // The attached component should be the label
+ assertSame(comp, attachedComponent);
+
+ // The attached target should be the layout
+ assertSame(olayout, attachTarget);
+
+ // The attached component should be found in the container
+ assertTrue(foundInContainer);
+
+ // The index of the component should not be -1
+ assertFalse(indexOfComponent == -1);
+ }
+
+ public void testOrderedLayoutDetachListener() {
+ // Add a component to detach
+ Component comp = new Label();
+ olayout.addComponent(comp);
+
+ // Reset state variables (since they are set by the attach listener)
+ resetVariables();
+
+ // Detach the component -> triggers the detach listener
+ olayout.removeComponent(comp);
+
+ // Detach counter should get incremented
+ assertEquals(1, detachCounter);
+
+ // The detached component should be the label
+ assertSame(comp, detachedComponent);
+
+ // The detached target should be the layout
+ assertSame(olayout, detachedTarget);
+
+ // The detached component should not be found in the container
+ assertFalse(foundInContainer);
+
+ // The index of the component should be -1
+ assertEquals(-1, indexOfComponent);
+ }
+
+ public void testGridLayoutAttachListener() {
+ // Reset state variables
+ resetVariables();
+
+ // Add component -> Should trigger attach listener
+ Component comp = new Label();
+ gridlayout.addComponent(comp);
+
+ // Attach counter should get incremented
+ assertEquals(1, attachCounter);
+
+ // The attached component should be the label
+ assertSame(comp, attachedComponent);
+
+ // The attached target should be the layout
+ assertSame(gridlayout, attachTarget);
+
+ // The attached component should be found in the container
+ assertTrue(foundInContainer);
+
+ // The grid area should not be null
+ assertNotNull(componentArea);
+ }
+
+ public void testGridLayoutDetachListener() {
+ // Add a component to detach
+ Component comp = new Label();
+ gridlayout.addComponent(comp);
+
+ // Reset state variables (since they are set by the attach listener)
+ resetVariables();
+
+ // Detach the component -> triggers the detach listener
+ gridlayout.removeComponent(comp);
+
+ // Detach counter should get incremented
+ assertEquals(1, detachCounter);
+
+ // The detached component should be the label
+ assertSame(comp, detachedComponent);
+
+ // The detached target should be the layout
+ assertSame(gridlayout, detachedTarget);
+
+ // The detached component should not be found in the container
+ assertFalse(foundInContainer);
+
+ // The grid area should be null
+ assertNull(componentArea);
+ }
+
+ public void testAbsoluteLayoutAttachListener() {
+ // Reset state variables
+ resetVariables();
+
+ // Add component -> Should trigger attach listener
+ Component comp = new Label();
+ absolutelayout.addComponent(comp);
+
+ // Attach counter should get incremented
+ assertEquals(1, attachCounter);
+
+ // The attached component should be the label
+ assertSame(comp, attachedComponent);
+
+ // The attached target should be the layout
+ assertSame(absolutelayout, attachTarget);
+
+ // The attached component should be found in the container
+ assertTrue(foundInContainer);
+
+ // The component position should not be null
+ assertNotNull(componentPosition);
+ }
+
+ public void testAbsoluteLayoutDetachListener() {
+ // Add a component to detach
+ Component comp = new Label();
+ absolutelayout.addComponent(comp);
+
+ // Reset state variables (since they are set by the attach listener)
+ resetVariables();
+
+ // Detach the component -> triggers the detach listener
+ absolutelayout.removeComponent(comp);
+
+ // Detach counter should get incremented
+ assertEquals(1, detachCounter);
+
+ // The detached component should be the label
+ assertSame(comp, detachedComponent);
+
+ // The detached target should be the layout
+ assertSame(absolutelayout, detachedTarget);
+
+ // The detached component should not be found in the container
+ assertFalse(foundInContainer);
+
+ // The component position should be null
+ assertNull(componentPosition);
+ }
+
+ public void testCSSLayoutAttachListener() {
+ // Reset state variables
+ resetVariables();
+
+ // Add component -> Should trigger attach listener
+ Component comp = new Label();
+ csslayout.addComponent(comp);
+
+ // Attach counter should get incremented
+ assertEquals(1, attachCounter);
+
+ // The attached component should be the label
+ assertSame(comp, attachedComponent);
+
+ // The attached target should be the layout
+ assertSame(csslayout, attachTarget);
+
+ // The attached component should be found in the container
+ assertTrue(foundInContainer);
+ }
+
+ public void testCSSLayoutDetachListener() {
+ // Add a component to detach
+ Component comp = new Label();
+ csslayout.addComponent(comp);
+
+ // Reset state variables (since they are set by the attach listener)
+ resetVariables();
+
+ // Detach the component -> triggers the detach listener
+ csslayout.removeComponent(comp);
+
+ // Detach counter should get incremented
+ assertEquals(1, detachCounter);
+
+ // The detached component should be the label
+ assertSame(comp, detachedComponent);
+
+ // The detached target should be the layout
+ assertSame(csslayout, detachedTarget);
+
+ // The detached component should not be found in the container
+ assertFalse(foundInContainer);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/components/TestComboBoxValueChange.java b/server/tests/src/com/vaadin/tests/server/components/TestComboBoxValueChange.java
new file mode 100644
index 0000000000..308889fa33
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/components/TestComboBoxValueChange.java
@@ -0,0 +1,31 @@
+package com.vaadin.tests.server.components;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.vaadin.ui.AbstractField;
+import com.vaadin.ui.ComboBox;
+
+/**
+ * Check that the value change listener for a combo box is triggered exactly
+ * once when setting the value, at the correct time.
+ *
+ * See <a href="http://dev.vaadin.com/ticket/4394">Ticket 4394</a>.
+ */
+public class TestComboBoxValueChange extends
+ AbstractTestFieldValueChange<Object> {
+ @Override
+ protected void setUp() throws Exception {
+ ComboBox combo = new ComboBox();
+ combo.addItem("myvalue");
+ super.setUp(combo);
+ }
+
+ @Override
+ protected void setValue(AbstractField<Object> field) {
+ Map<String, Object> variables = new HashMap<String, Object>();
+ variables.put("selected", new String[] { "myvalue" });
+ ((ComboBox) field).changeVariables(field, variables);
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/server/components/TestGridLayoutLastRowRemoval.java b/server/tests/src/com/vaadin/tests/server/components/TestGridLayoutLastRowRemoval.java
new file mode 100644
index 0000000000..92664917fd
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/components/TestGridLayoutLastRowRemoval.java
@@ -0,0 +1,40 @@
+package com.vaadin.tests.server.components;
+
+import junit.framework.TestCase;
+
+import com.vaadin.ui.GridLayout;
+import com.vaadin.ui.Label;
+
+public class TestGridLayoutLastRowRemoval extends TestCase {
+
+ public void testRemovingLastRow() {
+ GridLayout grid = new GridLayout(2, 1);
+ grid.addComponent(new Label("Col1"));
+ grid.addComponent(new Label("Col2"));
+
+ try {
+ // Removing the last row in the grid
+ grid.removeRow(0);
+ } catch (IllegalArgumentException iae) {
+ // Removing the last row should not throw an
+ // IllegalArgumentException
+ fail("removeRow(0) threw an IllegalArgumentExcetion when removing the last row");
+ }
+
+ // The column amount should be preserved
+ assertEquals(2, grid.getColumns());
+
+ // There should be one row left
+ assertEquals(1, grid.getRows());
+
+ // There should be no component left in the grid layout
+ assertNull("A component should not be left in the layout",
+ grid.getComponent(0, 0));
+ assertNull("A component should not be left in the layout",
+ grid.getComponent(1, 0));
+
+ // The cursor should be in the first cell
+ assertEquals(0, grid.getCursorX());
+ assertEquals(0, grid.getCursorY());
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/components/TestTextFieldValueChange.java b/server/tests/src/com/vaadin/tests/server/components/TestTextFieldValueChange.java
new file mode 100644
index 0000000000..de838e339c
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/components/TestTextFieldValueChange.java
@@ -0,0 +1,126 @@
+package com.vaadin.tests.server.components;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.Assert;
+
+import org.easymock.EasyMock;
+
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.ui.AbstractField;
+import com.vaadin.ui.TextField;
+
+/**
+ * Check that the value change listener for a text field is triggered exactly
+ * once when setting the value, at the correct time.
+ *
+ * See <a href="http://dev.vaadin.com/ticket/4394">Ticket 4394</a>.
+ */
+public class TestTextFieldValueChange extends
+ AbstractTestFieldValueChange<String> {
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp(new TextField());
+ }
+
+ /**
+ * Case where the text field only uses its internal buffer, no external
+ * property data source.
+ */
+ public void testNoDataSource() {
+ getField().setPropertyDataSource(null);
+
+ expectValueChangeFromSetValueNotCommit();
+ }
+
+ @Override
+ protected void setValue(AbstractField<String> field) {
+ Map<String, Object> variables = new HashMap<String, Object>();
+ variables.put("text", "newValue");
+ ((TextField) field).changeVariables(field, variables);
+ }
+
+ /**
+ * Test that field propagates value change events originating from property,
+ * but don't fire value change events twice if value has only changed once.
+ *
+ *
+ * TODO make test field type agnostic (eg. combobox)
+ */
+ public void testValueChangeEventPropagationWithReadThrough() {
+ ObjectProperty<String> property = new ObjectProperty<String>("");
+ getField().setPropertyDataSource(property);
+
+ // defaults, buffering off
+ getField().setBuffered(false);
+
+ // Expectations and start test
+ getListener().valueChange(EasyMock.isA(ValueChangeEvent.class));
+ EasyMock.replay(getListener());
+
+ // Add listener and set the value -> should end up in listener once
+ getField().addListener(getListener());
+
+ property.setValue("Foo");
+
+ // Ensure listener was called once
+ EasyMock.verify(getListener());
+
+ // get value should not fire value change again
+ Object value = getField().getValue();
+ Assert.assertEquals("Foo", value);
+
+ // Ensure listener still has been called only once
+ EasyMock.verify(getListener());
+ }
+
+ /**
+ * Value change events from property should not propagate if read through is
+ * false. Execpt when the property is being set.
+ *
+ * TODO make test field type agnostic (eg. combobox)
+ */
+ public void testValueChangePropagationWithReadThroughOff() {
+ final String initialValue = "initial";
+ ObjectProperty<String> property = new ObjectProperty<String>(
+ initialValue);
+
+ // set buffering
+ getField().setBuffered(true);
+
+ // Value change should only happen once, when setting the property,
+ // further changes via property should not cause value change listener
+ // in field to be notified
+ getListener().valueChange(EasyMock.isA(ValueChangeEvent.class));
+ EasyMock.replay(getListener());
+
+ getField().addListener(getListener());
+ getField().setPropertyDataSource(property);
+
+ // Ensure listener was called once
+ EasyMock.verify(getListener());
+
+ // modify property value, should not fire value change in field as the
+ // read buffering is on (read through == false)
+ property.setValue("Foo");
+
+ // Ensure listener still has been called only once
+ EasyMock.verify(getListener());
+
+ // get value should not fire value change again
+ Object value = getField().getValue();
+
+ // field value should be different from the original value and current
+ // proeprty value
+ boolean isValueEqualToInitial = value.equals(initialValue);
+ Assert.assertTrue(isValueEqualToInitial);
+
+ // Ensure listener still has been called only once
+ EasyMock.verify(getListener());
+
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/server/components/TestWindow.java b/server/tests/src/com/vaadin/tests/server/components/TestWindow.java
new file mode 100644
index 0000000000..12d3a3c8f5
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/components/TestWindow.java
@@ -0,0 +1,92 @@
+package com.vaadin.tests.server.components;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.easymock.EasyMock;
+
+import com.vaadin.ui.UI.LegacyWindow;
+import com.vaadin.ui.Window;
+import com.vaadin.ui.Window.CloseEvent;
+import com.vaadin.ui.Window.CloseListener;
+import com.vaadin.ui.Window.ResizeEvent;
+import com.vaadin.ui.Window.ResizeListener;
+
+public class TestWindow extends TestCase {
+
+ private Window window;
+
+ @Override
+ protected void setUp() throws Exception {
+ window = new Window();
+ new LegacyWindow().addWindow(window);
+ }
+
+ public void testCloseListener() {
+ CloseListener cl = EasyMock.createMock(Window.CloseListener.class);
+
+ // Expectations
+ cl.windowClose(EasyMock.isA(CloseEvent.class));
+
+ // Start actual test
+ EasyMock.replay(cl);
+
+ // Add listener and send a close event -> should end up in listener once
+ window.addListener(cl);
+ sendClose(window);
+
+ // Ensure listener was called once
+ EasyMock.verify(cl);
+
+ // Remove the listener and send close event -> should not end up in
+ // listener
+ window.removeListener(cl);
+ sendClose(window);
+
+ // Ensure listener still has been called only once
+ EasyMock.verify(cl);
+
+ }
+
+ public void testResizeListener() {
+ ResizeListener rl = EasyMock.createMock(Window.ResizeListener.class);
+
+ // Expectations
+ rl.windowResized(EasyMock.isA(ResizeEvent.class));
+
+ // Start actual test
+ EasyMock.replay(rl);
+
+ // Add listener and send a resize event -> should end up in listener
+ // once
+ window.addListener(rl);
+ sendResize(window);
+
+ // Ensure listener was called once
+ EasyMock.verify(rl);
+
+ // Remove the listener and send close event -> should not end up in
+ // listener
+ window.removeListener(rl);
+ sendResize(window);
+
+ // Ensure listener still has been called only once
+ EasyMock.verify(rl);
+
+ }
+
+ private void sendResize(Window window2) {
+ Map<String, Object> variables = new HashMap<String, Object>();
+ variables.put("height", 1234);
+ window.changeVariables(window, variables);
+
+ }
+
+ private static void sendClose(Window window) {
+ Map<String, Object> variables = new HashMap<String, Object>();
+ variables.put("close", true);
+ window.changeVariables(window, variables);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/navigator/ClassBasedViewProviderTest.java b/server/tests/src/com/vaadin/tests/server/navigator/ClassBasedViewProviderTest.java
new file mode 100644
index 0000000000..5db0df4280
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/navigator/ClassBasedViewProviderTest.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2011 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.navigator;
+
+import junit.framework.TestCase;
+
+import com.vaadin.navigator.Navigator.ClassBasedViewProvider;
+import com.vaadin.navigator.View;
+import com.vaadin.ui.Label;
+
+public class ClassBasedViewProviderTest extends TestCase {
+
+ public static class TestView extends Label implements View {
+ public String parameters = null;
+
+ @Override
+ public void navigateTo(String parameters) {
+ this.parameters = parameters;
+ }
+
+ }
+
+ public static class TestView2 extends TestView {
+
+ }
+
+ public void testCreateProviderWithNullName() throws Exception {
+ try {
+ new ClassBasedViewProvider(null, TestView.class);
+ fail("Should not be able to create view provider with null name");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ public void testCreateProviderWithEmptyStringName() throws Exception {
+ new ClassBasedViewProvider("", TestView.class);
+ }
+
+ public void testCreateProviderNullViewClass() throws Exception {
+ try {
+ new ClassBasedViewProvider("test", null);
+ fail("Should not be able to create view provider with null view class");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ public void testViewNameGetter() throws Exception {
+ ClassBasedViewProvider provider1 = new ClassBasedViewProvider("",
+ TestView.class);
+ assertEquals("View name should be empty", "", provider1.getViewName());
+
+ ClassBasedViewProvider provider2 = new ClassBasedViewProvider("test",
+ TestView.class);
+ assertEquals("View name does not match", "test",
+ provider2.getViewName());
+ }
+
+ public void testViewClassGetter() throws Exception {
+ ClassBasedViewProvider provider = new ClassBasedViewProvider("test",
+ TestView.class);
+ assertEquals("Incorrect view class returned by getter", TestView.class,
+ provider.getViewClass());
+ }
+
+ public void testGetViewNameForNullString() throws Exception {
+ ClassBasedViewProvider provider = new ClassBasedViewProvider("test",
+ TestView.class);
+ assertNull("Received view name for null view string",
+ provider.getViewName((String) null));
+ }
+
+ public void testGetViewNameForEmptyString() throws Exception {
+ ClassBasedViewProvider provider1 = new ClassBasedViewProvider("",
+ TestView.class);
+ assertEquals(
+ "Did not find view name for empty view string in a provider with empty string registered",
+ "", provider1.getViewName(""));
+
+ ClassBasedViewProvider provider2 = new ClassBasedViewProvider("test",
+ TestView.class);
+ assertNull(
+ "Found view name for empty view string when none registered",
+ provider2.getViewName(""));
+ }
+
+ public void testGetViewNameWithParameters() throws Exception {
+ ClassBasedViewProvider provider = new ClassBasedViewProvider("test",
+ TestView.class);
+ assertEquals("Incorrect view name found for view string", "test",
+ provider.getViewName("test"));
+ assertEquals(
+ "Incorrect view name found for view string ending with slash",
+ "test", provider.getViewName("test/"));
+ assertEquals(
+ "Incorrect view name found for view string with parameters",
+ "test", provider.getViewName("test/params/are/here"));
+ }
+
+ public void testGetView() throws Exception {
+ ClassBasedViewProvider provider = new ClassBasedViewProvider("test",
+ TestView.class);
+
+ View view = provider.getView("test");
+ assertNotNull("Did not get view from a provider", view);
+ assertEquals("Incorrect view type", TestView.class, view.getClass());
+ }
+
+ public void testGetViewIncorrectViewName() throws Exception {
+ ClassBasedViewProvider provider = new ClassBasedViewProvider("test",
+ TestView.class);
+
+ View view = provider.getView("test2");
+ assertNull("Got view from a provider for incorrect view name", view);
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/server/navigator/NavigatorTest.java b/server/tests/src/com/vaadin/tests/server/navigator/NavigatorTest.java
new file mode 100644
index 0000000000..595ddb95db
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/navigator/NavigatorTest.java
@@ -0,0 +1,575 @@
+/*
+ * Copyright 2011 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.navigator;
+
+import java.util.LinkedList;
+
+import junit.framework.TestCase;
+
+import org.easymock.EasyMock;
+import org.easymock.IMocksControl;
+
+import com.vaadin.navigator.FragmentManager;
+import com.vaadin.navigator.Navigator;
+import com.vaadin.navigator.View;
+import com.vaadin.navigator.ViewChangeListener;
+import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
+import com.vaadin.navigator.ViewDisplay;
+import com.vaadin.navigator.ViewProvider;
+import com.vaadin.tests.server.navigator.ClassBasedViewProviderTest.TestView;
+import com.vaadin.tests.server.navigator.ClassBasedViewProviderTest.TestView2;
+
+public class NavigatorTest extends TestCase {
+
+ // TODO test internal parameters (and absence of them)
+ // TODO test listeners blocking navigation, multiple listeners
+
+ public static class NullDisplay implements ViewDisplay {
+ @Override
+ public void showView(View view) {
+ // do nothing
+ }
+ }
+
+ public static class NullFragmentManager implements FragmentManager {
+ @Override
+ public String getFragment() {
+ return null;
+ }
+
+ @Override
+ public void setFragment(String fragment) {
+ // do nothing
+ }
+ }
+
+ public static class TestDisplay implements ViewDisplay {
+ private View currentView;
+
+ @Override
+ public void showView(View view) {
+ currentView = view;
+ }
+
+ public View getCurrentView() {
+ return currentView;
+ }
+ }
+
+ public static class TestNavigator extends Navigator {
+ public TestNavigator() {
+ super(new NullFragmentManager(), new TestDisplay());
+ }
+
+ public View getView(String viewAndParameters) {
+ navigateTo(viewAndParameters);
+ return ((TestDisplay) getDisplay()).getCurrentView();
+ }
+ }
+
+ public static class ViewChangeTestListener implements ViewChangeListener {
+ private final LinkedList<ViewChangeEvent> referenceEvents = new LinkedList<ViewChangeListener.ViewChangeEvent>();
+ private final LinkedList<Boolean> referenceIsCheck = new LinkedList<Boolean>();
+ private final LinkedList<Boolean> checkReturnValues = new LinkedList<Boolean>();
+
+ public void addExpectedIsViewChangeAllowed(ViewChangeEvent event,
+ boolean returnValue) {
+ referenceIsCheck.add(true);
+ referenceEvents.add(event);
+ checkReturnValues.add(returnValue);
+ }
+
+ public void addExpectedNavigatorViewChange(ViewChangeEvent event) {
+ referenceIsCheck.add(false);
+ referenceEvents.add(event);
+ }
+
+ public boolean isReady() {
+ return referenceEvents.isEmpty();
+ }
+
+ public boolean equalsReferenceEvent(ViewChangeEvent event,
+ ViewChangeEvent reference) {
+ if (event == null) {
+ return false;
+ }
+ if (reference.getNavigator() != event.getNavigator()) {
+ return false;
+ }
+ if (reference.getOldView() != event.getOldView()) {
+ return false;
+ }
+ if (reference.getNewView() != event.getNewView()) {
+ return false;
+ }
+ if (!stringEquals(reference.getViewName(), event.getViewName())) {
+ return false;
+ }
+ if (!stringEquals(reference.getFragmentParameters(),
+ event.getFragmentParameters())) {
+ return false;
+ }
+ return true;
+ }
+
+ private static boolean stringEquals(String string1, String string2) {
+ if (string1 == null) {
+ return string2 == null;
+ } else {
+ return string1.equals(string2);
+ }
+ }
+
+ @Override
+ public boolean isViewChangeAllowed(ViewChangeEvent event) {
+ if (referenceEvents.isEmpty()) {
+ fail("Unexpected call to isViewChangeAllowed()");
+ }
+ ViewChangeEvent reference = referenceEvents.remove();
+ Boolean isCheck = referenceIsCheck.remove();
+ if (!isCheck) {
+ fail("Expected navigatorViewChanged(), received isViewChangeAllowed()");
+ }
+ // here to make sure exactly the correct values are removed from
+ // each queue
+ Boolean returnValue = checkReturnValues.remove();
+ if (!equalsReferenceEvent(event, reference)) {
+ fail("View change event does not match reference event");
+ }
+ return returnValue;
+ }
+
+ @Override
+ public void navigatorViewChanged(ViewChangeEvent event) {
+ if (referenceEvents.isEmpty()) {
+ fail("Unexpected call to navigatorViewChanged()");
+ }
+ ViewChangeEvent reference = referenceEvents.remove();
+ Boolean isCheck = referenceIsCheck.remove();
+ if (isCheck) {
+ fail("Expected isViewChangeAllowed(), received navigatorViewChanged()");
+ }
+ if (!equalsReferenceEvent(event, reference)) {
+ fail("View change event does not match reference event");
+ }
+ }
+ }
+
+ public void testBasicNavigation() {
+ IMocksControl control = EasyMock.createControl();
+ FragmentManager manager = control.createMock(FragmentManager.class);
+ ViewDisplay display = control.createMock(ViewDisplay.class);
+ ViewProvider provider = control.createMock(ViewProvider.class);
+ View view1 = control.createMock(View.class);
+ View view2 = control.createMock(View.class);
+
+ // prepare mocks: what to expect
+ EasyMock.expect(provider.getViewName("test1")).andReturn("test1");
+ EasyMock.expect(provider.getView("test1")).andReturn(view1);
+ EasyMock.expect(manager.getFragment()).andReturn("");
+ view1.navigateTo("");
+ display.showView(view1);
+ manager.setFragment("test1");
+
+ EasyMock.expect(provider.getViewName("test2/")).andReturn("test2");
+ EasyMock.expect(provider.getView("test2")).andReturn(view2);
+ EasyMock.expect(manager.getFragment()).andReturn("view1");
+ view2.navigateTo("");
+ display.showView(view2);
+ manager.setFragment("test2");
+
+ EasyMock.expect(provider.getViewName("test1/params"))
+ .andReturn("test1");
+ EasyMock.expect(provider.getView("test1")).andReturn(view1);
+ EasyMock.expect(manager.getFragment()).andReturn("view2");
+ view1.navigateTo("params");
+ display.showView(view1);
+ manager.setFragment("test1/params");
+
+ control.replay();
+
+ // create and test navigator
+ Navigator navigator = new Navigator(manager, display);
+ navigator.addProvider(provider);
+
+ navigator.navigateTo("test1");
+ navigator.navigateTo("test2/");
+ navigator.navigateTo("test1/params");
+ }
+
+ public void testMainView() {
+ IMocksControl control = EasyMock.createControl();
+ FragmentManager manager = control.createMock(FragmentManager.class);
+ ViewDisplay display = control.createMock(ViewDisplay.class);
+ ViewProvider provider = control.createMock(ViewProvider.class);
+ View view1 = control.createMock(View.class);
+ View view2 = control.createMock(View.class);
+
+ // prepare mocks: what to expect
+ EasyMock.expect(provider.getViewName("test2")).andReturn("test2");
+ EasyMock.expect(provider.getView("test2")).andReturn(view2);
+ EasyMock.expect(manager.getFragment()).andReturn("view1");
+ view2.navigateTo("");
+ display.showView(view2);
+ manager.setFragment("test2");
+
+ EasyMock.expect(provider.getViewName("")).andReturn("test1");
+ EasyMock.expect(provider.getView("test1")).andReturn(view1);
+ EasyMock.expect(manager.getFragment()).andReturn("");
+ view1.navigateTo("");
+ display.showView(view1);
+ manager.setFragment("test1");
+
+ EasyMock.expect(provider.getViewName("test1/params"))
+ .andReturn("test1");
+ EasyMock.expect(provider.getView("test1")).andReturn(view1);
+ EasyMock.expect(manager.getFragment()).andReturn("view2");
+ view1.navigateTo("params");
+ display.showView(view1);
+ manager.setFragment("test1/params");
+
+ control.replay();
+
+ // create and test navigator
+ Navigator navigator = new Navigator(manager, display);
+ navigator.addProvider(provider);
+
+ navigator.navigateTo("test2");
+ navigator.navigateTo("");
+ navigator.navigateTo("test1/params");
+ }
+
+ public void testListeners() {
+ IMocksControl control = EasyMock.createControl();
+ FragmentManager manager = control.createMock(FragmentManager.class);
+ ViewDisplay display = control.createMock(ViewDisplay.class);
+ ViewProvider provider = control.createMock(ViewProvider.class);
+ View view1 = control.createMock(View.class);
+ View view2 = control.createMock(View.class);
+ ViewChangeTestListener listener = new ViewChangeTestListener();
+
+ // create navigator to test
+ Navigator navigator = new Navigator(manager, display);
+
+ // prepare mocks: what to expect
+ EasyMock.expect(provider.getViewName("test1")).andReturn("test1");
+ EasyMock.expect(provider.getView("test1")).andReturn(view1);
+ ViewChangeEvent event1 = new ViewChangeEvent(navigator, null, view1,
+ "test1", "");
+ listener.addExpectedIsViewChangeAllowed(event1, true);
+ EasyMock.expect(manager.getFragment()).andReturn("");
+ view1.navigateTo("");
+ display.showView(view1);
+ manager.setFragment("test1");
+ listener.addExpectedNavigatorViewChange(event1);
+
+ EasyMock.expect(provider.getViewName("test2")).andReturn("test2");
+ EasyMock.expect(provider.getView("test2")).andReturn(view2);
+ ViewChangeEvent event2 = new ViewChangeEvent(navigator, view1, view2,
+ "test2", "");
+ listener.addExpectedIsViewChangeAllowed(event2, true);
+ EasyMock.expect(manager.getFragment()).andReturn("view1");
+ view2.navigateTo("");
+ display.showView(view2);
+ manager.setFragment("test2");
+ listener.addExpectedNavigatorViewChange(event2);
+
+ control.replay();
+
+ // test navigator
+ navigator.addProvider(provider);
+ navigator.addListener(listener);
+
+ navigator.navigateTo("test1");
+ navigator.navigateTo("test2");
+
+ if (!listener.isReady()) {
+ fail("Missing listener calls");
+ }
+ }
+
+ public void testBlockNavigation() {
+ IMocksControl control = EasyMock.createControl();
+ FragmentManager manager = control.createMock(FragmentManager.class);
+ ViewDisplay display = control.createMock(ViewDisplay.class);
+ ViewProvider provider = control.createMock(ViewProvider.class);
+ View view1 = control.createMock(View.class);
+ View view2 = control.createMock(View.class);
+ ViewChangeTestListener listener1 = new ViewChangeTestListener();
+ ViewChangeTestListener listener2 = new ViewChangeTestListener();
+
+ Navigator navigator = new Navigator(manager, display);
+
+ // prepare mocks: what to expect
+ // first listener blocks first view change
+ EasyMock.expect(provider.getViewName("test1")).andReturn("test1");
+ EasyMock.expect(provider.getView("test1")).andReturn(view1);
+ EasyMock.expect(manager.getFragment()).andReturn("");
+ ViewChangeEvent event1 = new ViewChangeEvent(navigator, null, view1,
+ "test1", "");
+ listener1.addExpectedIsViewChangeAllowed(event1, false);
+
+ // second listener blocks second view change
+ EasyMock.expect(provider.getViewName("test1/test")).andReturn("test1");
+ EasyMock.expect(provider.getView("test1")).andReturn(view1);
+ EasyMock.expect(manager.getFragment()).andReturn("");
+ ViewChangeEvent event2 = new ViewChangeEvent(navigator, null, view1,
+ "test1", "test");
+ listener1.addExpectedIsViewChangeAllowed(event2, true);
+ listener2.addExpectedIsViewChangeAllowed(event2, false);
+
+ // both listeners allow view change
+ EasyMock.expect(provider.getViewName("test1/bar")).andReturn("test1");
+ EasyMock.expect(provider.getView("test1")).andReturn(view1);
+ EasyMock.expect(manager.getFragment()).andReturn("");
+ ViewChangeEvent event3 = new ViewChangeEvent(navigator, null, view1,
+ "test1", "bar");
+ listener1.addExpectedIsViewChangeAllowed(event3, true);
+ listener2.addExpectedIsViewChangeAllowed(event3, true);
+ view1.navigateTo("bar");
+ display.showView(view1);
+ manager.setFragment("test1/bar");
+ listener1.addExpectedNavigatorViewChange(event3);
+ listener2.addExpectedNavigatorViewChange(event3);
+
+ // both listeners allow view change from non-null view
+ EasyMock.expect(provider.getViewName("test2")).andReturn("test2");
+ EasyMock.expect(provider.getView("test2")).andReturn(view2);
+ EasyMock.expect(manager.getFragment()).andReturn("view1");
+ ViewChangeEvent event4 = new ViewChangeEvent(navigator, view1, view2,
+ "test2", "");
+ listener1.addExpectedIsViewChangeAllowed(event4, true);
+ listener2.addExpectedIsViewChangeAllowed(event4, true);
+ view2.navigateTo("");
+ display.showView(view2);
+ manager.setFragment("test2");
+ listener1.addExpectedNavigatorViewChange(event4);
+ listener2.addExpectedNavigatorViewChange(event4);
+
+ control.replay();
+
+ // test navigator
+ navigator.addProvider(provider);
+ navigator.addListener(listener1);
+ navigator.addListener(listener2);
+
+ navigator.navigateTo("test1");
+ navigator.navigateTo("test1/test");
+ navigator.navigateTo("test1/bar");
+ navigator.navigateTo("test2");
+
+ if (!listener1.isReady()) {
+ fail("Missing listener calls for listener1");
+ }
+ if (!listener2.isReady()) {
+ fail("Missing listener calls for listener2");
+ }
+ }
+
+ public void testAddViewInstance() throws Exception {
+ View view = new TestView();
+
+ TestNavigator navigator = new TestNavigator();
+
+ navigator.addView("test", view);
+
+ assertEquals("Registered view instance not returned by navigator",
+ view, navigator.getView("test"));
+ }
+
+ public void testAddViewInstanceSameName() throws Exception {
+ View view1 = new TestView();
+ View view2 = new TestView2();
+
+ TestNavigator navigator = new TestNavigator();
+
+ navigator.addView("test", view1);
+ navigator.addView("test", view2);
+
+ assertEquals(
+ "Adding second view with same name should override previous view",
+ view2, navigator.getView("test"));
+ }
+
+ public void testAddViewClass() throws Exception {
+ TestNavigator navigator = new TestNavigator();
+
+ navigator.addView("test", TestView.class);
+
+ View view = navigator.getView("test");
+ assertNotNull("Received null view", view);
+ assertEquals("Received incorrect type of view", TestView.class,
+ view.getClass());
+ }
+
+ public void testAddViewClassSameName() throws Exception {
+ TestNavigator navigator = new TestNavigator();
+
+ navigator.addView("test", TestView.class);
+ navigator.addView("test", TestView2.class);
+
+ assertEquals(
+ "Adding second view class with same name should override previous view",
+ TestView2.class, navigator.getView("test").getClass());
+ }
+
+ public void testAddViewInstanceAndClassSameName() throws Exception {
+ TestNavigator navigator = new TestNavigator();
+
+ navigator.addView("test", TestView.class);
+ TestView2 view2 = new TestView2();
+ navigator.addView("test", view2);
+
+ assertEquals(
+ "Adding second view class with same name should override previous view",
+ view2, navigator.getView("test"));
+
+ navigator.addView("test", TestView.class);
+
+ assertEquals(
+ "Adding second view class with same name should override previous view",
+ TestView.class, navigator.getView("test").getClass());
+ }
+
+ public void testAddViewWithNullName() throws Exception {
+ Navigator navigator = new Navigator(new NullFragmentManager(),
+ new NullDisplay());
+
+ try {
+ navigator.addView(null, new TestView());
+ fail("addView() accepted null view name");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ navigator.addView(null, TestView.class);
+ fail("addView() accepted null view name");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ public void testAddViewWithNullInstance() throws Exception {
+ Navigator navigator = new Navigator(new NullFragmentManager(),
+ new NullDisplay());
+
+ try {
+ navigator.addView("test", (View) null);
+ fail("addView() accepted null view instance");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ public void testAddViewWithNullClass() throws Exception {
+ Navigator navigator = new Navigator(new NullFragmentManager(),
+ new NullDisplay());
+
+ try {
+ navigator.addView("test", (Class<View>) null);
+ fail("addView() accepted null view class");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ public void testRemoveViewInstance() throws Exception {
+ View view = new TestView();
+
+ TestNavigator navigator = new TestNavigator();
+
+ navigator.addView("test", view);
+ navigator.removeView("test");
+
+ assertNull("View not removed", navigator.getView("test"));
+ }
+
+ public void testRemoveViewInstanceNothingElse() throws Exception {
+ View view = new TestView();
+ View view2 = new TestView2();
+
+ TestNavigator navigator = new TestNavigator();
+
+ navigator.addView("test", view);
+ navigator.addView("test2", view2);
+ navigator.removeView("test");
+
+ assertEquals("Removed extra views", view2, navigator.getView("test2"));
+ }
+
+ public void testRemoveViewClass() throws Exception {
+ TestNavigator navigator = new TestNavigator();
+
+ navigator.addView("test", TestView.class);
+ navigator.removeView("test");
+
+ assertNull("View not removed", navigator.getView("test"));
+ }
+
+ public void testRemoveViewClassNothingElse() throws Exception {
+ TestNavigator navigator = new TestNavigator();
+
+ navigator.addView("test", TestView.class);
+ navigator.addView("test2", TestView2.class);
+ navigator.removeView("test");
+
+ assertEquals("Removed extra views", TestView2.class,
+ navigator.getView("test2").getClass());
+ }
+
+ public void testGetViewNestedNames() throws Exception {
+ TestNavigator navigator = new TestNavigator();
+
+ navigator.addView("test/subview", TestView2.class);
+ navigator.addView("test", TestView.class);
+
+ assertEquals("Incorrect view name found for subview string",
+ TestView2.class, navigator.getView("test/subview").getClass());
+ assertEquals(
+ "Incorrect view name found for subview string with empty parameters",
+ TestView2.class, navigator.getView("test/subview/").getClass());
+ assertEquals(
+ "Incorrect view name found for subview string with parameters",
+ TestView2.class, navigator.getView("test/subview/parameters")
+ .getClass());
+ assertEquals("Incorrect view name found for top level view string",
+ TestView.class, navigator.getView("test").getClass());
+ assertEquals(
+ "Incorrect view name found for top level view string with empty parameters",
+ TestView.class, navigator.getView("test/").getClass());
+ assertEquals(
+ "Incorrect view name found for top level view string with parameters starting like subview name",
+ TestView.class, navigator.getView("test/subviewnothere")
+ .getClass());
+ }
+
+ public void testGetViewLongestPrefixOrder() throws Exception {
+ TestNavigator navigator = new TestNavigator();
+
+ navigator.addView("test/subview", TestView2.class);
+ navigator.addView("test", TestView.class);
+
+ assertEquals("Incorrect view name found", TestView.class, navigator
+ .getView("test").getClass());
+
+ // other order
+
+ TestNavigator navigator2 = new TestNavigator();
+
+ navigator2.addView("test", TestView.class);
+ navigator2.addView("test/subview", TestView2.class);
+
+ assertEquals("Incorrect view name found", TestView.class, navigator2
+ .getView("test").getClass());
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/navigator/UriFragmentManagerTest.java b/server/tests/src/com/vaadin/tests/server/navigator/UriFragmentManagerTest.java
new file mode 100644
index 0000000000..18ed52cc2a
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/navigator/UriFragmentManagerTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2011 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.navigator;
+
+import junit.framework.TestCase;
+
+import org.easymock.EasyMock;
+import org.easymock.IMocksControl;
+
+import com.vaadin.navigator.Navigator;
+import com.vaadin.navigator.Navigator.UriFragmentManager;
+import com.vaadin.server.Page;
+import com.vaadin.server.Page.FragmentChangedEvent;
+
+public class UriFragmentManagerTest extends TestCase {
+
+ public void testGetSetFragment() {
+ Page page = EasyMock.createMock(Page.class);
+ UriFragmentManager manager = new UriFragmentManager(page, null);
+
+ // prepare mock
+ EasyMock.expect(page.getFragment()).andReturn("");
+ page.setFragment("test", false);
+ EasyMock.expect(page.getFragment()).andReturn("test");
+ EasyMock.replay(page);
+
+ // test manager using the mock
+ assertEquals("Incorrect fragment value", "", manager.getFragment());
+ manager.setFragment("test");
+ assertEquals("Incorrect fragment value", "test", manager.getFragment());
+ }
+
+ public void testListener() {
+ // create mocks
+ IMocksControl control = EasyMock.createControl();
+ Navigator navigator = control.createMock(Navigator.class);
+ Page page = control.createMock(Page.class);
+
+ UriFragmentManager manager = new UriFragmentManager(page, navigator);
+
+ EasyMock.expect(page.getFragment()).andReturn("test");
+ navigator.navigateTo("test");
+ control.replay();
+
+ FragmentChangedEvent event = page.new FragmentChangedEvent(page,
+ "oldtest");
+ manager.fragmentChanged(event);
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/validation/RangeValidatorTest.java b/server/tests/src/com/vaadin/tests/server/validation/RangeValidatorTest.java
new file mode 100644
index 0000000000..e3320b8699
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/validation/RangeValidatorTest.java
@@ -0,0 +1,52 @@
+package com.vaadin.tests.server.validation;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.validator.IntegerRangeValidator;
+
+public class RangeValidatorTest extends TestCase {
+
+ // This test uses IntegerRangeValidator for simplicity.
+ // IntegerRangeValidator contains no code so we really are testing
+ // RangeValidator
+ public void testMinValueNonInclusive() {
+ IntegerRangeValidator iv = new IntegerRangeValidator("Failed", 0, 10);
+ iv.setMinValueIncluded(false);
+ assertFalse(iv.isValid(0));
+ assertTrue(iv.isValid(10));
+ assertFalse(iv.isValid(11));
+ assertFalse(iv.isValid(-1));
+ }
+
+ public void testMinMaxValuesInclusive() {
+ IntegerRangeValidator iv = new IntegerRangeValidator("Failed", 0, 10);
+ assertTrue(iv.isValid(0));
+ assertTrue(iv.isValid(1));
+ assertTrue(iv.isValid(10));
+ assertFalse(iv.isValid(11));
+ assertFalse(iv.isValid(-1));
+ }
+
+ public void testMaxValueNonInclusive() {
+ IntegerRangeValidator iv = new IntegerRangeValidator("Failed", 0, 10);
+ iv.setMaxValueIncluded(false);
+ assertTrue(iv.isValid(0));
+ assertTrue(iv.isValid(9));
+ assertFalse(iv.isValid(10));
+ assertFalse(iv.isValid(11));
+ assertFalse(iv.isValid(-1));
+ }
+
+ public void testMinMaxValuesNonInclusive() {
+ IntegerRangeValidator iv = new IntegerRangeValidator("Failed", 0, 10);
+ iv.setMinValueIncluded(false);
+ iv.setMaxValueIncluded(false);
+
+ assertFalse(iv.isValid(0));
+ assertTrue(iv.isValid(1));
+ assertTrue(iv.isValid(9));
+ assertFalse(iv.isValid(10));
+ assertFalse(iv.isValid(11));
+ assertFalse(iv.isValid(-1));
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/validation/TestBeanValidation.java b/server/tests/src/com/vaadin/tests/server/validation/TestBeanValidation.java
new file mode 100644
index 0000000000..8f6928fc35
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/validation/TestBeanValidation.java
@@ -0,0 +1,57 @@
+package com.vaadin.tests.server.validation;
+
+import org.junit.Test;
+
+import com.vaadin.data.Validator.InvalidValueException;
+import com.vaadin.data.validator.BeanValidator;
+import com.vaadin.tests.data.bean.BeanToValidate;
+
+public class TestBeanValidation {
+ @Test(expected = InvalidValueException.class)
+ public void testBeanValidationNull() {
+ BeanValidator validator = new BeanValidator(BeanToValidate.class,
+ "firstname");
+ validator.validate(null);
+ }
+
+ @Test(expected = InvalidValueException.class)
+ public void testBeanValidationStringTooShort() {
+ BeanValidator validator = new BeanValidator(BeanToValidate.class,
+ "firstname");
+ validator.validate("aa");
+ }
+
+ @Test
+ public void testBeanValidationStringOk() {
+ BeanValidator validator = new BeanValidator(BeanToValidate.class,
+ "firstname");
+ validator.validate("aaa");
+ }
+
+ @Test(expected = InvalidValueException.class)
+ public void testBeanValidationIntegerTooSmall() {
+ BeanValidator validator = new BeanValidator(BeanToValidate.class, "age");
+ validator.validate(17);
+ }
+
+ @Test
+ public void testBeanValidationIntegerOk() {
+ BeanValidator validator = new BeanValidator(BeanToValidate.class, "age");
+ validator.validate(18);
+ }
+
+ @Test(expected = InvalidValueException.class)
+ public void testBeanValidationTooManyDigits() {
+ BeanValidator validator = new BeanValidator(BeanToValidate.class,
+ "decimals");
+ validator.validate("1234.567");
+ }
+
+ @Test
+ public void testBeanValidationDigitsOk() {
+ BeanValidator validator = new BeanValidator(BeanToValidate.class,
+ "decimals");
+ validator.validate("123.45");
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/server/validation/TestReadOnlyValidation.java b/server/tests/src/com/vaadin/tests/server/validation/TestReadOnlyValidation.java
new file mode 100644
index 0000000000..e37b97e02c
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/validation/TestReadOnlyValidation.java
@@ -0,0 +1,17 @@
+package com.vaadin.tests.server.validation;
+
+import org.junit.Test;
+
+import com.vaadin.data.validator.IntegerValidator;
+import com.vaadin.ui.TextField;
+
+public class TestReadOnlyValidation {
+
+ @Test
+ public void testIntegerValidation() {
+ TextField field = new TextField();
+ field.addValidator(new IntegerValidator("Enter a Valid Number"));
+ field.setValue(String.valueOf(10));
+ field.validate();
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/util/GraphVizClassHierarchyCreator.java b/server/tests/src/com/vaadin/tests/util/GraphVizClassHierarchyCreator.java
new file mode 100644
index 0000000000..9e791500b0
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/util/GraphVizClassHierarchyCreator.java
@@ -0,0 +1,149 @@
+package com.vaadin.tests.util;
+
+import java.lang.reflect.Modifier;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import com.vaadin.tests.VaadinClasses;
+
+public class GraphVizClassHierarchyCreator {
+
+ public static void main(String[] args) {
+ String gv = getGraphVizHierarchy((List) VaadinClasses.getComponents(),
+ "com.vaadin");
+ System.out.println(gv);
+ }
+
+ private static String getGraphVizHierarchy(List<Class> classes,
+ String packageToInclude) {
+ boolean includeInterfaces = false;
+
+ StringBuilder header = new StringBuilder();
+ header.append("digraph finite_state_machine {\n"
+ + " rankdir=BT;\n" + " dpi=\"150\";\n"
+ + " ratio=\"0.25\";\n");
+
+ StringBuilder sb = new StringBuilder();
+
+ Set<Class> classesAndParents = new HashSet<Class>();
+ for (Class<?> cls : classes) {
+ addClassAndParents(classesAndParents, cls, packageToInclude);
+ }
+
+ Set<Class> interfaces = new HashSet<Class>();
+ for (Object cls : classesAndParents.toArray()) {
+ for (Class<?> c : ((Class) cls).getInterfaces()) {
+ addClassAndParentInterfaces(classesAndParents, c,
+ packageToInclude);
+ }
+ }
+
+ for (Class<?> c : classesAndParents) {
+ appendClass(sb, c, c.getSuperclass(), packageToInclude,
+ includeInterfaces);
+ for (Class ci : c.getInterfaces()) {
+ appendClass(sb, c, ci, packageToInclude, includeInterfaces);
+ }
+ }
+
+ header.append(" node [shape = ellipse, style=\"dotted\"] ");
+ for (Class c : classesAndParents) {
+ if (!c.isInterface() && Modifier.isAbstract(c.getModifiers())) {
+ header.append(c.getSimpleName() + " ");
+ }
+ }
+ if (includeInterfaces) {
+ System.out.print(" node [shape = ellipse, style=\"solid\"] ");
+ for (Class c : classesAndParents) {
+ if (c.isInterface()) {
+ header.append(c.getSimpleName() + " ");
+ }
+ }
+ header.append(";\n");
+ }
+ header.append(";\n");
+ header.append(" node [shape = rectangle, style=\"solid\"];\n");
+ return header.toString() + sb.toString() + "}";
+ }
+
+ private static void addClassAndParents(Set<Class> classesAndParents,
+ Class<?> cls, String packageToInclude) {
+
+ if (cls == null) {
+ return;
+ }
+
+ if (classesAndParents.contains(cls)) {
+ return;
+ }
+
+ if (!cls.getPackage().getName().startsWith(packageToInclude)) {
+ return;
+ }
+
+ classesAndParents.add(cls);
+ addClassAndParents(classesAndParents, cls.getSuperclass(),
+ packageToInclude);
+
+ }
+
+ private static void addClassAndParentInterfaces(
+ Set<Class> classesAndParents, Class<?> cls, String packageToInclude) {
+
+ if (cls == null) {
+ return;
+ }
+
+ if (classesAndParents.contains(cls)) {
+ return;
+ }
+
+ if (!cls.getPackage().getName().startsWith(packageToInclude)) {
+ return;
+ }
+
+ classesAndParents.add(cls);
+ for (Class iClass : cls.getInterfaces()) {
+ addClassAndParentInterfaces(classesAndParents, iClass,
+ packageToInclude);
+ }
+
+ }
+
+ private static void appendClass(StringBuilder sb, Class<?> c,
+ Class<?> superClass, String packageToInclude,
+ boolean includeInterfaces) {
+ if (superClass == null) {
+ return;
+ }
+ if (!c.getPackage().getName().startsWith(packageToInclude)) {
+ return;
+ }
+ if (!superClass.getPackage().getName().startsWith(packageToInclude)) {
+ return;
+ }
+ if (!includeInterfaces && (c.isInterface() || superClass.isInterface())) {
+ return;
+ }
+
+ sb.append(c.getSimpleName()).append(" -> ")
+ .append(superClass.getSimpleName()).append("\n");
+
+ }
+
+ private static void addInterfaces(Set<Class> interfaces, Class<?> cls) {
+ if (interfaces.contains(cls)) {
+ return;
+ }
+
+ if (cls.isInterface()) {
+ interfaces.add(cls);
+ }
+
+ for (Class c : cls.getInterfaces()) {
+ addInterfaces(interfaces, c);
+ }
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/util/TestUtil.java b/server/tests/src/com/vaadin/tests/util/TestUtil.java
new file mode 100644
index 0000000000..e84f9dd8b9
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/util/TestUtil.java
@@ -0,0 +1,43 @@
+package com.vaadin.tests.util;
+
+import java.util.Iterator;
+
+import junit.framework.Assert;
+
+public class TestUtil {
+ public static void assertArrays(Object[] actualObjects,
+ Object[] expectedObjects) {
+ Assert.assertEquals(
+ "Actual contains a different number of values than was expected",
+ expectedObjects.length, actualObjects.length);
+
+ for (int i = 0; i < actualObjects.length; i++) {
+ Object actual = actualObjects[i];
+ Object expected = expectedObjects[i];
+
+ Assert.assertEquals("Item[" + i + "] does not match", expected,
+ actual);
+ }
+
+ }
+
+ public static void assertIterableEquals(Iterable<?> iterable1,
+ Iterable<?> iterable2) {
+ Iterator<?> i1 = iterable1.iterator();
+ Iterator<?> i2 = iterable2.iterator();
+
+ while (i1.hasNext()) {
+ Object o1 = i1.next();
+ if (!i2.hasNext()) {
+ Assert.fail("The second iterable contains fewer items than the first. The object "
+ + o1 + " has no match in the second iterable.");
+ }
+ Object o2 = i2.next();
+ Assert.assertEquals(o1, o2);
+ }
+ if (i2.hasNext()) {
+ Assert.fail("The second iterable contains more items than the first. The object "
+ + i2.next() + " has no match in the first iterable.");
+ }
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/util/UniqueSerializableTest.java b/server/tests/src/com/vaadin/tests/util/UniqueSerializableTest.java
new file mode 100644
index 0000000000..d62f0df332
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/util/UniqueSerializableTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2011 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.util;
+
+import java.io.Serializable;
+
+import junit.framework.TestCase;
+
+import org.apache.commons.lang.SerializationUtils;
+
+import com.vaadin.ui.UniqueSerializable;
+
+public class UniqueSerializableTest extends TestCase implements Serializable {
+
+ public void testUniqueness() {
+ UniqueSerializable o1 = new UniqueSerializable() {
+ };
+ UniqueSerializable o2 = new UniqueSerializable() {
+ };
+ assertFalse(o1 == o2);
+ assertFalse(o1.equals(o2));
+ }
+
+ public void testSerialization() {
+ UniqueSerializable o1 = new UniqueSerializable() {
+ };
+ UniqueSerializable d1 = (UniqueSerializable) SerializationUtils
+ .deserialize(SerializationUtils.serialize(o1));
+ assertTrue(d1.equals(o1));
+ }
+
+}