aboutsummaryrefslogtreecommitdiffstats
path: root/server/src
diff options
context:
space:
mode:
Diffstat (limited to 'server/src')
-rw-r--r--server/src/main/java/com/vaadin/annotations/AutoGenerated.java (renamed from server/src/com/vaadin/annotations/AutoGenerated.java)0
-rw-r--r--server/src/main/java/com/vaadin/annotations/DesignRoot.java (renamed from server/src/com/vaadin/annotations/DesignRoot.java)0
-rw-r--r--server/src/main/java/com/vaadin/annotations/JavaScript.java (renamed from server/src/com/vaadin/annotations/JavaScript.java)0
-rw-r--r--server/src/main/java/com/vaadin/annotations/PreserveOnRefresh.java (renamed from server/src/com/vaadin/annotations/PreserveOnRefresh.java)0
-rw-r--r--server/src/main/java/com/vaadin/annotations/Push.java (renamed from server/src/com/vaadin/annotations/Push.java)0
-rw-r--r--server/src/main/java/com/vaadin/annotations/StyleSheet.java (renamed from server/src/com/vaadin/annotations/StyleSheet.java)0
-rw-r--r--server/src/main/java/com/vaadin/annotations/Theme.java (renamed from server/src/com/vaadin/annotations/Theme.java)0
-rw-r--r--server/src/main/java/com/vaadin/annotations/Title.java (renamed from server/src/com/vaadin/annotations/Title.java)0
-rw-r--r--server/src/main/java/com/vaadin/annotations/VaadinServletConfiguration.java (renamed from server/src/com/vaadin/annotations/VaadinServletConfiguration.java)0
-rw-r--r--server/src/main/java/com/vaadin/annotations/Viewport.java (renamed from server/src/com/vaadin/annotations/Viewport.java)0
-rw-r--r--server/src/main/java/com/vaadin/annotations/ViewportGeneratorClass.java (renamed from server/src/com/vaadin/annotations/ViewportGeneratorClass.java)0
-rw-r--r--server/src/main/java/com/vaadin/annotations/Widgetset.java (renamed from server/src/com/vaadin/annotations/Widgetset.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/Buffered.java (renamed from server/src/com/vaadin/data/Buffered.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/BufferedValidatable.java (renamed from server/src/com/vaadin/data/BufferedValidatable.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/Collapsible.java (renamed from server/src/com/vaadin/data/Collapsible.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/Container.java (renamed from server/src/com/vaadin/data/Container.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/ContainerHelpers.java (renamed from server/src/com/vaadin/data/ContainerHelpers.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/Item.java (renamed from server/src/com/vaadin/data/Item.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/Property.java (renamed from server/src/com/vaadin/data/Property.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/Validatable.java (renamed from server/src/com/vaadin/data/Validatable.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/Validator.java (renamed from server/src/com/vaadin/data/Validator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/fieldgroup/BeanFieldGroup.java (renamed from server/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/fieldgroup/Caption.java (renamed from server/src/com/vaadin/data/fieldgroup/Caption.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java (renamed from server/src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/fieldgroup/FieldGroup.java (renamed from server/src/com/vaadin/data/fieldgroup/FieldGroup.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java (renamed from server/src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/fieldgroup/PropertyId.java (renamed from server/src/com/vaadin/data/fieldgroup/PropertyId.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/sort/Sort.java (renamed from server/src/com/vaadin/data/sort/Sort.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/sort/SortOrder.java (renamed from server/src/com/vaadin/data/sort/SortOrder.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/AbstractBeanContainer.java (renamed from server/src/com/vaadin/data/util/AbstractBeanContainer.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/AbstractContainer.java (renamed from server/src/com/vaadin/data/util/AbstractContainer.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/AbstractInMemoryContainer.java (renamed from server/src/com/vaadin/data/util/AbstractInMemoryContainer.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/AbstractProperty.java (renamed from server/src/com/vaadin/data/util/AbstractProperty.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/BeanContainer.java (renamed from server/src/com/vaadin/data/util/BeanContainer.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/BeanItem.java (renamed from server/src/com/vaadin/data/util/BeanItem.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/BeanItemContainer.java (renamed from server/src/com/vaadin/data/util/BeanItemContainer.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/BeanUtil.java (renamed from server/src/com/vaadin/data/util/BeanUtil.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/ContainerHierarchicalWrapper.java (renamed from server/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/ContainerOrderedWrapper.java (renamed from server/src/com/vaadin/data/util/ContainerOrderedWrapper.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/DefaultItemSorter.java (renamed from server/src/com/vaadin/data/util/DefaultItemSorter.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/FilesystemContainer.java (renamed from server/src/com/vaadin/data/util/FilesystemContainer.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/GeneratedPropertyContainer.java (renamed from server/src/com/vaadin/data/util/GeneratedPropertyContainer.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/HierarchicalContainer.java (renamed from server/src/com/vaadin/data/util/HierarchicalContainer.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/HierarchicalContainerOrderedWrapper.java (renamed from server/src/com/vaadin/data/util/HierarchicalContainerOrderedWrapper.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/IndexedContainer.java (renamed from server/src/com/vaadin/data/util/IndexedContainer.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/ItemSorter.java (renamed from server/src/com/vaadin/data/util/ItemSorter.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/LegacyPropertyHelper.java (renamed from server/src/com/vaadin/data/util/LegacyPropertyHelper.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/ListSet.java (renamed from server/src/com/vaadin/data/util/ListSet.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/MethodProperty.java (renamed from server/src/com/vaadin/data/util/MethodProperty.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/MethodPropertyDescriptor.java (renamed from server/src/com/vaadin/data/util/MethodPropertyDescriptor.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/NestedMethodProperty.java (renamed from server/src/com/vaadin/data/util/NestedMethodProperty.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/NestedPropertyDescriptor.java (renamed from server/src/com/vaadin/data/util/NestedPropertyDescriptor.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/ObjectProperty.java (renamed from server/src/com/vaadin/data/util/ObjectProperty.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/PropertyFormatter.java (renamed from server/src/com/vaadin/data/util/PropertyFormatter.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/PropertyValueGenerator.java (renamed from server/src/com/vaadin/data/util/PropertyValueGenerator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/PropertysetItem.java (renamed from server/src/com/vaadin/data/util/PropertysetItem.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/TextFileProperty.java (renamed from server/src/com/vaadin/data/util/TextFileProperty.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/TransactionalPropertyWrapper.java (renamed from server/src/com/vaadin/data/util/TransactionalPropertyWrapper.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/VaadinPropertyDescriptor.java (renamed from server/src/com/vaadin/data/util/VaadinPropertyDescriptor.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/converter/AbstractStringToNumberConverter.java (renamed from server/src/com/vaadin/data/util/converter/AbstractStringToNumberConverter.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/converter/Converter.java (renamed from server/src/com/vaadin/data/util/converter/Converter.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/converter/ConverterFactory.java (renamed from server/src/com/vaadin/data/util/converter/ConverterFactory.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/converter/ConverterUtil.java (renamed from server/src/com/vaadin/data/util/converter/ConverterUtil.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/converter/DateToLongConverter.java (renamed from server/src/com/vaadin/data/util/converter/DateToLongConverter.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/converter/DateToSqlDateConverter.java (renamed from server/src/com/vaadin/data/util/converter/DateToSqlDateConverter.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/converter/DefaultConverterFactory.java (renamed from server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/converter/ReverseConverter.java (renamed from server/src/com/vaadin/data/util/converter/ReverseConverter.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/converter/StringToBigDecimalConverter.java (renamed from server/src/com/vaadin/data/util/converter/StringToBigDecimalConverter.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/converter/StringToBigIntegerConverter.java (renamed from server/src/com/vaadin/data/util/converter/StringToBigIntegerConverter.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/converter/StringToBooleanConverter.java (renamed from server/src/com/vaadin/data/util/converter/StringToBooleanConverter.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/converter/StringToByteConverter.java (renamed from server/src/com/vaadin/data/util/converter/StringToByteConverter.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/converter/StringToCollectionConverter.java (renamed from server/src/com/vaadin/data/util/converter/StringToCollectionConverter.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/converter/StringToDateConverter.java (renamed from server/src/com/vaadin/data/util/converter/StringToDateConverter.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/converter/StringToDoubleConverter.java (renamed from server/src/com/vaadin/data/util/converter/StringToDoubleConverter.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/converter/StringToEnumConverter.java (renamed from server/src/com/vaadin/data/util/converter/StringToEnumConverter.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/converter/StringToFloatConverter.java (renamed from server/src/com/vaadin/data/util/converter/StringToFloatConverter.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/converter/StringToIntegerConverter.java (renamed from server/src/com/vaadin/data/util/converter/StringToIntegerConverter.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/converter/StringToLongConverter.java (renamed from server/src/com/vaadin/data/util/converter/StringToLongConverter.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/converter/StringToShortConverter.java (renamed from server/src/com/vaadin/data/util/converter/StringToShortConverter.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/filter/AbstractJunctionFilter.java (renamed from server/src/com/vaadin/data/util/filter/AbstractJunctionFilter.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/filter/And.java (renamed from server/src/com/vaadin/data/util/filter/And.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/filter/Between.java (renamed from server/src/com/vaadin/data/util/filter/Between.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/filter/Compare.java (renamed from server/src/com/vaadin/data/util/filter/Compare.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/filter/IsNull.java (renamed from server/src/com/vaadin/data/util/filter/IsNull.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/filter/Like.java (renamed from server/src/com/vaadin/data/util/filter/Like.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/filter/Not.java (renamed from server/src/com/vaadin/data/util/filter/Not.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/filter/Or.java (renamed from server/src/com/vaadin/data/util/filter/Or.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/filter/SimpleStringFilter.java (renamed from server/src/com/vaadin/data/util/filter/SimpleStringFilter.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/filter/UnsupportedFilterException.java (renamed from server/src/com/vaadin/data/util/filter/UnsupportedFilterException.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/CacheMap.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/CacheMap.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/ColumnProperty.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/ColumnProperty.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/OptimisticLockException.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/OptimisticLockException.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/ReadOnlyRowId.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/ReadOnlyRowId.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/Reference.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/Reference.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/RowId.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/RowId.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/RowItem.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/RowItem.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/SQLContainer.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/SQLUtil.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/SQLUtil.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/TemporaryRowId.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/TemporaryRowId.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPool.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPool.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/connection/JDBCConnectionPool.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/connection/JDBCConnectionPool.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/query/AbstractTransactionalQuery.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/query/AbstractTransactionalQuery.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/query/FreeformQueryDelegate.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQueryDelegate.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/query/OrderBy.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/query/OrderBy.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/query/QueryDelegate.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/query/QueryDelegate.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/query/TableQuery.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/MSSQLGenerator.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/query/generator/MSSQLGenerator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/OracleGenerator.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/query/generator/OracleGenerator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/SQLGenerator.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/query/generator/SQLGenerator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/AndTranslator.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/AndTranslator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/BetweenTranslator.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/BetweenTranslator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/CompareTranslator.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/CompareTranslator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/FilterTranslator.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/FilterTranslator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/IsNullTranslator.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/IsNullTranslator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/LikeTranslator.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/LikeTranslator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/NotTranslator.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/NotTranslator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/OrTranslator.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/OrTranslator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/QueryBuilder.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/QueryBuilder.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/SimpleStringTranslator.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/SimpleStringTranslator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/StringDecorator.java (renamed from server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/StringDecorator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/validator/AbstractStringValidator.java (renamed from server/src/com/vaadin/data/validator/AbstractStringValidator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/validator/AbstractValidator.java (renamed from server/src/com/vaadin/data/validator/AbstractValidator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/validator/BeanValidator.java (renamed from server/src/com/vaadin/data/validator/BeanValidator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/validator/BigDecimalRangeValidator.java (renamed from server/src/com/vaadin/data/validator/BigDecimalRangeValidator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/validator/BigIntegerRangeValidator.java (renamed from server/src/com/vaadin/data/validator/BigIntegerRangeValidator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/validator/ByteRangeValidator.java (renamed from server/src/com/vaadin/data/validator/ByteRangeValidator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/validator/CompositeValidator.java (renamed from server/src/com/vaadin/data/validator/CompositeValidator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/validator/DateRangeValidator.java (renamed from server/src/com/vaadin/data/validator/DateRangeValidator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/validator/DoubleRangeValidator.java (renamed from server/src/com/vaadin/data/validator/DoubleRangeValidator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/validator/DoubleValidator.java (renamed from server/src/com/vaadin/data/validator/DoubleValidator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/validator/EmailValidator.java (renamed from server/src/com/vaadin/data/validator/EmailValidator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/validator/FloatRangeValidator.java (renamed from server/src/com/vaadin/data/validator/FloatRangeValidator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/validator/IntegerRangeValidator.java (renamed from server/src/com/vaadin/data/validator/IntegerRangeValidator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/validator/IntegerValidator.java (renamed from server/src/com/vaadin/data/validator/IntegerValidator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/validator/LongRangeValidator.java (renamed from server/src/com/vaadin/data/validator/LongRangeValidator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/validator/NullValidator.java (renamed from server/src/com/vaadin/data/validator/NullValidator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/validator/RangeValidator.java (renamed from server/src/com/vaadin/data/validator/RangeValidator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/validator/RegexpValidator.java (renamed from server/src/com/vaadin/data/validator/RegexpValidator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/validator/ShortRangeValidator.java (renamed from server/src/com/vaadin/data/validator/ShortRangeValidator.java)0
-rw-r--r--server/src/main/java/com/vaadin/data/validator/StringLengthValidator.java (renamed from server/src/com/vaadin/data/validator/StringLengthValidator.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/Action.java (renamed from server/src/com/vaadin/event/Action.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/ActionManager.java (renamed from server/src/com/vaadin/event/ActionManager.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/ConnectorActionManager.java (renamed from server/src/com/vaadin/event/ConnectorActionManager.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/ConnectorEvent.java (renamed from server/src/com/vaadin/event/ConnectorEvent.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/ConnectorEventListener.java (renamed from server/src/com/vaadin/event/ConnectorEventListener.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/ContextClickEvent.java (renamed from server/src/com/vaadin/event/ContextClickEvent.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/DataBoundTransferable.java (renamed from server/src/com/vaadin/event/DataBoundTransferable.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/EventRouter.java (renamed from server/src/com/vaadin/event/EventRouter.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/FieldEvents.java (renamed from server/src/com/vaadin/event/FieldEvents.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/ItemClickEvent.java (renamed from server/src/com/vaadin/event/ItemClickEvent.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/LayoutEvents.java (renamed from server/src/com/vaadin/event/LayoutEvents.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/ListenerMethod.java (renamed from server/src/com/vaadin/event/ListenerMethod.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/MethodEventSource.java (renamed from server/src/com/vaadin/event/MethodEventSource.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/MouseEvents.java (renamed from server/src/com/vaadin/event/MouseEvents.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/SelectionEvent.java (renamed from server/src/com/vaadin/event/SelectionEvent.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/ShortcutAction.java (renamed from server/src/com/vaadin/event/ShortcutAction.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/ShortcutListener.java (renamed from server/src/com/vaadin/event/ShortcutListener.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/SortEvent.java (renamed from server/src/com/vaadin/event/SortEvent.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/Transferable.java (renamed from server/src/com/vaadin/event/Transferable.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/TransferableImpl.java (renamed from server/src/com/vaadin/event/TransferableImpl.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/UIEvents.java (renamed from server/src/com/vaadin/event/UIEvents.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/dd/DragAndDropEvent.java (renamed from server/src/com/vaadin/event/dd/DragAndDropEvent.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/dd/DragSource.java (renamed from server/src/com/vaadin/event/dd/DragSource.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/dd/DropHandler.java (renamed from server/src/com/vaadin/event/dd/DropHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/dd/DropTarget.java (renamed from server/src/com/vaadin/event/dd/DropTarget.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/dd/TargetDetails.java (renamed from server/src/com/vaadin/event/dd/TargetDetails.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/dd/TargetDetailsImpl.java (renamed from server/src/com/vaadin/event/dd/TargetDetailsImpl.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/dd/acceptcriteria/AcceptAll.java (renamed from server/src/com/vaadin/event/dd/acceptcriteria/AcceptAll.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/dd/acceptcriteria/AcceptCriterion.java (renamed from server/src/com/vaadin/event/dd/acceptcriteria/AcceptCriterion.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/dd/acceptcriteria/And.java (renamed from server/src/com/vaadin/event/dd/acceptcriteria/And.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/dd/acceptcriteria/ClientSideCriterion.java (renamed from server/src/com/vaadin/event/dd/acceptcriteria/ClientSideCriterion.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/dd/acceptcriteria/ContainsDataFlavor.java (renamed from server/src/com/vaadin/event/dd/acceptcriteria/ContainsDataFlavor.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/dd/acceptcriteria/Not.java (renamed from server/src/com/vaadin/event/dd/acceptcriteria/Not.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/dd/acceptcriteria/Or.java (renamed from server/src/com/vaadin/event/dd/acceptcriteria/Or.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/dd/acceptcriteria/ServerSideCriterion.java (renamed from server/src/com/vaadin/event/dd/acceptcriteria/ServerSideCriterion.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/dd/acceptcriteria/SourceIs.java (renamed from server/src/com/vaadin/event/dd/acceptcriteria/SourceIs.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/dd/acceptcriteria/SourceIsTarget.java (renamed from server/src/com/vaadin/event/dd/acceptcriteria/SourceIsTarget.java)0
-rw-r--r--server/src/main/java/com/vaadin/event/dd/acceptcriteria/TargetDetailIs.java (renamed from server/src/com/vaadin/event/dd/acceptcriteria/TargetDetailIs.java)0
-rw-r--r--server/src/main/java/com/vaadin/navigator/NavigationStateManager.java (renamed from server/src/com/vaadin/navigator/NavigationStateManager.java)0
-rw-r--r--server/src/main/java/com/vaadin/navigator/Navigator.java (renamed from server/src/com/vaadin/navigator/Navigator.java)0
-rw-r--r--server/src/main/java/com/vaadin/navigator/View.java (renamed from server/src/com/vaadin/navigator/View.java)0
-rw-r--r--server/src/main/java/com/vaadin/navigator/ViewChangeListener.java (renamed from server/src/com/vaadin/navigator/ViewChangeListener.java)0
-rw-r--r--server/src/main/java/com/vaadin/navigator/ViewDisplay.java (renamed from server/src/com/vaadin/navigator/ViewDisplay.java)0
-rw-r--r--server/src/main/java/com/vaadin/navigator/ViewProvider.java (renamed from server/src/com/vaadin/navigator/ViewProvider.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/AbstractClientConnector.java (renamed from server/src/com/vaadin/server/AbstractClientConnector.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/AbstractDeploymentConfiguration.java (renamed from server/src/com/vaadin/server/AbstractDeploymentConfiguration.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/AbstractErrorMessage.java (renamed from server/src/com/vaadin/server/AbstractErrorMessage.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/AbstractExtension.java (renamed from server/src/com/vaadin/server/AbstractExtension.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/AbstractJavaScriptExtension.java (renamed from server/src/com/vaadin/server/AbstractJavaScriptExtension.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/BootstrapFragmentResponse.java (renamed from server/src/com/vaadin/server/BootstrapFragmentResponse.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/BootstrapHandler.java (renamed from server/src/com/vaadin/server/BootstrapHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/BootstrapListener.java (renamed from server/src/com/vaadin/server/BootstrapListener.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/BootstrapPageResponse.java (renamed from server/src/com/vaadin/server/BootstrapPageResponse.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/BootstrapResponse.java (renamed from server/src/com/vaadin/server/BootstrapResponse.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/BrowserWindowOpener.java (renamed from server/src/com/vaadin/server/BrowserWindowOpener.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/ClassResource.java (renamed from server/src/com/vaadin/server/ClassResource.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/ClientConnector.java (renamed from server/src/com/vaadin/server/ClientConnector.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/ClientMethodInvocation.java (renamed from server/src/com/vaadin/server/ClientMethodInvocation.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/ComponentSizeValidator.java (renamed from server/src/com/vaadin/server/ComponentSizeValidator.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/CompositeErrorMessage.java (renamed from server/src/com/vaadin/server/CompositeErrorMessage.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/ConnectorResource.java (renamed from server/src/com/vaadin/server/ConnectorResource.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/ConnectorResourceHandler.java (renamed from server/src/com/vaadin/server/ConnectorResourceHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/Constants.java (renamed from server/src/com/vaadin/server/Constants.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/CustomizedSystemMessages.java (renamed from server/src/com/vaadin/server/CustomizedSystemMessages.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/DefaultDeploymentConfiguration.java (renamed from server/src/com/vaadin/server/DefaultDeploymentConfiguration.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/DefaultErrorHandler.java (renamed from server/src/com/vaadin/server/DefaultErrorHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/DefaultSystemMessagesProvider.java (renamed from server/src/com/vaadin/server/DefaultSystemMessagesProvider.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/DefaultUIProvider.java (renamed from server/src/com/vaadin/server/DefaultUIProvider.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/DeploymentConfiguration.java (renamed from server/src/com/vaadin/server/DeploymentConfiguration.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/DownloadStream.java (renamed from server/src/com/vaadin/server/DownloadStream.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/DragAndDropService.java (renamed from server/src/com/vaadin/server/DragAndDropService.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/EncodeResult.java (renamed from server/src/com/vaadin/server/EncodeResult.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/ErrorEvent.java (renamed from server/src/com/vaadin/server/ErrorEvent.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/ErrorHandler.java (renamed from server/src/com/vaadin/server/ErrorHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/ErrorHandlingRunnable.java (renamed from server/src/com/vaadin/server/ErrorHandlingRunnable.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/ErrorMessage.java (renamed from server/src/com/vaadin/server/ErrorMessage.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/Extension.java (renamed from server/src/com/vaadin/server/Extension.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/ExternalResource.java (renamed from server/src/com/vaadin/server/ExternalResource.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/FileDownloader.java (renamed from server/src/com/vaadin/server/FileDownloader.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/FileResource.java (renamed from server/src/com/vaadin/server/FileResource.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/FontAwesome.java (renamed from server/src/com/vaadin/server/FontAwesome.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/FontIcon.java (renamed from server/src/com/vaadin/server/FontIcon.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/GAEVaadinServlet.java (renamed from server/src/com/vaadin/server/GAEVaadinServlet.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/GenericFontIcon.java (renamed from server/src/com/vaadin/server/GenericFontIcon.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/GlobalResourceHandler.java (renamed from server/src/com/vaadin/server/GlobalResourceHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/JavaScriptCallbackHelper.java (renamed from server/src/com/vaadin/server/JavaScriptCallbackHelper.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/JsonCodec.java (renamed from server/src/com/vaadin/server/JsonCodec.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/JsonPaintTarget.java (renamed from server/src/com/vaadin/server/JsonPaintTarget.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/KeyMapper.java (renamed from server/src/com/vaadin/server/KeyMapper.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/LegacyApplication.java (renamed from server/src/com/vaadin/server/LegacyApplication.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/LegacyApplicationUIProvider.java (renamed from server/src/com/vaadin/server/LegacyApplicationUIProvider.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/LegacyCommunicationManager.java (renamed from server/src/com/vaadin/server/LegacyCommunicationManager.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/LegacyPaint.java (renamed from server/src/com/vaadin/server/LegacyPaint.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/LegacyVaadinPortlet.java (renamed from server/src/com/vaadin/server/LegacyVaadinPortlet.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/LegacyVaadinServlet.java (renamed from server/src/com/vaadin/server/LegacyVaadinServlet.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/LocaleService.java (renamed from server/src/com/vaadin/server/LocaleService.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/NoInputStreamException.java (renamed from server/src/com/vaadin/server/NoInputStreamException.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/NoOutputStreamException.java (renamed from server/src/com/vaadin/server/NoOutputStreamException.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/Page.java (renamed from server/src/com/vaadin/server/Page.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/PaintException.java (renamed from server/src/com/vaadin/server/PaintException.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/PaintTarget.java (renamed from server/src/com/vaadin/server/PaintTarget.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/RequestHandler.java (renamed from server/src/com/vaadin/server/RequestHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/Resource.java (renamed from server/src/com/vaadin/server/Resource.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/ResourceReference.java (renamed from server/src/com/vaadin/server/ResourceReference.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/Responsive.java (renamed from server/src/com/vaadin/server/Responsive.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/RestrictedRenderResponse.java (renamed from server/src/com/vaadin/server/RestrictedRenderResponse.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/Scrollable.java (renamed from server/src/com/vaadin/server/Scrollable.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/ServerRpcManager.java (renamed from server/src/com/vaadin/server/ServerRpcManager.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/ServerRpcMethodInvocation.java (renamed from server/src/com/vaadin/server/ServerRpcMethodInvocation.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/ServiceDestroyEvent.java (renamed from server/src/com/vaadin/server/ServiceDestroyEvent.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/ServiceDestroyListener.java (renamed from server/src/com/vaadin/server/ServiceDestroyListener.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/ServiceException.java (renamed from server/src/com/vaadin/server/ServiceException.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/ServletPortletHelper.java (renamed from server/src/com/vaadin/server/ServletPortletHelper.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/SessionDestroyEvent.java (renamed from server/src/com/vaadin/server/SessionDestroyEvent.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/SessionDestroyListener.java (renamed from server/src/com/vaadin/server/SessionDestroyListener.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/SessionExpiredException.java (renamed from server/src/com/vaadin/server/SessionExpiredException.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/SessionExpiredHandler.java (renamed from server/src/com/vaadin/server/SessionExpiredHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/SessionInitEvent.java (renamed from server/src/com/vaadin/server/SessionInitEvent.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/SessionInitListener.java (renamed from server/src/com/vaadin/server/SessionInitListener.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/SizeWithUnit.java (renamed from server/src/com/vaadin/server/SizeWithUnit.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/Sizeable.java (renamed from server/src/com/vaadin/server/Sizeable.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/StreamResource.java (renamed from server/src/com/vaadin/server/StreamResource.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/StreamVariable.java (renamed from server/src/com/vaadin/server/StreamVariable.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/SynchronizedRequestHandler.java (renamed from server/src/com/vaadin/server/SynchronizedRequestHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/SystemError.java (renamed from server/src/com/vaadin/server/SystemError.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/SystemMessageException.java (renamed from server/src/com/vaadin/server/SystemMessageException.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/SystemMessages.java (renamed from server/src/com/vaadin/server/SystemMessages.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/SystemMessagesInfo.java (renamed from server/src/com/vaadin/server/SystemMessagesInfo.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/SystemMessagesProvider.java (renamed from server/src/com/vaadin/server/SystemMessagesProvider.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/ThemeResource.java (renamed from server/src/com/vaadin/server/ThemeResource.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/UIClassSelectionEvent.java (renamed from server/src/com/vaadin/server/UIClassSelectionEvent.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/UICreateEvent.java (renamed from server/src/com/vaadin/server/UICreateEvent.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/UIProvider.java (renamed from server/src/com/vaadin/server/UIProvider.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/UIProviderEvent.java (renamed from server/src/com/vaadin/server/UIProviderEvent.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/UnsupportedBrowserHandler.java (renamed from server/src/com/vaadin/server/UnsupportedBrowserHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/UploadException.java (renamed from server/src/com/vaadin/server/UploadException.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/UserError.java (renamed from server/src/com/vaadin/server/UserError.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/VaadinPortlet.java (renamed from server/src/com/vaadin/server/VaadinPortlet.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/VaadinPortletRequest.java (renamed from server/src/com/vaadin/server/VaadinPortletRequest.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/VaadinPortletResponse.java (renamed from server/src/com/vaadin/server/VaadinPortletResponse.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/VaadinPortletService.java (renamed from server/src/com/vaadin/server/VaadinPortletService.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/VaadinPortletSession.java (renamed from server/src/com/vaadin/server/VaadinPortletSession.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/VaadinRequest.java (renamed from server/src/com/vaadin/server/VaadinRequest.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/VaadinResponse.java (renamed from server/src/com/vaadin/server/VaadinResponse.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/VaadinService.java (renamed from server/src/com/vaadin/server/VaadinService.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/VaadinServiceClassLoaderUtil.java (renamed from server/src/com/vaadin/server/VaadinServiceClassLoaderUtil.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/VaadinServlet.java (renamed from server/src/com/vaadin/server/VaadinServlet.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/VaadinServletRequest.java (renamed from server/src/com/vaadin/server/VaadinServletRequest.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/VaadinServletResponse.java (renamed from server/src/com/vaadin/server/VaadinServletResponse.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/VaadinServletService.java (renamed from server/src/com/vaadin/server/VaadinServletService.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/VaadinSession.java (renamed from server/src/com/vaadin/server/VaadinSession.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/VariableOwner.java (renamed from server/src/com/vaadin/server/VariableOwner.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/ViewportGenerator.java (renamed from server/src/com/vaadin/server/ViewportGenerator.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/WebBrowser.java (renamed from server/src/com/vaadin/server/WebBrowser.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/WrappedHttpSession.java (renamed from server/src/com/vaadin/server/WrappedHttpSession.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/WrappedPortletSession.java (renamed from server/src/com/vaadin/server/WrappedPortletSession.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/WrappedSession.java (renamed from server/src/com/vaadin/server/WrappedSession.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/AbstractStreamingEvent.java (renamed from server/src/com/vaadin/server/communication/AbstractStreamingEvent.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/AtmospherePushConnection.java (renamed from server/src/com/vaadin/server/communication/AtmospherePushConnection.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/ClientRpcWriter.java (renamed from server/src/com/vaadin/server/communication/ClientRpcWriter.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/ConnectorHierarchyWriter.java (renamed from server/src/com/vaadin/server/communication/ConnectorHierarchyWriter.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/ConnectorTypeWriter.java (renamed from server/src/com/vaadin/server/communication/ConnectorTypeWriter.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/DateSerializer.java (renamed from server/src/com/vaadin/server/communication/DateSerializer.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/FileUploadHandler.java (renamed from server/src/com/vaadin/server/communication/FileUploadHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/HeartbeatHandler.java (renamed from server/src/com/vaadin/server/communication/HeartbeatHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/JSONSerializer.java (renamed from server/src/com/vaadin/server/communication/JSONSerializer.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/JSR356WebsocketInitializer.java (renamed from server/src/com/vaadin/server/communication/JSR356WebsocketInitializer.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/LegacyUidlWriter.java (renamed from server/src/com/vaadin/server/communication/LegacyUidlWriter.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/MetadataWriter.java (renamed from server/src/com/vaadin/server/communication/MetadataWriter.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/PortletBootstrapHandler.java (renamed from server/src/com/vaadin/server/communication/PortletBootstrapHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/PortletDummyRequestHandler.java (renamed from server/src/com/vaadin/server/communication/PortletDummyRequestHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/PortletListenerNotifier.java (renamed from server/src/com/vaadin/server/communication/PortletListenerNotifier.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/PortletStateAwareRequestHandler.java (renamed from server/src/com/vaadin/server/communication/PortletStateAwareRequestHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/PortletUIInitHandler.java (renamed from server/src/com/vaadin/server/communication/PortletUIInitHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/PublishedFileHandler.java (renamed from server/src/com/vaadin/server/communication/PublishedFileHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/PushAtmosphereHandler.java (renamed from server/src/com/vaadin/server/communication/PushAtmosphereHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/PushConnection.java (renamed from server/src/com/vaadin/server/communication/PushConnection.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/PushHandler.java (renamed from server/src/com/vaadin/server/communication/PushHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/PushRequestHandler.java (renamed from server/src/com/vaadin/server/communication/PushRequestHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/ResourceWriter.java (renamed from server/src/com/vaadin/server/communication/ResourceWriter.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/ServerRpcHandler.java (renamed from server/src/com/vaadin/server/communication/ServerRpcHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/ServletBootstrapHandler.java (renamed from server/src/com/vaadin/server/communication/ServletBootstrapHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/ServletUIInitHandler.java (renamed from server/src/com/vaadin/server/communication/ServletUIInitHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/SessionRequestHandler.java (renamed from server/src/com/vaadin/server/communication/SessionRequestHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/SharedStateWriter.java (renamed from server/src/com/vaadin/server/communication/SharedStateWriter.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/StreamingEndEventImpl.java (renamed from server/src/com/vaadin/server/communication/StreamingEndEventImpl.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/StreamingErrorEventImpl.java (renamed from server/src/com/vaadin/server/communication/StreamingErrorEventImpl.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/StreamingProgressEventImpl.java (renamed from server/src/com/vaadin/server/communication/StreamingProgressEventImpl.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/StreamingStartEventImpl.java (renamed from server/src/com/vaadin/server/communication/StreamingStartEventImpl.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/UIInitHandler.java (renamed from server/src/com/vaadin/server/communication/UIInitHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/UidlRequestHandler.java (renamed from server/src/com/vaadin/server/communication/UidlRequestHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/UidlWriter.java (renamed from server/src/com/vaadin/server/communication/UidlWriter.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/data/DataGenerator.java (renamed from server/src/com/vaadin/server/communication/data/DataGenerator.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/communication/data/RpcDataProviderExtension.java (renamed from server/src/com/vaadin/server/communication/data/RpcDataProviderExtension.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/themeutils/SASSAddonImportFileCreator.java (renamed from server/src/com/vaadin/server/themeutils/SASSAddonImportFileCreator.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/widgetsetutils/ClassPathExplorer.java (renamed from server/src/com/vaadin/server/widgetsetutils/ClassPathExplorer.java)0
-rw-r--r--server/src/main/java/com/vaadin/server/widgetsetutils/WidgetSetBuilder.java (renamed from server/src/com/vaadin/server/widgetsetutils/WidgetSetBuilder.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/AbsoluteLayout.java (renamed from server/src/com/vaadin/ui/AbsoluteLayout.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/AbstractColorPicker.java (renamed from server/src/com/vaadin/ui/AbstractColorPicker.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/AbstractComponent.java (renamed from server/src/com/vaadin/ui/AbstractComponent.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/AbstractComponentContainer.java (renamed from server/src/com/vaadin/ui/AbstractComponentContainer.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/AbstractEmbedded.java (renamed from server/src/com/vaadin/ui/AbstractEmbedded.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/AbstractField.java (renamed from server/src/com/vaadin/ui/AbstractField.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/AbstractFocusable.java (renamed from server/src/com/vaadin/ui/AbstractFocusable.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/AbstractJavaScriptComponent.java (renamed from server/src/com/vaadin/ui/AbstractJavaScriptComponent.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/AbstractLayout.java (renamed from server/src/com/vaadin/ui/AbstractLayout.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/AbstractMedia.java (renamed from server/src/com/vaadin/ui/AbstractMedia.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/AbstractOrderedLayout.java (renamed from server/src/com/vaadin/ui/AbstractOrderedLayout.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/AbstractSelect.java (renamed from server/src/com/vaadin/ui/AbstractSelect.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/AbstractSingleComponentContainer.java (renamed from server/src/com/vaadin/ui/AbstractSingleComponentContainer.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/AbstractSplitPanel.java (renamed from server/src/com/vaadin/ui/AbstractSplitPanel.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/AbstractTextField.java (renamed from server/src/com/vaadin/ui/AbstractTextField.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/Accordion.java (renamed from server/src/com/vaadin/ui/Accordion.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/Alignment.java (renamed from server/src/com/vaadin/ui/Alignment.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/Audio.java (renamed from server/src/com/vaadin/ui/Audio.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/BrowserFrame.java (renamed from server/src/com/vaadin/ui/BrowserFrame.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/Button.java (renamed from server/src/com/vaadin/ui/Button.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/Calendar.java (renamed from server/src/com/vaadin/ui/Calendar.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/CheckBox.java (renamed from server/src/com/vaadin/ui/CheckBox.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/ColorPicker.java (renamed from server/src/com/vaadin/ui/ColorPicker.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/ColorPickerArea.java (renamed from server/src/com/vaadin/ui/ColorPickerArea.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/ComboBox.java (renamed from server/src/com/vaadin/ui/ComboBox.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/Component.java (renamed from server/src/com/vaadin/ui/Component.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/ComponentContainer.java (renamed from server/src/com/vaadin/ui/ComponentContainer.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/ConnectorTracker.java (renamed from server/src/com/vaadin/ui/ConnectorTracker.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/CssLayout.java (renamed from server/src/com/vaadin/ui/CssLayout.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/CustomComponent.java (renamed from server/src/com/vaadin/ui/CustomComponent.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/CustomField.java (renamed from server/src/com/vaadin/ui/CustomField.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/CustomLayout.java (renamed from server/src/com/vaadin/ui/CustomLayout.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/DateField.java (renamed from server/src/com/vaadin/ui/DateField.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/DefaultFieldFactory.java (renamed from server/src/com/vaadin/ui/DefaultFieldFactory.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/DragAndDropWrapper.java (renamed from server/src/com/vaadin/ui/DragAndDropWrapper.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/Embedded.java (renamed from server/src/com/vaadin/ui/Embedded.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/Field.java (renamed from server/src/com/vaadin/ui/Field.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/Flash.java (renamed from server/src/com/vaadin/ui/Flash.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/Form.java (renamed from server/src/com/vaadin/ui/Form.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/FormFieldFactory.java (renamed from server/src/com/vaadin/ui/FormFieldFactory.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/FormLayout.java (renamed from server/src/com/vaadin/ui/FormLayout.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/Grid.java (renamed from server/src/com/vaadin/ui/Grid.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/GridLayout.java (renamed from server/src/com/vaadin/ui/GridLayout.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/HasChildMeasurementHint.java (renamed from server/src/com/vaadin/ui/HasChildMeasurementHint.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/HasComponents.java (renamed from server/src/com/vaadin/ui/HasComponents.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/HorizontalLayout.java (renamed from server/src/com/vaadin/ui/HorizontalLayout.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/HorizontalSplitPanel.java (renamed from server/src/com/vaadin/ui/HorizontalSplitPanel.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/Html5File.java (renamed from server/src/com/vaadin/ui/Html5File.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/Image.java (renamed from server/src/com/vaadin/ui/Image.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/InlineDateField.java (renamed from server/src/com/vaadin/ui/InlineDateField.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/JavaScript.java (renamed from server/src/com/vaadin/ui/JavaScript.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/JavaScriptFunction.java (renamed from server/src/com/vaadin/ui/JavaScriptFunction.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/Label.java (renamed from server/src/com/vaadin/ui/Label.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/Layout.java (renamed from server/src/com/vaadin/ui/Layout.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/LegacyComponent.java (renamed from server/src/com/vaadin/ui/LegacyComponent.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/LegacyWindow.java (renamed from server/src/com/vaadin/ui/LegacyWindow.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/Link.java (renamed from server/src/com/vaadin/ui/Link.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/ListSelect.java (renamed from server/src/com/vaadin/ui/ListSelect.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/LoadingIndicatorConfiguration.java (renamed from server/src/com/vaadin/ui/LoadingIndicatorConfiguration.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/LoginForm.java (renamed from server/src/com/vaadin/ui/LoginForm.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/MenuBar.java (renamed from server/src/com/vaadin/ui/MenuBar.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/NativeButton.java (renamed from server/src/com/vaadin/ui/NativeButton.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/NativeSelect.java (renamed from server/src/com/vaadin/ui/NativeSelect.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/Notification.java (renamed from server/src/com/vaadin/ui/Notification.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/NotificationConfiguration.java (renamed from server/src/com/vaadin/ui/NotificationConfiguration.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/OptionGroup.java (renamed from server/src/com/vaadin/ui/OptionGroup.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/Panel.java (renamed from server/src/com/vaadin/ui/Panel.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/PasswordField.java (renamed from server/src/com/vaadin/ui/PasswordField.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/PopupDateField.java (renamed from server/src/com/vaadin/ui/PopupDateField.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/PopupView.java (renamed from server/src/com/vaadin/ui/PopupView.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/ProgressBar.java (renamed from server/src/com/vaadin/ui/ProgressBar.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/ProgressIndicator.java (renamed from server/src/com/vaadin/ui/ProgressIndicator.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/PushConfiguration.java (renamed from server/src/com/vaadin/ui/PushConfiguration.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/ReconnectDialogConfiguration.java (renamed from server/src/com/vaadin/ui/ReconnectDialogConfiguration.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/RichTextArea.java (renamed from server/src/com/vaadin/ui/RichTextArea.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/Select.java (renamed from server/src/com/vaadin/ui/Select.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/SelectiveRenderer.java (renamed from server/src/com/vaadin/ui/SelectiveRenderer.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/SingleComponentContainer.java (renamed from server/src/com/vaadin/ui/SingleComponentContainer.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/Slider.java (renamed from server/src/com/vaadin/ui/Slider.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/TabSheet.java (renamed from server/src/com/vaadin/ui/TabSheet.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/Table.java (renamed from server/src/com/vaadin/ui/Table.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/TableFieldFactory.java (renamed from server/src/com/vaadin/ui/TableFieldFactory.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/TextArea.java (renamed from server/src/com/vaadin/ui/TextArea.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/TextField.java (renamed from server/src/com/vaadin/ui/TextField.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/TooltipConfiguration.java (renamed from server/src/com/vaadin/ui/TooltipConfiguration.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/Tree.java (renamed from server/src/com/vaadin/ui/Tree.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/TreeTable.java (renamed from server/src/com/vaadin/ui/TreeTable.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/TwinColSelect.java (renamed from server/src/com/vaadin/ui/TwinColSelect.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/UI.java (renamed from server/src/com/vaadin/ui/UI.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/UIDetachedException.java (renamed from server/src/com/vaadin/ui/UIDetachedException.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/UniqueSerializable.java (renamed from server/src/com/vaadin/ui/UniqueSerializable.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/Upload.java (renamed from server/src/com/vaadin/ui/Upload.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/VerticalLayout.java (renamed from server/src/com/vaadin/ui/VerticalLayout.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/VerticalSplitPanel.java (renamed from server/src/com/vaadin/ui/VerticalSplitPanel.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/Video.java (renamed from server/src/com/vaadin/ui/Video.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/Window.java (renamed from server/src/com/vaadin/ui/Window.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/calendar/CalendarComponentEvent.java (renamed from server/src/com/vaadin/ui/components/calendar/CalendarComponentEvent.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/calendar/CalendarComponentEvents.java (renamed from server/src/com/vaadin/ui/components/calendar/CalendarComponentEvents.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/calendar/CalendarDateRange.java (renamed from server/src/com/vaadin/ui/components/calendar/CalendarDateRange.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/calendar/CalendarTargetDetails.java (renamed from server/src/com/vaadin/ui/components/calendar/CalendarTargetDetails.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/calendar/ContainerEventProvider.java (renamed from server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/calendar/event/BasicEvent.java (renamed from server/src/com/vaadin/ui/components/calendar/event/BasicEvent.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/calendar/event/BasicEventProvider.java (renamed from server/src/com/vaadin/ui/components/calendar/event/BasicEventProvider.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/calendar/event/CalendarEditableEventProvider.java (renamed from server/src/com/vaadin/ui/components/calendar/event/CalendarEditableEventProvider.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/calendar/event/CalendarEvent.java (renamed from server/src/com/vaadin/ui/components/calendar/event/CalendarEvent.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/calendar/event/CalendarEventProvider.java (renamed from server/src/com/vaadin/ui/components/calendar/event/CalendarEventProvider.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/calendar/event/EditableCalendarEvent.java (renamed from server/src/com/vaadin/ui/components/calendar/event/EditableCalendarEvent.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicBackwardHandler.java (renamed from server/src/com/vaadin/ui/components/calendar/handler/BasicBackwardHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicDateClickHandler.java (renamed from server/src/com/vaadin/ui/components/calendar/handler/BasicDateClickHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicEventMoveHandler.java (renamed from server/src/com/vaadin/ui/components/calendar/handler/BasicEventMoveHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicEventResizeHandler.java (renamed from server/src/com/vaadin/ui/components/calendar/handler/BasicEventResizeHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicForwardHandler.java (renamed from server/src/com/vaadin/ui/components/calendar/handler/BasicForwardHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicWeekClickHandler.java (renamed from server/src/com/vaadin/ui/components/calendar/handler/BasicWeekClickHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/colorpicker/ColorChangeEvent.java (renamed from server/src/com/vaadin/ui/components/colorpicker/ColorChangeEvent.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/colorpicker/ColorChangeListener.java (renamed from server/src/com/vaadin/ui/components/colorpicker/ColorChangeListener.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerGradient.java (renamed from server/src/com/vaadin/ui/components/colorpicker/ColorPickerGradient.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerGrid.java (renamed from server/src/com/vaadin/ui/components/colorpicker/ColorPickerGrid.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerHistory.java (renamed from server/src/com/vaadin/ui/components/colorpicker/ColorPickerHistory.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerPopup.java (renamed from server/src/com/vaadin/ui/components/colorpicker/ColorPickerPopup.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerPreview.java (renamed from server/src/com/vaadin/ui/components/colorpicker/ColorPickerPreview.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerSelect.java (renamed from server/src/com/vaadin/ui/components/colorpicker/ColorPickerSelect.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/colorpicker/ColorSelector.java (renamed from server/src/com/vaadin/ui/components/colorpicker/ColorSelector.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/components/colorpicker/HasColorChangeListener.java (renamed from server/src/com/vaadin/ui/components/colorpicker/HasColorChangeListener.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/declarative/Design.java (renamed from server/src/com/vaadin/ui/declarative/Design.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/declarative/DesignAttributeHandler.java (renamed from server/src/com/vaadin/ui/declarative/DesignAttributeHandler.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/declarative/DesignContext.java (renamed from server/src/com/vaadin/ui/declarative/DesignContext.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/declarative/DesignException.java (renamed from server/src/com/vaadin/ui/declarative/DesignException.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/declarative/DesignFormatter.java (renamed from server/src/com/vaadin/ui/declarative/DesignFormatter.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/declarative/FieldBinder.java (renamed from server/src/com/vaadin/ui/declarative/FieldBinder.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/declarative/FieldBindingException.java (renamed from server/src/com/vaadin/ui/declarative/FieldBindingException.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/declarative/ShouldWriteDataDelegate.java (renamed from server/src/com/vaadin/ui/declarative/ShouldWriteDataDelegate.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/declarative/converters/DesignDateConverter.java (renamed from server/src/com/vaadin/ui/declarative/converters/DesignDateConverter.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/declarative/converters/DesignEnumConverter.java (renamed from server/src/com/vaadin/ui/declarative/converters/DesignEnumConverter.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/declarative/converters/DesignObjectConverter.java (renamed from server/src/com/vaadin/ui/declarative/converters/DesignObjectConverter.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/declarative/converters/DesignResourceConverter.java (renamed from server/src/com/vaadin/ui/declarative/converters/DesignResourceConverter.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/declarative/converters/DesignShortcutActionConverter.java (renamed from server/src/com/vaadin/ui/declarative/converters/DesignShortcutActionConverter.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/declarative/converters/DesignTimeZoneConverter.java (renamed from server/src/com/vaadin/ui/declarative/converters/DesignTimeZoneConverter.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/declarative/converters/DesignToStringConverter.java (renamed from server/src/com/vaadin/ui/declarative/converters/DesignToStringConverter.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/declarative/converters/ShortcutKeyMapper.java (renamed from server/src/com/vaadin/ui/declarative/converters/ShortcutKeyMapper.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/renderers/AbstractJavaScriptRenderer.java (renamed from server/src/com/vaadin/ui/renderers/AbstractJavaScriptRenderer.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/renderers/ButtonRenderer.java (renamed from server/src/com/vaadin/ui/renderers/ButtonRenderer.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/renderers/ClickableRenderer.java (renamed from server/src/com/vaadin/ui/renderers/ClickableRenderer.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/renderers/DateRenderer.java (renamed from server/src/com/vaadin/ui/renderers/DateRenderer.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/renderers/HtmlRenderer.java (renamed from server/src/com/vaadin/ui/renderers/HtmlRenderer.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/renderers/ImageRenderer.java (renamed from server/src/com/vaadin/ui/renderers/ImageRenderer.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/renderers/NumberRenderer.java (renamed from server/src/com/vaadin/ui/renderers/NumberRenderer.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/renderers/ProgressBarRenderer.java (renamed from server/src/com/vaadin/ui/renderers/ProgressBarRenderer.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/renderers/Renderer.java (renamed from server/src/com/vaadin/ui/renderers/Renderer.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/renderers/TextRenderer.java (renamed from server/src/com/vaadin/ui/renderers/TextRenderer.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/themes/BaseTheme.java (renamed from server/src/com/vaadin/ui/themes/BaseTheme.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/themes/ChameleonTheme.java (renamed from server/src/com/vaadin/ui/themes/ChameleonTheme.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/themes/LiferayTheme.java (renamed from server/src/com/vaadin/ui/themes/LiferayTheme.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/themes/Reindeer.java (renamed from server/src/com/vaadin/ui/themes/Reindeer.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/themes/Runo.java (renamed from server/src/com/vaadin/ui/themes/Runo.java)0
-rw-r--r--server/src/main/java/com/vaadin/ui/themes/ValoTheme.java (renamed from server/src/com/vaadin/ui/themes/ValoTheme.java)0
-rw-r--r--server/src/main/java/com/vaadin/util/ConnectorHelper.java (renamed from server/src/com/vaadin/util/ConnectorHelper.java)0
-rw-r--r--server/src/main/java/com/vaadin/util/CurrentInstance.java (renamed from server/src/com/vaadin/util/CurrentInstance.java)0
-rw-r--r--server/src/main/java/com/vaadin/util/FileTypeResolver.java (renamed from server/src/com/vaadin/util/FileTypeResolver.java)0
-rw-r--r--server/src/main/java/com/vaadin/util/ReflectTools.java (renamed from server/src/com/vaadin/util/ReflectTools.java)0
-rw-r--r--server/src/main/java/com/vaadin/util/SerializerHelper.java (renamed from server/src/com/vaadin/util/SerializerHelper.java)0
-rw-r--r--server/src/main/resources/VAADIN/vaadinBootstrap.js359
-rw-r--r--server/src/main/resources/com/vaadin/annotations/package.html (renamed from server/src/com/vaadin/annotations/package.html)0
-rw-r--r--server/src/main/resources/com/vaadin/data/package.html (renamed from server/src/com/vaadin/data/package.html)0
-rw-r--r--server/src/main/resources/com/vaadin/data/util/package.html (renamed from server/src/com/vaadin/data/util/package.html)0
-rw-r--r--server/src/main/resources/com/vaadin/data/validator/package.html (renamed from server/src/com/vaadin/data/validator/package.html)0
-rw-r--r--server/src/main/resources/com/vaadin/event/package.html (renamed from server/src/com/vaadin/event/package.html)0
-rw-r--r--server/src/main/resources/com/vaadin/package.html (renamed from server/src/com/vaadin/package.html)0
-rw-r--r--server/src/main/resources/com/vaadin/server/package.html (renamed from server/src/com/vaadin/server/package.html)0
-rw-r--r--server/src/main/resources/com/vaadin/ui/doc-files/component_class_hierarchy.gif (renamed from server/src/com/vaadin/ui/doc-files/component_class_hierarchy.gif)bin11077 -> 11077 bytes
-rw-r--r--server/src/main/resources/com/vaadin/ui/doc-files/component_interfaces.gif (renamed from server/src/com/vaadin/ui/doc-files/component_interfaces.gif)bin2272 -> 2272 bytes
-rw-r--r--server/src/main/resources/com/vaadin/ui/package.html (renamed from server/src/com/vaadin/ui/package.html)0
-rw-r--r--server/src/test/java/ClassInDefaultPackage.java29
-rw-r--r--server/src/test/java/com/vaadin/benchmarks/PerformanceTester8759.java52
-rw-r--r--server/src/test/java/com/vaadin/data/DefaultFieldGroupFieldFactoryTest.java120
-rw-r--r--server/src/test/java/com/vaadin/data/fieldgroup/BeanFieldGroupTest.java70
-rw-r--r--server/src/test/java/com/vaadin/data/fieldgroup/FieldGroupDateTest.java97
-rw-r--r--server/src/test/java/com/vaadin/data/fieldgroup/FieldGroupExceptionTest.java33
-rw-r--r--server/src/test/java/com/vaadin/data/fieldgroup/FieldGroupTests.java95
-rw-r--r--server/src/test/java/com/vaadin/data/util/AbstractBeanContainerTestBase.java77
-rw-r--r--server/src/test/java/com/vaadin/data/util/AbstractContainerTestBase.java856
-rw-r--r--server/src/test/java/com/vaadin/data/util/AbstractHierarchicalContainerTestBase.java285
-rw-r--r--server/src/test/java/com/vaadin/data/util/AbstractInMemoryContainerTestBase.java6
-rw-r--r--server/src/test/java/com/vaadin/data/util/BeanContainerTest.java488
-rw-r--r--server/src/test/java/com/vaadin/data/util/BeanItemContainerGenerator.java150
-rw-r--r--server/src/test/java/com/vaadin/data/util/BeanItemContainerSortTest.java166
-rw-r--r--server/src/test/java/com/vaadin/data/util/BeanItemContainerTest.java969
-rw-r--r--server/src/test/java/com/vaadin/data/util/BeanItemTest.java375
-rw-r--r--server/src/test/java/com/vaadin/data/util/ContainerHierarchicalWrapperTest.java22
-rw-r--r--server/src/test/java/com/vaadin/data/util/ContainerOrderedWrapperTest.java102
-rw-r--r--server/src/test/java/com/vaadin/data/util/ContainerSizeAssertTest.java59
-rw-r--r--server/src/test/java/com/vaadin/data/util/ContainerSortingTest.java224
-rw-r--r--server/src/test/java/com/vaadin/data/util/FileSystemContainerTest.java16
-rw-r--r--server/src/test/java/com/vaadin/data/util/GeneratedPropertyContainerBasicTest.java561
-rw-r--r--server/src/test/java/com/vaadin/data/util/GeneratedPropertyContainerTest.java306
-rw-r--r--server/src/test/java/com/vaadin/data/util/HierarchicalContainerOrderedWrapperTest.java27
-rw-r--r--server/src/test/java/com/vaadin/data/util/HierarchicalContainerTest.java270
-rw-r--r--server/src/test/java/com/vaadin/data/util/IndexedContainerTest.java539
-rw-r--r--server/src/test/java/com/vaadin/data/util/MethodPropertyMemoryConsumptionTest.java145
-rw-r--r--server/src/test/java/com/vaadin/data/util/NestedMethodPropertyTest.java344
-rw-r--r--server/src/test/java/com/vaadin/data/util/ObjectPropertyTest.java97
-rw-r--r--server/src/test/java/com/vaadin/data/util/PerformanceTestIndexedContainerTest.java116
-rw-r--r--server/src/test/java/com/vaadin/data/util/PropertyDescriptorTest.java80
-rw-r--r--server/src/test/java/com/vaadin/data/util/PropertySetItemTest.java405
-rw-r--r--server/src/test/java/com/vaadin/data/util/ReflectToolsGetSuperFieldTest.java35
-rw-r--r--server/src/test/java/com/vaadin/data/util/TransactionalPropertyWrapperTest.java116
-rw-r--r--server/src/test/java/com/vaadin/data/util/filter/AbstractFilterTestBase.java97
-rw-r--r--server/src/test/java/com/vaadin/data/util/filter/AndOrFilterTest.java233
-rw-r--r--server/src/test/java/com/vaadin/data/util/filter/CompareFilterTest.java314
-rw-r--r--server/src/test/java/com/vaadin/data/util/filter/IsNullFilterTest.java57
-rw-r--r--server/src/test/java/com/vaadin/data/util/filter/LikeFilterTest.java46
-rw-r--r--server/src/test/java/com/vaadin/data/util/filter/NotFilterTest.java50
-rw-r--r--server/src/test/java/com/vaadin/data/util/filter/SimpleStringFilterTest.java130
-rw-r--r--server/src/test/java/com/vaadin/data/util/sqlcontainer/AllTests.java24
-rw-r--r--server/src/test/java/com/vaadin/data/util/sqlcontainer/ColumnPropertyTest.java315
-rw-r--r--server/src/test/java/com/vaadin/data/util/sqlcontainer/DataGenerator.java133
-rw-r--r--server/src/test/java/com/vaadin/data/util/sqlcontainer/FreeformQueryUtil.java65
-rw-r--r--server/src/test/java/com/vaadin/data/util/sqlcontainer/ReadOnlyRowIdTest.java55
-rw-r--r--server/src/test/java/com/vaadin/data/util/sqlcontainer/RowIdTest.java60
-rw-r--r--server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java1363
-rw-r--r--server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLContainerTest.java2477
-rwxr-xr-xserver/src/test/java/com/vaadin/data/util/sqlcontainer/SQLTestsConstants.java154
-rw-r--r--server/src/test/java/com/vaadin/data/util/sqlcontainer/TicketTests.java198
-rw-r--r--server/src/test/java/com/vaadin/data/util/sqlcontainer/UtilTest.java50
-rw-r--r--server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPoolTest.java107
-rw-r--r--server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/MockInitialContextFactory.java27
-rw-r--r--server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPoolTest.java183
-rw-r--r--server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/BetweenTest.java182
-rw-r--r--server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/CompareTest.java44
-rw-r--r--server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/LikeTest.java229
-rw-r--r--server/src/test/java/com/vaadin/data/util/sqlcontainer/generator/SQLGeneratorsTest.java242
-rw-r--r--server/src/test/java/com/vaadin/data/util/sqlcontainer/generator/StatementHelperTest.java64
-rw-r--r--server/src/test/java/com/vaadin/data/util/sqlcontainer/query/FreeformQueryTest.java1010
-rw-r--r--server/src/test/java/com/vaadin/data/util/sqlcontainer/query/QueryBuilderTest.java310
-rw-r--r--server/src/test/java/com/vaadin/data/util/sqlcontainer/query/TableQueryTest.java743
-rw-r--r--server/src/test/java/com/vaadin/data/util/sqlcontainer/query/ValidatingSimpleJDBCConnectionPool.java89
-rw-r--r--server/src/test/java/com/vaadin/server/AbstractClientConnectorProxyHandlingTest.java50
-rw-r--r--server/src/test/java/com/vaadin/server/AbstractClientConnectorTest.java112
-rw-r--r--server/src/test/java/com/vaadin/server/AbstractDeploymentConfigurationTest.java162
-rw-r--r--server/src/test/java/com/vaadin/server/BrowserWindowOpenerTest.java79
-rw-r--r--server/src/test/java/com/vaadin/server/ConnectorResourceHandlerTest.java97
-rw-r--r--server/src/test/java/com/vaadin/server/DefaultDeploymentConfigurationTest.java53
-rw-r--r--server/src/test/java/com/vaadin/server/DownloadStreamTest.java39
-rw-r--r--server/src/test/java/com/vaadin/server/DragAndDropServiceTest.java125
-rw-r--r--server/src/test/java/com/vaadin/server/JSONSerializerTest.java171
-rw-r--r--server/src/test/java/com/vaadin/server/JsonEqualsTest.java276
-rw-r--r--server/src/test/java/com/vaadin/server/MockServletConfig.java86
-rw-r--r--server/src/test/java/com/vaadin/server/MockServletContext.java569
-rw-r--r--server/src/test/java/com/vaadin/server/MockUIContainingServlet.java16
-rw-r--r--server/src/test/java/com/vaadin/server/MockVaadinSession.java70
-rw-r--r--server/src/test/java/com/vaadin/server/PageTest.java92
-rw-r--r--server/src/test/java/com/vaadin/server/TestAbstractApplicationServletStaticFilesLocation.java153
-rw-r--r--server/src/test/java/com/vaadin/server/VaadinGateInRequestTest.java39
-rw-r--r--server/src/test/java/com/vaadin/server/VaadinHttpAndPortletRequestTestBase.java138
-rw-r--r--server/src/test/java/com/vaadin/server/VaadinLiferayRequestTest.java39
-rw-r--r--server/src/test/java/com/vaadin/server/VaadinPortletRequestTests.java53
-rw-r--r--server/src/test/java/com/vaadin/server/VaadinPortletServiceTests.java219
-rw-r--r--server/src/test/java/com/vaadin/server/VaadinPortletTests.java94
-rw-r--r--server/src/test/java/com/vaadin/server/VaadinServiceTest.java142
-rw-r--r--server/src/test/java/com/vaadin/server/VaadinServletConfigurationTest.java135
-rw-r--r--server/src/test/java/com/vaadin/server/VaadinServletTest.java60
-rw-r--r--server/src/test/java/com/vaadin/server/VaadinSessionTest.java343
-rw-r--r--server/src/test/java/com/vaadin/server/VaadinWebSpherePortalRequestTest.java39
-rw-r--r--server/src/test/java/com/vaadin/server/communication/AtmospherePushConnectionTest.java56
-rw-r--r--server/src/test/java/com/vaadin/server/communication/FileUploadHandlerTest.java150
-rw-r--r--server/src/test/java/com/vaadin/server/communication/MetadataWriterTest.java109
-rw-r--r--server/src/test/java/com/vaadin/tests/CompileTransitionPropertyTest.java69
-rw-r--r--server/src/test/java/com/vaadin/tests/VaadinClasses.java259
-rw-r--r--server/src/test/java/com/vaadin/tests/components/draganddropwrapper/DragAndDropWrapperDeclarativeTest.java67
-rw-r--r--server/src/test/java/com/vaadin/tests/components/menubar/MenuBarDeclarativeTest.java198
-rw-r--r--server/src/test/java/com/vaadin/tests/data/bean/Address.java63
-rw-r--r--server/src/test/java/com/vaadin/tests/data/bean/AnotherTestEnum.java16
-rw-r--r--server/src/test/java/com/vaadin/tests/data/bean/BeanToValidate.java69
-rw-r--r--server/src/test/java/com/vaadin/tests/data/bean/BeanWithReadOnlyField.java18
-rw-r--r--server/src/test/java/com/vaadin/tests/data/bean/Country.java18
-rw-r--r--server/src/test/java/com/vaadin/tests/data/bean/Person.java143
-rw-r--r--server/src/test/java/com/vaadin/tests/data/bean/PersonWithBeanValidationAnnotations.java159
-rw-r--r--server/src/test/java/com/vaadin/tests/data/bean/Sex.java20
-rw-r--r--server/src/test/java/com/vaadin/tests/data/bean/TestEnum.java16
-rw-r--r--server/src/test/java/com/vaadin/tests/data/converter/AnyEnumToStringConverterTest.java127
-rw-r--r--server/src/test/java/com/vaadin/tests/data/converter/ConverterFactoryTest.java122
-rw-r--r--server/src/test/java/com/vaadin/tests/data/converter/DateToLongConverterTest.java21
-rw-r--r--server/src/test/java/com/vaadin/tests/data/converter/DateToSqlDateConverterTest.java25
-rw-r--r--server/src/test/java/com/vaadin/tests/data/converter/DefaultConverterFactoryTest.java128
-rw-r--r--server/src/test/java/com/vaadin/tests/data/converter/SpecificEnumToStringConverterTest.java125
-rw-r--r--server/src/test/java/com/vaadin/tests/data/converter/StringToBigDecimalConverterTest.java53
-rw-r--r--server/src/test/java/com/vaadin/tests/data/converter/StringToBigIntegerConverterTest.java57
-rw-r--r--server/src/test/java/com/vaadin/tests/data/converter/StringToBooleanConverterTest.java57
-rw-r--r--server/src/test/java/com/vaadin/tests/data/converter/StringToByteConverterTest.java69
-rw-r--r--server/src/test/java/com/vaadin/tests/data/converter/StringToCollectionConverterTest.java172
-rw-r--r--server/src/test/java/com/vaadin/tests/data/converter/StringToDateConverterTest.java26
-rw-r--r--server/src/test/java/com/vaadin/tests/data/converter/StringToDoubleConverterTest.java22
-rw-r--r--server/src/test/java/com/vaadin/tests/data/converter/StringToEnumConverterTest.java135
-rw-r--r--server/src/test/java/com/vaadin/tests/data/converter/StringToFloatConverterTest.java23
-rw-r--r--server/src/test/java/com/vaadin/tests/data/converter/StringToIntegerConverterTest.java41
-rw-r--r--server/src/test/java/com/vaadin/tests/data/converter/StringToLongConverterTest.java69
-rw-r--r--server/src/test/java/com/vaadin/tests/data/converter/StringToShortConverterTest.java70
-rw-r--r--server/src/test/java/com/vaadin/tests/data/validator/BigDecimalRangeValidatorTest.java55
-rw-r--r--server/src/test/java/com/vaadin/tests/data/validator/BigIntegerRangeValidatorTest.java55
-rw-r--r--server/src/test/java/com/vaadin/tests/data/validator/ByteRangeValidatorTest.java50
-rw-r--r--server/src/test/java/com/vaadin/tests/data/validator/CompositeValidatorTest.java116
-rw-r--r--server/src/test/java/com/vaadin/tests/data/validator/DateRangeValidatorTest.java97
-rw-r--r--server/src/test/java/com/vaadin/tests/data/validator/DoubleRangeValidatorTest.java45
-rw-r--r--server/src/test/java/com/vaadin/tests/data/validator/EmailValidatorTest.java26
-rw-r--r--server/src/test/java/com/vaadin/tests/data/validator/FloatRangeValidatorTest.java45
-rw-r--r--server/src/test/java/com/vaadin/tests/data/validator/IntegerRangeValidatorTest.java45
-rw-r--r--server/src/test/java/com/vaadin/tests/data/validator/LongRangeValidatorTest.java45
-rw-r--r--server/src/test/java/com/vaadin/tests/data/validator/NullValidatorTest.java40
-rw-r--r--server/src/test/java/com/vaadin/tests/data/validator/RegexpValidatorTest.java44
-rw-r--r--server/src/test/java/com/vaadin/tests/data/validator/ShortRangeValidatorTest.java52
-rw-r--r--server/src/test/java/com/vaadin/tests/data/validator/StringLengthValidatorTest.java65
-rw-r--r--server/src/test/java/com/vaadin/tests/design/AbstractComponentSetResponsiveTest.java36
-rw-r--r--server/src/test/java/com/vaadin/tests/design/ComponentFactoryTest.java144
-rw-r--r--server/src/test/java/com/vaadin/tests/design/ComponentMapperTest.java129
-rw-r--r--server/src/test/java/com/vaadin/tests/design/DeclarativeTestBase.java130
-rw-r--r--server/src/test/java/com/vaadin/tests/design/DeclarativeTestBaseBase.java270
-rw-r--r--server/src/test/java/com/vaadin/tests/design/DesignContextLocalIdTest.java129
-rw-r--r--server/src/test/java/com/vaadin/tests/design/DesignFormatterTest.java377
-rw-r--r--server/src/test/java/com/vaadin/tests/design/DesignReadInConstructor.java28
-rw-r--r--server/src/test/java/com/vaadin/tests/design/DesignReadInConstructorTest.java77
-rw-r--r--server/src/test/java/com/vaadin/tests/design/DesignTest.java128
-rw-r--r--server/src/test/java/com/vaadin/tests/design/EmbeddedsTest.java105
-rw-r--r--server/src/test/java/com/vaadin/tests/design/FieldNameWhichConflictsWithGettersTest.java82
-rw-r--r--server/src/test/java/com/vaadin/tests/design/InvalidLayoutTemplate.java55
-rw-r--r--server/src/test/java/com/vaadin/tests/design/InvalidTagNames.java103
-rw-r--r--server/src/test/java/com/vaadin/tests/design/LayoutTemplate.java49
-rw-r--r--server/src/test/java/com/vaadin/tests/design/LocaleTest.java181
-rw-r--r--server/src/test/java/com/vaadin/tests/design/ParseAllSupportedComponentsTest.java45
-rw-r--r--server/src/test/java/com/vaadin/tests/design/ParseLayoutTest.java219
-rw-r--r--server/src/test/java/com/vaadin/tests/design/ParseLegacyPrefixTest.java44
-rw-r--r--server/src/test/java/com/vaadin/tests/design/ParseMixedLegacyAndNewPrefixTest.java35
-rw-r--r--server/src/test/java/com/vaadin/tests/design/WriteLegacyDesignTest.java99
-rw-r--r--server/src/test/java/com/vaadin/tests/design/designroot/DesignRootTest.java54
-rw-r--r--server/src/test/java/com/vaadin/tests/design/designroot/DesignWithAnnotation.java34
-rw-r--r--server/src/test/java/com/vaadin/tests/design/designroot/DesignWithEmptyAnnotation.java34
-rw-r--r--server/src/test/java/com/vaadin/tests/design/designroot/ExtendedDesignWithAnnotation.java28
-rw-r--r--server/src/test/java/com/vaadin/tests/design/designroot/ExtendedDesignWithEmptyAnnotation.java47
-rw-r--r--server/src/test/java/com/vaadin/tests/design/designroot/ExtendedDesignWithEmptyAnnotationUI.java29
-rw-r--r--server/src/test/java/com/vaadin/tests/design/nested/MyChildDesign.java37
-rw-r--r--server/src/test/java/com/vaadin/tests/design/nested/MyChildDesignCustomComponent.java22
-rw-r--r--server/src/test/java/com/vaadin/tests/design/nested/MyDesignRoot.java35
-rw-r--r--server/src/test/java/com/vaadin/tests/design/nested/MyExtendedChildDesign.java22
-rw-r--r--server/src/test/java/com/vaadin/tests/design/nested/NestedCustomLayoutsTest.java82
-rw-r--r--server/src/test/java/com/vaadin/tests/design/nested/ReadNestedTemplatesTest.java71
-rw-r--r--server/src/test/java/com/vaadin/tests/design/nested/WriteNestedTemplatesTest.java93
-rw-r--r--server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomAbsoluteLayout.java28
-rw-r--r--server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomAccordion.java28
-rw-r--r--server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomCssLayout.java28
-rw-r--r--server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomFormLayout.java28
-rw-r--r--server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomGridLayout.java28
-rw-r--r--server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomHorizontalLayout.java28
-rw-r--r--server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomHorizontalSplitPanel.java28
-rw-r--r--server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomPanel.java28
-rw-r--r--server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomTabSheet.java28
-rw-r--r--server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomVerticalLayout.java28
-rw-r--r--server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomVerticalSplitPanel.java28
-rw-r--r--server/src/test/java/com/vaadin/tests/event/EventRouterTest.java111
-rw-r--r--server/src/test/java/com/vaadin/tests/event/ShortcutActionTest.java115
-rw-r--r--server/src/test/java/com/vaadin/tests/server/AbstractBeanContainerListenersTest.java16
-rw-r--r--server/src/test/java/com/vaadin/tests/server/AbstractContainerListenersTest.java22
-rw-r--r--server/src/test/java/com/vaadin/tests/server/AbstractInMemoryContainerListenersTest.java14
-rw-r--r--server/src/test/java/com/vaadin/tests/server/AbstractPropertyListenersTest.java25
-rw-r--r--server/src/test/java/com/vaadin/tests/server/AssertionsEnabledTest.java33
-rw-r--r--server/src/test/java/com/vaadin/tests/server/AtmosphereVersionTest.java18
-rw-r--r--server/src/test/java/com/vaadin/tests/server/ClassesSerializableTest.java325
-rw-r--r--server/src/test/java/com/vaadin/tests/server/ClientMethodSerializationTest.java145
-rw-r--r--server/src/test/java/com/vaadin/tests/server/ContextClickListenerTest.java163
-rw-r--r--server/src/test/java/com/vaadin/tests/server/CsrfTokenMissingTest.java253
-rw-r--r--server/src/test/java/com/vaadin/tests/server/EventRouterTest.java39
-rw-r--r--server/src/test/java/com/vaadin/tests/server/ExtensionTest.java40
-rw-r--r--server/src/test/java/com/vaadin/tests/server/FileResourceTest.java36
-rw-r--r--server/src/test/java/com/vaadin/tests/server/FileTypeResolverTest.java79
-rw-r--r--server/src/test/java/com/vaadin/tests/server/IndexedContainerListenersTest.java21
-rw-r--r--server/src/test/java/com/vaadin/tests/server/KeyMapperTest.java102
-rw-r--r--server/src/test/java/com/vaadin/tests/server/MimeTypesTest.java17
-rw-r--r--server/src/test/java/com/vaadin/tests/server/PropertyFormatterTest.java75
-rw-r--r--server/src/test/java/com/vaadin/tests/server/PropertysetItemListenersTest.java14
-rw-r--r--server/src/test/java/com/vaadin/tests/server/SerializationTest.java139
-rw-r--r--server/src/test/java/com/vaadin/tests/server/SimpleMultiPartInputStreamTest.java138
-rw-r--r--server/src/test/java/com/vaadin/tests/server/StreamResourceTest.java55
-rw-r--r--server/src/test/java/com/vaadin/tests/server/StreamVariableMappingTest.java88
-rw-r--r--server/src/test/java/com/vaadin/tests/server/clientconnector/AttachDetachListenersTest.java195
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/AbstractListenerMethodsTestBase.java173
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/ComponentSizeParseTest.java61
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/DeclarativeMarginTestBase.java72
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/FieldDefaultValues.java73
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/FinalMethodTest.java68
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/ReadEmptyDesignTest.java78
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/StateGetDoesNotMarkDirtyTest.java100
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/WriteEmptyDesignTest.java58
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/absolutelayout/AbsoluteLayoutDeclarativeTest.java60
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/absolutelayout/AbsoluteLayoutListenersTest.java14
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/absolutelayout/AddComponentsTest.java43
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/absolutelayout/ComponentPositionTest.java204
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentDeclarativeTest.java243
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentStyleNamesTest.java61
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractcomponentcontainer/AbstractComponentContainerListenersTest.java22
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractcomponentcontainer/AddParentAsChildTest.java64
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbsFieldValidatorsTest.java117
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbsFieldValueConversionErrorTest.java87
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbsFieldValueConversionsTest.java266
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbstractFieldDeclarativeTest.java71
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbstractFieldListenersTest.java21
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractfield/DefaultConverterFactoryTest.java133
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractfield/RemoveListenersOnDetachTest.java106
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractorderedlayout/AbstractOrderedLayoutDeclarativeTest.java129
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractorderedlayout/AbstractOrderedLayoutListenersTest.java14
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractorderedlayout/AddComponentsTest.java154
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractorderedlayout/LayoutSettingsOnReplaceTest.java85
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractselect/AbstractSelectDeclarativeTest.java305
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractselect/AbstractSelectListenersTest.java21
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractselect/AbstractSelectStateTest.java60
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractselect/OptionGroupDeclarativeTests.java160
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractselect/OptionGroupTests.java32
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractsinglecomponentcontainer/RemoveFromParentLockingTest.java129
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractsinglecomponentcontainer/SetParentAsContentTest.java45
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractsplitpanel/AbstractSplitPanelDeclarativeTest.java86
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractsplitpanel/AbstractSplitPanelListenersTest.java14
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstracttextfield/AbstractTextFieldDeclarativeTest.java52
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstracttextfield/AbstractTextFieldListenersTest.java28
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/audio/AudioDeclarativeTest.java63
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/audio/AudioStateTest.java59
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/audio/VideoDeclarativeTest.java59
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/browserframe/BrowserFrameDeclarativeTest.java57
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/button/ButtonClickTest.java84
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/button/ButtonDeclarativeTest.java149
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/button/ButtonListenersTest.java27
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/calendar/CalendarBasicsTest.java290
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/calendar/CalendarDeclarativeTest.java61
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/calendar/ContainerDataSourceTest.java394
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/calendar/ContainerEventProviderTest.java88
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/checkbox/CheckboxDeclarativeTest.java57
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/colorpicker/AbstractColorPickerDeclarativeTest.java87
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/colorpicker/ColorConversionsTest.java57
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/combobox/ComboBoxDeclarativeTest.java88
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/combobox/ComboBoxStateTest.java59
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/csslayout/AddComponentsTest.java130
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/csslayout/CssLayoutDeclarativeTest.java63
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/csslayout/CssLayoutListenersTest.java13
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/customlayout/CustomLayoutDeclarativeTest.java96
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/customlayout/CustomLayoutTest.java148
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldConverterTest.java77
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldDeclarativeTest.java102
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldListenersTest.java20
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/datefield/InlineDateFieldDeclarativeTest.java62
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/datefield/PopupDateFieldDeclarativeTest.java62
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/datefield/ResolutionTest.java61
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/embedded/EmbeddedListenersTest.java13
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/fieldgroup/BeanFieldGroupTest.java171
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/fieldgroup/CaseInsensitiveBindingTest.java85
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/fieldgroup/FieldGroupTest.java149
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/fieldgroup/FieldGroupWithReadOnlyPropertiesTest.java51
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/fieldgroup/FieldNamedDescriptionTest.java53
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/flash/FlashDeclarativeTest.java67
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/form/FormTest.java68
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/grid/GridAddRowBuiltinContainerTest.java219
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/grid/GridChildren.java59
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/grid/GridColumnAddingAndRemovingTest.java134
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/grid/GridColumns.java414
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/grid/GridContainerNotSortableTest.java103
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/grid/GridContainerTest.java122
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/grid/GridEditorTest.java294
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/grid/GridExtensionTest.java41
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/grid/GridSelection.java374
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/grid/GridStateTest.java44
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/grid/GridStaticSectionTest.java132
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/grid/MultiSelectionModelTest.java171
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/grid/SingleSelectionModelTest.java154
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/grid/TestGrid.java62
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/grid/declarative/GridColumnDeclarativeTest.java103
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/grid/declarative/GridDeclarativeAttributeTest.java84
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/grid/declarative/GridDeclarativeTestBase.java158
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/grid/declarative/GridHeaderFooterDeclarativeTest.java356
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/grid/declarative/GridInlineDataDeclarativeTest.java130
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/grid/declarative/GridStructureDeclarativeTest.java50
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/grid/sort/SortTest.java203
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/gridlayout/DefaultAlignmentTest.java45
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/gridlayout/GridLayoutDeclarativeTest.java288
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/gridlayout/GridLayoutListenersTest.java13
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/gridlayout/GridLayoutTest.java108
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/image/ImageDeclarativeTest.java58
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/label/LabelConvertersTest.java87
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/label/LabelDeclarativeTest.java159
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/label/LabelListenersTest.java92
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/link/LinkDeclarativeTest.java66
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/listselect/ListSelectDeclarativeTest.java70
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/listselect/ListSelectStateTest.java45
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/loginform/LoginFormListenersTest.java13
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/menubar/MenuBarIdsTest.java98
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/nativeselect/NativeSelectDeclarativeTest.java69
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/optiongroup/OptionGroupListenersTest.java20
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/optiongroup/OptionGroupStateTest.java60
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/orderedlayout/DefaultAlignmentTest.java67
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/orderedlayout/OrderedLayoutTest.java49
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/panel/PanelDeclarativeTest.java62
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/panel/PanelListenersTest.java13
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/passwordfield/PasswordFieldDeclarativeTest.java40
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/popupview/PopupViewDeclarativeTest.java74
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/popupview/PopupViewListenersTest.java14
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/progressbar/ProgressBarDeclarativeTest.java74
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/richtextarea/RichTextAreaDeclarativeTest.java70
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/richtextarea/RichTextAreaStateTest.java59
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/select/SelectListenersTest.java20
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/slider/SliderDeclarativeTest.java81
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/slider/SliderTest.java135
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/table/CacheUpdateExceptionCausesTest.java55
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/table/FooterTest.java94
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/table/MultipleSelectionTest.java57
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/table/TableColumnAlignmentsTest.java143
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/table/TableContextClickTest.java57
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/table/TableDeclarativeTest.java197
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/table/TableDeclarativeTestBase.java74
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/table/TableGeneratorTest.java42
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/table/TableListenersTest.java41
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/table/TablePropertyValueConverterTest.java380
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/table/TableSelectable.java75
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/table/TableSerializationTest.java25
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/table/TableStateTest.java60
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/table/TableVisibleColumnsTest.java70
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/tabsheet/TabSheetDeclarativeTest.java87
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/tabsheet/TabSheetListenersTest.java13
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/tabsheet/TabSheetTest.java286
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/textarea/TextAreaDeclarativeTest.java74
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/textfield/TextFieldDeclarativeTest.java57
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/textfield/TextFieldWithConverterAndValidatorTest.java49
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/textfield/TextFieldWithPropertyFormatterTest.java106
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/textfield/TextFieldWithValidatorTest.java172
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/tree/ListenersTest.java137
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/tree/TreeDeclarativeTest.java81
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/tree/TreeListenersTest.java27
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/tree/TreeTest.java178
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/treetable/EmptyTreeTableTest.java13
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableDeclarativeTest.java156
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableSetContainerNullTest.java15
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableTest.java101
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/twincolselect/TwinColSelectDeclarativeTest.java74
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/twincolselect/TwinColSelectStateTest.java60
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/ui/CustomUIClassLoaderTest.java124
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/ui/LegacyUIAddRemoveComponentsTest.java65
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/upload/UploadDeclarativeTest.java61
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/upload/UploadListenersTest.java41
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/upload/UploadTest.java130
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/window/AddRemoveSubWindowTest.java82
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/window/AttachDetachWindowTest.java314
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/window/WindowAttachTest.java44
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/window/WindowDeclarativeTest.java193
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/window/WindowListenersTest.java34
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/window/WindowTest.java60
-rw-r--r--server/src/test/java/com/vaadin/tests/server/componentcontainer/AbstractIndexedLayoutTestBase.java84
-rw-r--r--server/src/test/java/com/vaadin/tests/server/componentcontainer/AddRemoveComponentTest.java42
-rw-r--r--server/src/test/java/com/vaadin/tests/server/componentcontainer/CssLayoutTest.java34
-rw-r--r--server/src/test/java/com/vaadin/tests/server/componentcontainer/FormLayoutTest.java105
-rw-r--r--server/src/test/java/com/vaadin/tests/server/componentcontainer/VerticalLayoutTest.java34
-rw-r--r--server/src/test/java/com/vaadin/tests/server/components/AbstractFieldValueChangeTestBase.java129
-rw-r--r--server/src/test/java/com/vaadin/tests/server/components/ComboBoxValueChangeTest.java31
-rw-r--r--server/src/test/java/com/vaadin/tests/server/components/ComponentAttachDetachListenerTest.java395
-rw-r--r--server/src/test/java/com/vaadin/tests/server/components/GridLayoutLastRowRemovalTest.java40
-rw-r--r--server/src/test/java/com/vaadin/tests/server/components/TextFieldValueChangeTest.java125
-rw-r--r--server/src/test/java/com/vaadin/tests/server/components/WindowTest.java92
-rw-r--r--server/src/test/java/com/vaadin/tests/server/navigator/ClassBasedViewProviderTest.java131
-rw-r--r--server/src/test/java/com/vaadin/tests/server/navigator/NavigatorTest.java824
-rw-r--r--server/src/test/java/com/vaadin/tests/server/navigator/UriFragmentManagerTest.java126
-rw-r--r--server/src/test/java/com/vaadin/tests/server/renderer/ImageRendererTest.java85
-rw-r--r--server/src/test/java/com/vaadin/tests/server/renderer/RendererTest.java267
-rw-r--r--server/src/test/java/com/vaadin/tests/server/validation/BeanValidationTest.java125
-rw-r--r--server/src/test/java/com/vaadin/tests/server/validation/RangeValidatorTest.java52
-rw-r--r--server/src/test/java/com/vaadin/tests/server/validation/ReadOnlyValidationTest.java17
-rw-r--r--server/src/test/java/com/vaadin/tests/util/AlwaysLockedVaadinSession.java13
-rw-r--r--server/src/test/java/com/vaadin/tests/util/GraphVizClassHierarchyCreator.java149
-rw-r--r--server/src/test/java/com/vaadin/tests/util/MockDeploymentConfiguration.java128
-rw-r--r--server/src/test/java/com/vaadin/tests/util/MockUI.java46
-rw-r--r--server/src/test/java/com/vaadin/tests/util/TestUtil.java43
-rw-r--r--server/src/test/java/com/vaadin/tests/util/UniqueSerializableTest.java45
-rw-r--r--server/src/test/java/com/vaadin/ui/AbsFieldDataSourceLocaleChangeTest.java62
-rw-r--r--server/src/test/java/com/vaadin/ui/AbsSelectTest.java147
-rw-r--r--server/src/test/java/com/vaadin/ui/CheckBoxTest.java48
-rw-r--r--server/src/test/java/com/vaadin/ui/DateFieldTests.java56
-rw-r--r--server/src/test/java/com/vaadin/ui/GridLayoutExpandRatioTest.java113
-rw-r--r--server/src/test/java/com/vaadin/ui/HorizontalSplitPanelTest.java30
-rw-r--r--server/src/test/java/com/vaadin/ui/LabelDataSourceTest.java117
-rw-r--r--server/src/test/java/com/vaadin/ui/NativeSelectTest.java70
-rw-r--r--server/src/test/java/com/vaadin/ui/PushConfigurationTransportTest.java52
-rw-r--r--server/src/test/java/com/vaadin/ui/RichTextAreaTest.java47
-rw-r--r--server/src/test/java/com/vaadin/ui/SplitPositionChangeListenerTest.java44
-rw-r--r--server/src/test/java/com/vaadin/ui/TableTest.java78
-rw-r--r--server/src/test/java/com/vaadin/ui/TextAreaTest.java47
-rw-r--r--server/src/test/java/com/vaadin/ui/TextFieldTest.java48
-rw-r--r--server/src/test/java/com/vaadin/ui/UIInitRefreshTest.java116
-rw-r--r--server/src/test/java/com/vaadin/ui/UIThemeEscapingTest.java89
-rw-r--r--server/src/test/java/com/vaadin/ui/VerticalSplitPanelTest.java30
-rw-r--r--server/src/test/java/com/vaadin/ui/declarative/DesignTest.java129
-rw-r--r--server/src/test/java/com/vaadin/util/CurrentInstanceTest.java248
-rw-r--r--server/src/test/java/com/vaadin/util/ReflectToolsGetFieldValueByTypeTest.java63
-rw-r--r--server/src/test/java/com/vaadin/util/ReflectToolsGetPrimitiveFieldValueTest.java26
-rw-r--r--server/src/test/resources/com/vaadin/tests/design/DesignReadInConstructor.html5
-rw-r--r--server/src/test/resources/com/vaadin/tests/design/MyVerticalLayout.html4
-rw-r--r--server/src/test/resources/com/vaadin/tests/design/all-components-legacy.html122
-rw-r--r--server/src/test/resources/com/vaadin/tests/design/all-components.html122
-rw-r--r--server/src/test/resources/com/vaadin/tests/design/designroot/DesignWithEmptyAnnotation.html5
-rw-r--r--server/src/test/resources/com/vaadin/tests/design/duplicate-ids.html4
-rw-r--r--server/src/test/resources/com/vaadin/tests/design/duplicate-local-ids.html4
-rw-r--r--server/src/test/resources/com/vaadin/tests/design/local-ids.html4
-rw-r--r--server/src/test/resources/com/vaadin/tests/design/nested/mychilddesign.html12
-rw-r--r--server/src/test/resources/com/vaadin/tests/design/nested/mydesignroot.html10
-rw-r--r--server/src/test/resources/com/vaadin/tests/design/testFile-legacy.html19
-rw-r--r--server/src/test/resources/com/vaadin/tests/design/testFile.html19
-rw-r--r--server/src/test/resources/com/vaadin/tests/design/verticallayout-one-child.html3
-rw-r--r--server/src/test/resources/com/vaadin/tests/design/verticallayout-two-children.html4
-rw-r--r--server/src/test/resources/com/vaadin/tests/styles.scss5
951 files changed, 50887 insertions, 0 deletions
diff --git a/server/src/com/vaadin/annotations/AutoGenerated.java b/server/src/main/java/com/vaadin/annotations/AutoGenerated.java
index 1ad9f67ad1..1ad9f67ad1 100644
--- a/server/src/com/vaadin/annotations/AutoGenerated.java
+++ b/server/src/main/java/com/vaadin/annotations/AutoGenerated.java
diff --git a/server/src/com/vaadin/annotations/DesignRoot.java b/server/src/main/java/com/vaadin/annotations/DesignRoot.java
index a00a00dc0b..a00a00dc0b 100644
--- a/server/src/com/vaadin/annotations/DesignRoot.java
+++ b/server/src/main/java/com/vaadin/annotations/DesignRoot.java
diff --git a/server/src/com/vaadin/annotations/JavaScript.java b/server/src/main/java/com/vaadin/annotations/JavaScript.java
index 445ef75ddf..445ef75ddf 100644
--- a/server/src/com/vaadin/annotations/JavaScript.java
+++ b/server/src/main/java/com/vaadin/annotations/JavaScript.java
diff --git a/server/src/com/vaadin/annotations/PreserveOnRefresh.java b/server/src/main/java/com/vaadin/annotations/PreserveOnRefresh.java
index 7f4ef3ffe5..7f4ef3ffe5 100644
--- a/server/src/com/vaadin/annotations/PreserveOnRefresh.java
+++ b/server/src/main/java/com/vaadin/annotations/PreserveOnRefresh.java
diff --git a/server/src/com/vaadin/annotations/Push.java b/server/src/main/java/com/vaadin/annotations/Push.java
index b6a28c1560..b6a28c1560 100644
--- a/server/src/com/vaadin/annotations/Push.java
+++ b/server/src/main/java/com/vaadin/annotations/Push.java
diff --git a/server/src/com/vaadin/annotations/StyleSheet.java b/server/src/main/java/com/vaadin/annotations/StyleSheet.java
index 191e39ee24..191e39ee24 100644
--- a/server/src/com/vaadin/annotations/StyleSheet.java
+++ b/server/src/main/java/com/vaadin/annotations/StyleSheet.java
diff --git a/server/src/com/vaadin/annotations/Theme.java b/server/src/main/java/com/vaadin/annotations/Theme.java
index 61c47389ad..61c47389ad 100644
--- a/server/src/com/vaadin/annotations/Theme.java
+++ b/server/src/main/java/com/vaadin/annotations/Theme.java
diff --git a/server/src/com/vaadin/annotations/Title.java b/server/src/main/java/com/vaadin/annotations/Title.java
index 38a3d75f17..38a3d75f17 100644
--- a/server/src/com/vaadin/annotations/Title.java
+++ b/server/src/main/java/com/vaadin/annotations/Title.java
diff --git a/server/src/com/vaadin/annotations/VaadinServletConfiguration.java b/server/src/main/java/com/vaadin/annotations/VaadinServletConfiguration.java
index 00af38ecc1..00af38ecc1 100644
--- a/server/src/com/vaadin/annotations/VaadinServletConfiguration.java
+++ b/server/src/main/java/com/vaadin/annotations/VaadinServletConfiguration.java
diff --git a/server/src/com/vaadin/annotations/Viewport.java b/server/src/main/java/com/vaadin/annotations/Viewport.java
index c5b0abd56f..c5b0abd56f 100644
--- a/server/src/com/vaadin/annotations/Viewport.java
+++ b/server/src/main/java/com/vaadin/annotations/Viewport.java
diff --git a/server/src/com/vaadin/annotations/ViewportGeneratorClass.java b/server/src/main/java/com/vaadin/annotations/ViewportGeneratorClass.java
index aec7ac07e6..aec7ac07e6 100644
--- a/server/src/com/vaadin/annotations/ViewportGeneratorClass.java
+++ b/server/src/main/java/com/vaadin/annotations/ViewportGeneratorClass.java
diff --git a/server/src/com/vaadin/annotations/Widgetset.java b/server/src/main/java/com/vaadin/annotations/Widgetset.java
index c6ef6a7194..c6ef6a7194 100644
--- a/server/src/com/vaadin/annotations/Widgetset.java
+++ b/server/src/main/java/com/vaadin/annotations/Widgetset.java
diff --git a/server/src/com/vaadin/data/Buffered.java b/server/src/main/java/com/vaadin/data/Buffered.java
index 469f9987a4..469f9987a4 100644
--- a/server/src/com/vaadin/data/Buffered.java
+++ b/server/src/main/java/com/vaadin/data/Buffered.java
diff --git a/server/src/com/vaadin/data/BufferedValidatable.java b/server/src/main/java/com/vaadin/data/BufferedValidatable.java
index 6f9d952d2f..6f9d952d2f 100644
--- a/server/src/com/vaadin/data/BufferedValidatable.java
+++ b/server/src/main/java/com/vaadin/data/BufferedValidatable.java
diff --git a/server/src/com/vaadin/data/Collapsible.java b/server/src/main/java/com/vaadin/data/Collapsible.java
index 0ef290312d..0ef290312d 100644
--- a/server/src/com/vaadin/data/Collapsible.java
+++ b/server/src/main/java/com/vaadin/data/Collapsible.java
diff --git a/server/src/com/vaadin/data/Container.java b/server/src/main/java/com/vaadin/data/Container.java
index fb7a93e832..fb7a93e832 100644
--- a/server/src/com/vaadin/data/Container.java
+++ b/server/src/main/java/com/vaadin/data/Container.java
diff --git a/server/src/com/vaadin/data/ContainerHelpers.java b/server/src/main/java/com/vaadin/data/ContainerHelpers.java
index 817bec9474..817bec9474 100644
--- a/server/src/com/vaadin/data/ContainerHelpers.java
+++ b/server/src/main/java/com/vaadin/data/ContainerHelpers.java
diff --git a/server/src/com/vaadin/data/Item.java b/server/src/main/java/com/vaadin/data/Item.java
index 13f965f098..13f965f098 100644
--- a/server/src/com/vaadin/data/Item.java
+++ b/server/src/main/java/com/vaadin/data/Item.java
diff --git a/server/src/com/vaadin/data/Property.java b/server/src/main/java/com/vaadin/data/Property.java
index 74ae1f86ec..74ae1f86ec 100644
--- a/server/src/com/vaadin/data/Property.java
+++ b/server/src/main/java/com/vaadin/data/Property.java
diff --git a/server/src/com/vaadin/data/Validatable.java b/server/src/main/java/com/vaadin/data/Validatable.java
index 1ae7cd8cee..1ae7cd8cee 100644
--- a/server/src/com/vaadin/data/Validatable.java
+++ b/server/src/main/java/com/vaadin/data/Validatable.java
diff --git a/server/src/com/vaadin/data/Validator.java b/server/src/main/java/com/vaadin/data/Validator.java
index d567267338..d567267338 100644
--- a/server/src/com/vaadin/data/Validator.java
+++ b/server/src/main/java/com/vaadin/data/Validator.java
diff --git a/server/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java b/server/src/main/java/com/vaadin/data/fieldgroup/BeanFieldGroup.java
index 0a92c00cad..0a92c00cad 100644
--- a/server/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java
+++ b/server/src/main/java/com/vaadin/data/fieldgroup/BeanFieldGroup.java
diff --git a/server/src/com/vaadin/data/fieldgroup/Caption.java b/server/src/main/java/com/vaadin/data/fieldgroup/Caption.java
index efe6f99d9a..efe6f99d9a 100644
--- a/server/src/com/vaadin/data/fieldgroup/Caption.java
+++ b/server/src/main/java/com/vaadin/data/fieldgroup/Caption.java
diff --git a/server/src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java b/server/src/main/java/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java
index b6bf97e68e..b6bf97e68e 100644
--- a/server/src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java
+++ b/server/src/main/java/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java
diff --git a/server/src/com/vaadin/data/fieldgroup/FieldGroup.java b/server/src/main/java/com/vaadin/data/fieldgroup/FieldGroup.java
index aaaae9e4f7..aaaae9e4f7 100644
--- a/server/src/com/vaadin/data/fieldgroup/FieldGroup.java
+++ b/server/src/main/java/com/vaadin/data/fieldgroup/FieldGroup.java
diff --git a/server/src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java b/server/src/main/java/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java
index 4aad08ba8d..4aad08ba8d 100644
--- a/server/src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java
+++ b/server/src/main/java/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java
diff --git a/server/src/com/vaadin/data/fieldgroup/PropertyId.java b/server/src/main/java/com/vaadin/data/fieldgroup/PropertyId.java
index e7fe50305e..e7fe50305e 100644
--- a/server/src/com/vaadin/data/fieldgroup/PropertyId.java
+++ b/server/src/main/java/com/vaadin/data/fieldgroup/PropertyId.java
diff --git a/server/src/com/vaadin/data/sort/Sort.java b/server/src/main/java/com/vaadin/data/sort/Sort.java
index 81e0d08c73..81e0d08c73 100644
--- a/server/src/com/vaadin/data/sort/Sort.java
+++ b/server/src/main/java/com/vaadin/data/sort/Sort.java
diff --git a/server/src/com/vaadin/data/sort/SortOrder.java b/server/src/main/java/com/vaadin/data/sort/SortOrder.java
index 2c419f88b7..2c419f88b7 100644
--- a/server/src/com/vaadin/data/sort/SortOrder.java
+++ b/server/src/main/java/com/vaadin/data/sort/SortOrder.java
diff --git a/server/src/com/vaadin/data/util/AbstractBeanContainer.java b/server/src/main/java/com/vaadin/data/util/AbstractBeanContainer.java
index 6dcfbb2b84..6dcfbb2b84 100644
--- a/server/src/com/vaadin/data/util/AbstractBeanContainer.java
+++ b/server/src/main/java/com/vaadin/data/util/AbstractBeanContainer.java
diff --git a/server/src/com/vaadin/data/util/AbstractContainer.java b/server/src/main/java/com/vaadin/data/util/AbstractContainer.java
index dafdd15b06..dafdd15b06 100644
--- a/server/src/com/vaadin/data/util/AbstractContainer.java
+++ b/server/src/main/java/com/vaadin/data/util/AbstractContainer.java
diff --git a/server/src/com/vaadin/data/util/AbstractInMemoryContainer.java b/server/src/main/java/com/vaadin/data/util/AbstractInMemoryContainer.java
index f7b1a4b0d8..f7b1a4b0d8 100644
--- a/server/src/com/vaadin/data/util/AbstractInMemoryContainer.java
+++ b/server/src/main/java/com/vaadin/data/util/AbstractInMemoryContainer.java
diff --git a/server/src/com/vaadin/data/util/AbstractProperty.java b/server/src/main/java/com/vaadin/data/util/AbstractProperty.java
index ee79fcd91e..ee79fcd91e 100644
--- a/server/src/com/vaadin/data/util/AbstractProperty.java
+++ b/server/src/main/java/com/vaadin/data/util/AbstractProperty.java
diff --git a/server/src/com/vaadin/data/util/BeanContainer.java b/server/src/main/java/com/vaadin/data/util/BeanContainer.java
index 9b878d627e..9b878d627e 100644
--- a/server/src/com/vaadin/data/util/BeanContainer.java
+++ b/server/src/main/java/com/vaadin/data/util/BeanContainer.java
diff --git a/server/src/com/vaadin/data/util/BeanItem.java b/server/src/main/java/com/vaadin/data/util/BeanItem.java
index 71f51c3feb..71f51c3feb 100644
--- a/server/src/com/vaadin/data/util/BeanItem.java
+++ b/server/src/main/java/com/vaadin/data/util/BeanItem.java
diff --git a/server/src/com/vaadin/data/util/BeanItemContainer.java b/server/src/main/java/com/vaadin/data/util/BeanItemContainer.java
index d5d399f0f8..d5d399f0f8 100644
--- a/server/src/com/vaadin/data/util/BeanItemContainer.java
+++ b/server/src/main/java/com/vaadin/data/util/BeanItemContainer.java
diff --git a/server/src/com/vaadin/data/util/BeanUtil.java b/server/src/main/java/com/vaadin/data/util/BeanUtil.java
index 1356cf5359..1356cf5359 100644
--- a/server/src/com/vaadin/data/util/BeanUtil.java
+++ b/server/src/main/java/com/vaadin/data/util/BeanUtil.java
diff --git a/server/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java b/server/src/main/java/com/vaadin/data/util/ContainerHierarchicalWrapper.java
index 199d186fab..199d186fab 100644
--- a/server/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java
+++ b/server/src/main/java/com/vaadin/data/util/ContainerHierarchicalWrapper.java
diff --git a/server/src/com/vaadin/data/util/ContainerOrderedWrapper.java b/server/src/main/java/com/vaadin/data/util/ContainerOrderedWrapper.java
index 4329219e96..4329219e96 100644
--- a/server/src/com/vaadin/data/util/ContainerOrderedWrapper.java
+++ b/server/src/main/java/com/vaadin/data/util/ContainerOrderedWrapper.java
diff --git a/server/src/com/vaadin/data/util/DefaultItemSorter.java b/server/src/main/java/com/vaadin/data/util/DefaultItemSorter.java
index 9728ccbd51..9728ccbd51 100644
--- a/server/src/com/vaadin/data/util/DefaultItemSorter.java
+++ b/server/src/main/java/com/vaadin/data/util/DefaultItemSorter.java
diff --git a/server/src/com/vaadin/data/util/FilesystemContainer.java b/server/src/main/java/com/vaadin/data/util/FilesystemContainer.java
index 7ceda49918..7ceda49918 100644
--- a/server/src/com/vaadin/data/util/FilesystemContainer.java
+++ b/server/src/main/java/com/vaadin/data/util/FilesystemContainer.java
diff --git a/server/src/com/vaadin/data/util/GeneratedPropertyContainer.java b/server/src/main/java/com/vaadin/data/util/GeneratedPropertyContainer.java
index 98dd3ed0c1..98dd3ed0c1 100644
--- a/server/src/com/vaadin/data/util/GeneratedPropertyContainer.java
+++ b/server/src/main/java/com/vaadin/data/util/GeneratedPropertyContainer.java
diff --git a/server/src/com/vaadin/data/util/HierarchicalContainer.java b/server/src/main/java/com/vaadin/data/util/HierarchicalContainer.java
index 2235e77b34..2235e77b34 100644
--- a/server/src/com/vaadin/data/util/HierarchicalContainer.java
+++ b/server/src/main/java/com/vaadin/data/util/HierarchicalContainer.java
diff --git a/server/src/com/vaadin/data/util/HierarchicalContainerOrderedWrapper.java b/server/src/main/java/com/vaadin/data/util/HierarchicalContainerOrderedWrapper.java
index 1c7960f954..1c7960f954 100644
--- a/server/src/com/vaadin/data/util/HierarchicalContainerOrderedWrapper.java
+++ b/server/src/main/java/com/vaadin/data/util/HierarchicalContainerOrderedWrapper.java
diff --git a/server/src/com/vaadin/data/util/IndexedContainer.java b/server/src/main/java/com/vaadin/data/util/IndexedContainer.java
index b851baf674..b851baf674 100644
--- a/server/src/com/vaadin/data/util/IndexedContainer.java
+++ b/server/src/main/java/com/vaadin/data/util/IndexedContainer.java
diff --git a/server/src/com/vaadin/data/util/ItemSorter.java b/server/src/main/java/com/vaadin/data/util/ItemSorter.java
index 141f84ad43..141f84ad43 100644
--- a/server/src/com/vaadin/data/util/ItemSorter.java
+++ b/server/src/main/java/com/vaadin/data/util/ItemSorter.java
diff --git a/server/src/com/vaadin/data/util/LegacyPropertyHelper.java b/server/src/main/java/com/vaadin/data/util/LegacyPropertyHelper.java
index 7432d036fb..7432d036fb 100644
--- a/server/src/com/vaadin/data/util/LegacyPropertyHelper.java
+++ b/server/src/main/java/com/vaadin/data/util/LegacyPropertyHelper.java
diff --git a/server/src/com/vaadin/data/util/ListSet.java b/server/src/main/java/com/vaadin/data/util/ListSet.java
index ccc9e0dbfd..ccc9e0dbfd 100644
--- a/server/src/com/vaadin/data/util/ListSet.java
+++ b/server/src/main/java/com/vaadin/data/util/ListSet.java
diff --git a/server/src/com/vaadin/data/util/MethodProperty.java b/server/src/main/java/com/vaadin/data/util/MethodProperty.java
index 83279afa53..83279afa53 100644
--- a/server/src/com/vaadin/data/util/MethodProperty.java
+++ b/server/src/main/java/com/vaadin/data/util/MethodProperty.java
diff --git a/server/src/com/vaadin/data/util/MethodPropertyDescriptor.java b/server/src/main/java/com/vaadin/data/util/MethodPropertyDescriptor.java
index f94ee75ac3..f94ee75ac3 100644
--- a/server/src/com/vaadin/data/util/MethodPropertyDescriptor.java
+++ b/server/src/main/java/com/vaadin/data/util/MethodPropertyDescriptor.java
diff --git a/server/src/com/vaadin/data/util/NestedMethodProperty.java b/server/src/main/java/com/vaadin/data/util/NestedMethodProperty.java
index 29fe62f845..29fe62f845 100644
--- a/server/src/com/vaadin/data/util/NestedMethodProperty.java
+++ b/server/src/main/java/com/vaadin/data/util/NestedMethodProperty.java
diff --git a/server/src/com/vaadin/data/util/NestedPropertyDescriptor.java b/server/src/main/java/com/vaadin/data/util/NestedPropertyDescriptor.java
index ca423b34ed..ca423b34ed 100644
--- a/server/src/com/vaadin/data/util/NestedPropertyDescriptor.java
+++ b/server/src/main/java/com/vaadin/data/util/NestedPropertyDescriptor.java
diff --git a/server/src/com/vaadin/data/util/ObjectProperty.java b/server/src/main/java/com/vaadin/data/util/ObjectProperty.java
index 8a2daa443c..8a2daa443c 100644
--- a/server/src/com/vaadin/data/util/ObjectProperty.java
+++ b/server/src/main/java/com/vaadin/data/util/ObjectProperty.java
diff --git a/server/src/com/vaadin/data/util/PropertyFormatter.java b/server/src/main/java/com/vaadin/data/util/PropertyFormatter.java
index e188ce8bc3..e188ce8bc3 100644
--- a/server/src/com/vaadin/data/util/PropertyFormatter.java
+++ b/server/src/main/java/com/vaadin/data/util/PropertyFormatter.java
diff --git a/server/src/com/vaadin/data/util/PropertyValueGenerator.java b/server/src/main/java/com/vaadin/data/util/PropertyValueGenerator.java
index 453e45b1db..453e45b1db 100644
--- a/server/src/com/vaadin/data/util/PropertyValueGenerator.java
+++ b/server/src/main/java/com/vaadin/data/util/PropertyValueGenerator.java
diff --git a/server/src/com/vaadin/data/util/PropertysetItem.java b/server/src/main/java/com/vaadin/data/util/PropertysetItem.java
index f463a52f54..f463a52f54 100644
--- a/server/src/com/vaadin/data/util/PropertysetItem.java
+++ b/server/src/main/java/com/vaadin/data/util/PropertysetItem.java
diff --git a/server/src/com/vaadin/data/util/TextFileProperty.java b/server/src/main/java/com/vaadin/data/util/TextFileProperty.java
index 22fd8168a1..22fd8168a1 100644
--- a/server/src/com/vaadin/data/util/TextFileProperty.java
+++ b/server/src/main/java/com/vaadin/data/util/TextFileProperty.java
diff --git a/server/src/com/vaadin/data/util/TransactionalPropertyWrapper.java b/server/src/main/java/com/vaadin/data/util/TransactionalPropertyWrapper.java
index c3cef6a0ec..c3cef6a0ec 100644
--- a/server/src/com/vaadin/data/util/TransactionalPropertyWrapper.java
+++ b/server/src/main/java/com/vaadin/data/util/TransactionalPropertyWrapper.java
diff --git a/server/src/com/vaadin/data/util/VaadinPropertyDescriptor.java b/server/src/main/java/com/vaadin/data/util/VaadinPropertyDescriptor.java
index 51084d9115..51084d9115 100644
--- a/server/src/com/vaadin/data/util/VaadinPropertyDescriptor.java
+++ b/server/src/main/java/com/vaadin/data/util/VaadinPropertyDescriptor.java
diff --git a/server/src/com/vaadin/data/util/converter/AbstractStringToNumberConverter.java b/server/src/main/java/com/vaadin/data/util/converter/AbstractStringToNumberConverter.java
index 81f1a85f89..81f1a85f89 100644
--- a/server/src/com/vaadin/data/util/converter/AbstractStringToNumberConverter.java
+++ b/server/src/main/java/com/vaadin/data/util/converter/AbstractStringToNumberConverter.java
diff --git a/server/src/com/vaadin/data/util/converter/Converter.java b/server/src/main/java/com/vaadin/data/util/converter/Converter.java
index a7188ebb33..a7188ebb33 100644
--- a/server/src/com/vaadin/data/util/converter/Converter.java
+++ b/server/src/main/java/com/vaadin/data/util/converter/Converter.java
diff --git a/server/src/com/vaadin/data/util/converter/ConverterFactory.java b/server/src/main/java/com/vaadin/data/util/converter/ConverterFactory.java
index 0280be4a73..0280be4a73 100644
--- a/server/src/com/vaadin/data/util/converter/ConverterFactory.java
+++ b/server/src/main/java/com/vaadin/data/util/converter/ConverterFactory.java
diff --git a/server/src/com/vaadin/data/util/converter/ConverterUtil.java b/server/src/main/java/com/vaadin/data/util/converter/ConverterUtil.java
index 91e11a6222..91e11a6222 100644
--- a/server/src/com/vaadin/data/util/converter/ConverterUtil.java
+++ b/server/src/main/java/com/vaadin/data/util/converter/ConverterUtil.java
diff --git a/server/src/com/vaadin/data/util/converter/DateToLongConverter.java b/server/src/main/java/com/vaadin/data/util/converter/DateToLongConverter.java
index fffe80352e..fffe80352e 100644
--- a/server/src/com/vaadin/data/util/converter/DateToLongConverter.java
+++ b/server/src/main/java/com/vaadin/data/util/converter/DateToLongConverter.java
diff --git a/server/src/com/vaadin/data/util/converter/DateToSqlDateConverter.java b/server/src/main/java/com/vaadin/data/util/converter/DateToSqlDateConverter.java
index 6a7e8327a1..6a7e8327a1 100644
--- a/server/src/com/vaadin/data/util/converter/DateToSqlDateConverter.java
+++ b/server/src/main/java/com/vaadin/data/util/converter/DateToSqlDateConverter.java
diff --git a/server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java b/server/src/main/java/com/vaadin/data/util/converter/DefaultConverterFactory.java
index 3a1f1a4252..3a1f1a4252 100644
--- a/server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java
+++ b/server/src/main/java/com/vaadin/data/util/converter/DefaultConverterFactory.java
diff --git a/server/src/com/vaadin/data/util/converter/ReverseConverter.java b/server/src/main/java/com/vaadin/data/util/converter/ReverseConverter.java
index 2495dc631a..2495dc631a 100644
--- a/server/src/com/vaadin/data/util/converter/ReverseConverter.java
+++ b/server/src/main/java/com/vaadin/data/util/converter/ReverseConverter.java
diff --git a/server/src/com/vaadin/data/util/converter/StringToBigDecimalConverter.java b/server/src/main/java/com/vaadin/data/util/converter/StringToBigDecimalConverter.java
index 549f156f61..549f156f61 100644
--- a/server/src/com/vaadin/data/util/converter/StringToBigDecimalConverter.java
+++ b/server/src/main/java/com/vaadin/data/util/converter/StringToBigDecimalConverter.java
diff --git a/server/src/com/vaadin/data/util/converter/StringToBigIntegerConverter.java b/server/src/main/java/com/vaadin/data/util/converter/StringToBigIntegerConverter.java
index adaa8c6111..adaa8c6111 100644
--- a/server/src/com/vaadin/data/util/converter/StringToBigIntegerConverter.java
+++ b/server/src/main/java/com/vaadin/data/util/converter/StringToBigIntegerConverter.java
diff --git a/server/src/com/vaadin/data/util/converter/StringToBooleanConverter.java b/server/src/main/java/com/vaadin/data/util/converter/StringToBooleanConverter.java
index f965cfcc6a..f965cfcc6a 100644
--- a/server/src/com/vaadin/data/util/converter/StringToBooleanConverter.java
+++ b/server/src/main/java/com/vaadin/data/util/converter/StringToBooleanConverter.java
diff --git a/server/src/com/vaadin/data/util/converter/StringToByteConverter.java b/server/src/main/java/com/vaadin/data/util/converter/StringToByteConverter.java
index 719fced0ed..719fced0ed 100644
--- a/server/src/com/vaadin/data/util/converter/StringToByteConverter.java
+++ b/server/src/main/java/com/vaadin/data/util/converter/StringToByteConverter.java
diff --git a/server/src/com/vaadin/data/util/converter/StringToCollectionConverter.java b/server/src/main/java/com/vaadin/data/util/converter/StringToCollectionConverter.java
index 6930b6da06..6930b6da06 100644
--- a/server/src/com/vaadin/data/util/converter/StringToCollectionConverter.java
+++ b/server/src/main/java/com/vaadin/data/util/converter/StringToCollectionConverter.java
diff --git a/server/src/com/vaadin/data/util/converter/StringToDateConverter.java b/server/src/main/java/com/vaadin/data/util/converter/StringToDateConverter.java
index 8f0db24caf..8f0db24caf 100644
--- a/server/src/com/vaadin/data/util/converter/StringToDateConverter.java
+++ b/server/src/main/java/com/vaadin/data/util/converter/StringToDateConverter.java
diff --git a/server/src/com/vaadin/data/util/converter/StringToDoubleConverter.java b/server/src/main/java/com/vaadin/data/util/converter/StringToDoubleConverter.java
index f514eac648..f514eac648 100644
--- a/server/src/com/vaadin/data/util/converter/StringToDoubleConverter.java
+++ b/server/src/main/java/com/vaadin/data/util/converter/StringToDoubleConverter.java
diff --git a/server/src/com/vaadin/data/util/converter/StringToEnumConverter.java b/server/src/main/java/com/vaadin/data/util/converter/StringToEnumConverter.java
index 7b2f43f972..7b2f43f972 100644
--- a/server/src/com/vaadin/data/util/converter/StringToEnumConverter.java
+++ b/server/src/main/java/com/vaadin/data/util/converter/StringToEnumConverter.java
diff --git a/server/src/com/vaadin/data/util/converter/StringToFloatConverter.java b/server/src/main/java/com/vaadin/data/util/converter/StringToFloatConverter.java
index f4d7f97853..f4d7f97853 100644
--- a/server/src/com/vaadin/data/util/converter/StringToFloatConverter.java
+++ b/server/src/main/java/com/vaadin/data/util/converter/StringToFloatConverter.java
diff --git a/server/src/com/vaadin/data/util/converter/StringToIntegerConverter.java b/server/src/main/java/com/vaadin/data/util/converter/StringToIntegerConverter.java
index 59a46babe1..59a46babe1 100644
--- a/server/src/com/vaadin/data/util/converter/StringToIntegerConverter.java
+++ b/server/src/main/java/com/vaadin/data/util/converter/StringToIntegerConverter.java
diff --git a/server/src/com/vaadin/data/util/converter/StringToLongConverter.java b/server/src/main/java/com/vaadin/data/util/converter/StringToLongConverter.java
index cd7cf49042..cd7cf49042 100644
--- a/server/src/com/vaadin/data/util/converter/StringToLongConverter.java
+++ b/server/src/main/java/com/vaadin/data/util/converter/StringToLongConverter.java
diff --git a/server/src/com/vaadin/data/util/converter/StringToShortConverter.java b/server/src/main/java/com/vaadin/data/util/converter/StringToShortConverter.java
index 554b958ee0..554b958ee0 100644
--- a/server/src/com/vaadin/data/util/converter/StringToShortConverter.java
+++ b/server/src/main/java/com/vaadin/data/util/converter/StringToShortConverter.java
diff --git a/server/src/com/vaadin/data/util/filter/AbstractJunctionFilter.java b/server/src/main/java/com/vaadin/data/util/filter/AbstractJunctionFilter.java
index 28e6cda34e..28e6cda34e 100644
--- a/server/src/com/vaadin/data/util/filter/AbstractJunctionFilter.java
+++ b/server/src/main/java/com/vaadin/data/util/filter/AbstractJunctionFilter.java
diff --git a/server/src/com/vaadin/data/util/filter/And.java b/server/src/main/java/com/vaadin/data/util/filter/And.java
index 938aedae95..938aedae95 100644
--- a/server/src/com/vaadin/data/util/filter/And.java
+++ b/server/src/main/java/com/vaadin/data/util/filter/And.java
diff --git a/server/src/com/vaadin/data/util/filter/Between.java b/server/src/main/java/com/vaadin/data/util/filter/Between.java
index c50488c521..c50488c521 100644
--- a/server/src/com/vaadin/data/util/filter/Between.java
+++ b/server/src/main/java/com/vaadin/data/util/filter/Between.java
diff --git a/server/src/com/vaadin/data/util/filter/Compare.java b/server/src/main/java/com/vaadin/data/util/filter/Compare.java
index 1fcbe85580..1fcbe85580 100644
--- a/server/src/com/vaadin/data/util/filter/Compare.java
+++ b/server/src/main/java/com/vaadin/data/util/filter/Compare.java
diff --git a/server/src/com/vaadin/data/util/filter/IsNull.java b/server/src/main/java/com/vaadin/data/util/filter/IsNull.java
index 9bcfe40c03..9bcfe40c03 100644
--- a/server/src/com/vaadin/data/util/filter/IsNull.java
+++ b/server/src/main/java/com/vaadin/data/util/filter/IsNull.java
diff --git a/server/src/com/vaadin/data/util/filter/Like.java b/server/src/main/java/com/vaadin/data/util/filter/Like.java
index 9b7b2af292..9b7b2af292 100644
--- a/server/src/com/vaadin/data/util/filter/Like.java
+++ b/server/src/main/java/com/vaadin/data/util/filter/Like.java
diff --git a/server/src/com/vaadin/data/util/filter/Not.java b/server/src/main/java/com/vaadin/data/util/filter/Not.java
index a677e7f752..a677e7f752 100644
--- a/server/src/com/vaadin/data/util/filter/Not.java
+++ b/server/src/main/java/com/vaadin/data/util/filter/Not.java
diff --git a/server/src/com/vaadin/data/util/filter/Or.java b/server/src/main/java/com/vaadin/data/util/filter/Or.java
index 69d20513a2..69d20513a2 100644
--- a/server/src/com/vaadin/data/util/filter/Or.java
+++ b/server/src/main/java/com/vaadin/data/util/filter/Or.java
diff --git a/server/src/com/vaadin/data/util/filter/SimpleStringFilter.java b/server/src/main/java/com/vaadin/data/util/filter/SimpleStringFilter.java
index ea5e93277e..ea5e93277e 100644
--- a/server/src/com/vaadin/data/util/filter/SimpleStringFilter.java
+++ b/server/src/main/java/com/vaadin/data/util/filter/SimpleStringFilter.java
diff --git a/server/src/com/vaadin/data/util/filter/UnsupportedFilterException.java b/server/src/main/java/com/vaadin/data/util/filter/UnsupportedFilterException.java
index 42a7784da8..42a7784da8 100644
--- a/server/src/com/vaadin/data/util/filter/UnsupportedFilterException.java
+++ b/server/src/main/java/com/vaadin/data/util/filter/UnsupportedFilterException.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java
index 12d806a8d5..12d806a8d5 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/CacheMap.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/CacheMap.java
index cdeff873d0..cdeff873d0 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/CacheMap.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/CacheMap.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/ColumnProperty.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/ColumnProperty.java
index e89b8c02a8..e89b8c02a8 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/ColumnProperty.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/ColumnProperty.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/OptimisticLockException.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/OptimisticLockException.java
index ed8eb3c0ff..ed8eb3c0ff 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/OptimisticLockException.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/OptimisticLockException.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/ReadOnlyRowId.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/ReadOnlyRowId.java
index c845cadc7a..c845cadc7a 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/ReadOnlyRowId.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/ReadOnlyRowId.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/Reference.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/Reference.java
index e82f63ad2f..e82f63ad2f 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/Reference.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/Reference.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/RowId.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/RowId.java
index 79c16b0f60..79c16b0f60 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/RowId.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/RowId.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/RowItem.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/RowItem.java
index ddb5de1d31..ddb5de1d31 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/RowItem.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/RowItem.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/SQLContainer.java
index 86e9069e90..86e9069e90 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/SQLContainer.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/SQLUtil.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/SQLUtil.java
index e5282c867a..e5282c867a 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/SQLUtil.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/SQLUtil.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/TemporaryRowId.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/TemporaryRowId.java
index ca2f25963e..ca2f25963e 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/TemporaryRowId.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/TemporaryRowId.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPool.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPool.java
index acad5beed9..acad5beed9 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPool.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPool.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/connection/JDBCConnectionPool.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/connection/JDBCConnectionPool.java
index 11669075a3..11669075a3 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/connection/JDBCConnectionPool.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/connection/JDBCConnectionPool.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java
index 57ea188cb4..57ea188cb4 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/AbstractTransactionalQuery.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/AbstractTransactionalQuery.java
index e7fd9f4aa4..e7fd9f4aa4 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/AbstractTransactionalQuery.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/AbstractTransactionalQuery.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java
index 6b800cb965..6b800cb965 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQueryDelegate.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/FreeformQueryDelegate.java
index b6fa56055d..b6fa56055d 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQueryDelegate.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/FreeformQueryDelegate.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java
index 9df72f5b98..9df72f5b98 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/OrderBy.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/OrderBy.java
index 2bafa5dc0c..2bafa5dc0c 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/OrderBy.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/OrderBy.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/QueryDelegate.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/QueryDelegate.java
index 413dd55ab9..413dd55ab9 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/QueryDelegate.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/QueryDelegate.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/TableQuery.java
index 9a41766a31..9a41766a31 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/TableQuery.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java
index 2fc7ebd544..2fc7ebd544 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/MSSQLGenerator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/MSSQLGenerator.java
index 5a1f2003cd..5a1f2003cd 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/MSSQLGenerator.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/MSSQLGenerator.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/OracleGenerator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/OracleGenerator.java
index 86508d37c4..86508d37c4 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/OracleGenerator.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/OracleGenerator.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/SQLGenerator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/SQLGenerator.java
index 53ff924a36..53ff924a36 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/SQLGenerator.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/SQLGenerator.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java
index 5a9fcb17c0..5a9fcb17c0 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/AndTranslator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/AndTranslator.java
index a3d9b90705..a3d9b90705 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/AndTranslator.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/AndTranslator.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/BetweenTranslator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/BetweenTranslator.java
index 13d3553742..13d3553742 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/BetweenTranslator.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/BetweenTranslator.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/CompareTranslator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/CompareTranslator.java
index d8d5cc61fb..d8d5cc61fb 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/CompareTranslator.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/CompareTranslator.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/FilterTranslator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/FilterTranslator.java
index 0ece263ef4..0ece263ef4 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/FilterTranslator.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/FilterTranslator.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/IsNullTranslator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/IsNullTranslator.java
index 764a04eece..764a04eece 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/IsNullTranslator.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/IsNullTranslator.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/LikeTranslator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/LikeTranslator.java
index 07e544d40b..07e544d40b 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/LikeTranslator.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/LikeTranslator.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/NotTranslator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/NotTranslator.java
index 1bbc2a8e7e..1bbc2a8e7e 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/NotTranslator.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/NotTranslator.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/OrTranslator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/OrTranslator.java
index 00b4d5421b..00b4d5421b 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/OrTranslator.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/OrTranslator.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/QueryBuilder.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/QueryBuilder.java
index b277551209..b277551209 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/QueryBuilder.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/QueryBuilder.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/SimpleStringTranslator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/SimpleStringTranslator.java
index 9bfda5fb34..9bfda5fb34 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/SimpleStringTranslator.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/SimpleStringTranslator.java
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/StringDecorator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/StringDecorator.java
index 0132260a0c..0132260a0c 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/StringDecorator.java
+++ b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/StringDecorator.java
diff --git a/server/src/com/vaadin/data/validator/AbstractStringValidator.java b/server/src/main/java/com/vaadin/data/validator/AbstractStringValidator.java
index 70227afa67..70227afa67 100644
--- a/server/src/com/vaadin/data/validator/AbstractStringValidator.java
+++ b/server/src/main/java/com/vaadin/data/validator/AbstractStringValidator.java
diff --git a/server/src/com/vaadin/data/validator/AbstractValidator.java b/server/src/main/java/com/vaadin/data/validator/AbstractValidator.java
index b0894bbdbf..b0894bbdbf 100644
--- a/server/src/com/vaadin/data/validator/AbstractValidator.java
+++ b/server/src/main/java/com/vaadin/data/validator/AbstractValidator.java
diff --git a/server/src/com/vaadin/data/validator/BeanValidator.java b/server/src/main/java/com/vaadin/data/validator/BeanValidator.java
index b25f7e687c..b25f7e687c 100644
--- a/server/src/com/vaadin/data/validator/BeanValidator.java
+++ b/server/src/main/java/com/vaadin/data/validator/BeanValidator.java
diff --git a/server/src/com/vaadin/data/validator/BigDecimalRangeValidator.java b/server/src/main/java/com/vaadin/data/validator/BigDecimalRangeValidator.java
index 1363d230f6..1363d230f6 100644
--- a/server/src/com/vaadin/data/validator/BigDecimalRangeValidator.java
+++ b/server/src/main/java/com/vaadin/data/validator/BigDecimalRangeValidator.java
diff --git a/server/src/com/vaadin/data/validator/BigIntegerRangeValidator.java b/server/src/main/java/com/vaadin/data/validator/BigIntegerRangeValidator.java
index ecf1990192..ecf1990192 100644
--- a/server/src/com/vaadin/data/validator/BigIntegerRangeValidator.java
+++ b/server/src/main/java/com/vaadin/data/validator/BigIntegerRangeValidator.java
diff --git a/server/src/com/vaadin/data/validator/ByteRangeValidator.java b/server/src/main/java/com/vaadin/data/validator/ByteRangeValidator.java
index b147212c06..b147212c06 100644
--- a/server/src/com/vaadin/data/validator/ByteRangeValidator.java
+++ b/server/src/main/java/com/vaadin/data/validator/ByteRangeValidator.java
diff --git a/server/src/com/vaadin/data/validator/CompositeValidator.java b/server/src/main/java/com/vaadin/data/validator/CompositeValidator.java
index f3b7133b9d..f3b7133b9d 100644
--- a/server/src/com/vaadin/data/validator/CompositeValidator.java
+++ b/server/src/main/java/com/vaadin/data/validator/CompositeValidator.java
diff --git a/server/src/com/vaadin/data/validator/DateRangeValidator.java b/server/src/main/java/com/vaadin/data/validator/DateRangeValidator.java
index 3add69c207..3add69c207 100644
--- a/server/src/com/vaadin/data/validator/DateRangeValidator.java
+++ b/server/src/main/java/com/vaadin/data/validator/DateRangeValidator.java
diff --git a/server/src/com/vaadin/data/validator/DoubleRangeValidator.java b/server/src/main/java/com/vaadin/data/validator/DoubleRangeValidator.java
index 8992e2644a..8992e2644a 100644
--- a/server/src/com/vaadin/data/validator/DoubleRangeValidator.java
+++ b/server/src/main/java/com/vaadin/data/validator/DoubleRangeValidator.java
diff --git a/server/src/com/vaadin/data/validator/DoubleValidator.java b/server/src/main/java/com/vaadin/data/validator/DoubleValidator.java
index e40cf3eecf..e40cf3eecf 100644
--- a/server/src/com/vaadin/data/validator/DoubleValidator.java
+++ b/server/src/main/java/com/vaadin/data/validator/DoubleValidator.java
diff --git a/server/src/com/vaadin/data/validator/EmailValidator.java b/server/src/main/java/com/vaadin/data/validator/EmailValidator.java
index 853c855a37..853c855a37 100644
--- a/server/src/com/vaadin/data/validator/EmailValidator.java
+++ b/server/src/main/java/com/vaadin/data/validator/EmailValidator.java
diff --git a/server/src/com/vaadin/data/validator/FloatRangeValidator.java b/server/src/main/java/com/vaadin/data/validator/FloatRangeValidator.java
index ee29cf16b1..ee29cf16b1 100644
--- a/server/src/com/vaadin/data/validator/FloatRangeValidator.java
+++ b/server/src/main/java/com/vaadin/data/validator/FloatRangeValidator.java
diff --git a/server/src/com/vaadin/data/validator/IntegerRangeValidator.java b/server/src/main/java/com/vaadin/data/validator/IntegerRangeValidator.java
index 6ef848bed3..6ef848bed3 100644
--- a/server/src/com/vaadin/data/validator/IntegerRangeValidator.java
+++ b/server/src/main/java/com/vaadin/data/validator/IntegerRangeValidator.java
diff --git a/server/src/com/vaadin/data/validator/IntegerValidator.java b/server/src/main/java/com/vaadin/data/validator/IntegerValidator.java
index f52ba0ab3a..f52ba0ab3a 100644
--- a/server/src/com/vaadin/data/validator/IntegerValidator.java
+++ b/server/src/main/java/com/vaadin/data/validator/IntegerValidator.java
diff --git a/server/src/com/vaadin/data/validator/LongRangeValidator.java b/server/src/main/java/com/vaadin/data/validator/LongRangeValidator.java
index c4d8a9c9ca..c4d8a9c9ca 100644
--- a/server/src/com/vaadin/data/validator/LongRangeValidator.java
+++ b/server/src/main/java/com/vaadin/data/validator/LongRangeValidator.java
diff --git a/server/src/com/vaadin/data/validator/NullValidator.java b/server/src/main/java/com/vaadin/data/validator/NullValidator.java
index 42cf419973..42cf419973 100644
--- a/server/src/com/vaadin/data/validator/NullValidator.java
+++ b/server/src/main/java/com/vaadin/data/validator/NullValidator.java
diff --git a/server/src/com/vaadin/data/validator/RangeValidator.java b/server/src/main/java/com/vaadin/data/validator/RangeValidator.java
index 5ba3aef363..5ba3aef363 100644
--- a/server/src/com/vaadin/data/validator/RangeValidator.java
+++ b/server/src/main/java/com/vaadin/data/validator/RangeValidator.java
diff --git a/server/src/com/vaadin/data/validator/RegexpValidator.java b/server/src/main/java/com/vaadin/data/validator/RegexpValidator.java
index 74e1f89253..74e1f89253 100644
--- a/server/src/com/vaadin/data/validator/RegexpValidator.java
+++ b/server/src/main/java/com/vaadin/data/validator/RegexpValidator.java
diff --git a/server/src/com/vaadin/data/validator/ShortRangeValidator.java b/server/src/main/java/com/vaadin/data/validator/ShortRangeValidator.java
index a8b0d3aeb4..a8b0d3aeb4 100644
--- a/server/src/com/vaadin/data/validator/ShortRangeValidator.java
+++ b/server/src/main/java/com/vaadin/data/validator/ShortRangeValidator.java
diff --git a/server/src/com/vaadin/data/validator/StringLengthValidator.java b/server/src/main/java/com/vaadin/data/validator/StringLengthValidator.java
index efb551c614..efb551c614 100644
--- a/server/src/com/vaadin/data/validator/StringLengthValidator.java
+++ b/server/src/main/java/com/vaadin/data/validator/StringLengthValidator.java
diff --git a/server/src/com/vaadin/event/Action.java b/server/src/main/java/com/vaadin/event/Action.java
index 1af1de6e6d..1af1de6e6d 100644
--- a/server/src/com/vaadin/event/Action.java
+++ b/server/src/main/java/com/vaadin/event/Action.java
diff --git a/server/src/com/vaadin/event/ActionManager.java b/server/src/main/java/com/vaadin/event/ActionManager.java
index 6eb698d08a..6eb698d08a 100644
--- a/server/src/com/vaadin/event/ActionManager.java
+++ b/server/src/main/java/com/vaadin/event/ActionManager.java
diff --git a/server/src/com/vaadin/event/ConnectorActionManager.java b/server/src/main/java/com/vaadin/event/ConnectorActionManager.java
index 0816ba48df..0816ba48df 100644
--- a/server/src/com/vaadin/event/ConnectorActionManager.java
+++ b/server/src/main/java/com/vaadin/event/ConnectorActionManager.java
diff --git a/server/src/com/vaadin/event/ConnectorEvent.java b/server/src/main/java/com/vaadin/event/ConnectorEvent.java
index 3dc73b864a..3dc73b864a 100644
--- a/server/src/com/vaadin/event/ConnectorEvent.java
+++ b/server/src/main/java/com/vaadin/event/ConnectorEvent.java
diff --git a/server/src/com/vaadin/event/ConnectorEventListener.java b/server/src/main/java/com/vaadin/event/ConnectorEventListener.java
index e3cb9c283b..e3cb9c283b 100644
--- a/server/src/com/vaadin/event/ConnectorEventListener.java
+++ b/server/src/main/java/com/vaadin/event/ConnectorEventListener.java
diff --git a/server/src/com/vaadin/event/ContextClickEvent.java b/server/src/main/java/com/vaadin/event/ContextClickEvent.java
index 5b15634105..5b15634105 100644
--- a/server/src/com/vaadin/event/ContextClickEvent.java
+++ b/server/src/main/java/com/vaadin/event/ContextClickEvent.java
diff --git a/server/src/com/vaadin/event/DataBoundTransferable.java b/server/src/main/java/com/vaadin/event/DataBoundTransferable.java
index d461692b2e..d461692b2e 100644
--- a/server/src/com/vaadin/event/DataBoundTransferable.java
+++ b/server/src/main/java/com/vaadin/event/DataBoundTransferable.java
diff --git a/server/src/com/vaadin/event/EventRouter.java b/server/src/main/java/com/vaadin/event/EventRouter.java
index b662dfcb36..b662dfcb36 100644
--- a/server/src/com/vaadin/event/EventRouter.java
+++ b/server/src/main/java/com/vaadin/event/EventRouter.java
diff --git a/server/src/com/vaadin/event/FieldEvents.java b/server/src/main/java/com/vaadin/event/FieldEvents.java
index 364ac76ffd..364ac76ffd 100644
--- a/server/src/com/vaadin/event/FieldEvents.java
+++ b/server/src/main/java/com/vaadin/event/FieldEvents.java
diff --git a/server/src/com/vaadin/event/ItemClickEvent.java b/server/src/main/java/com/vaadin/event/ItemClickEvent.java
index 1280c16872..1280c16872 100644
--- a/server/src/com/vaadin/event/ItemClickEvent.java
+++ b/server/src/main/java/com/vaadin/event/ItemClickEvent.java
diff --git a/server/src/com/vaadin/event/LayoutEvents.java b/server/src/main/java/com/vaadin/event/LayoutEvents.java
index e4432b7c7a..e4432b7c7a 100644
--- a/server/src/com/vaadin/event/LayoutEvents.java
+++ b/server/src/main/java/com/vaadin/event/LayoutEvents.java
diff --git a/server/src/com/vaadin/event/ListenerMethod.java b/server/src/main/java/com/vaadin/event/ListenerMethod.java
index 3311ed705e..3311ed705e 100644
--- a/server/src/com/vaadin/event/ListenerMethod.java
+++ b/server/src/main/java/com/vaadin/event/ListenerMethod.java
diff --git a/server/src/com/vaadin/event/MethodEventSource.java b/server/src/main/java/com/vaadin/event/MethodEventSource.java
index ddfc87ca8c..ddfc87ca8c 100644
--- a/server/src/com/vaadin/event/MethodEventSource.java
+++ b/server/src/main/java/com/vaadin/event/MethodEventSource.java
diff --git a/server/src/com/vaadin/event/MouseEvents.java b/server/src/main/java/com/vaadin/event/MouseEvents.java
index b32ce06587..b32ce06587 100644
--- a/server/src/com/vaadin/event/MouseEvents.java
+++ b/server/src/main/java/com/vaadin/event/MouseEvents.java
diff --git a/server/src/com/vaadin/event/SelectionEvent.java b/server/src/main/java/com/vaadin/event/SelectionEvent.java
index e75369e6da..e75369e6da 100644
--- a/server/src/com/vaadin/event/SelectionEvent.java
+++ b/server/src/main/java/com/vaadin/event/SelectionEvent.java
diff --git a/server/src/com/vaadin/event/ShortcutAction.java b/server/src/main/java/com/vaadin/event/ShortcutAction.java
index dd511c23c0..dd511c23c0 100644
--- a/server/src/com/vaadin/event/ShortcutAction.java
+++ b/server/src/main/java/com/vaadin/event/ShortcutAction.java
diff --git a/server/src/com/vaadin/event/ShortcutListener.java b/server/src/main/java/com/vaadin/event/ShortcutListener.java
index ccfe68d6fb..ccfe68d6fb 100644
--- a/server/src/com/vaadin/event/ShortcutListener.java
+++ b/server/src/main/java/com/vaadin/event/ShortcutListener.java
diff --git a/server/src/com/vaadin/event/SortEvent.java b/server/src/main/java/com/vaadin/event/SortEvent.java
index f303e47781..f303e47781 100644
--- a/server/src/com/vaadin/event/SortEvent.java
+++ b/server/src/main/java/com/vaadin/event/SortEvent.java
diff --git a/server/src/com/vaadin/event/Transferable.java b/server/src/main/java/com/vaadin/event/Transferable.java
index 9cfbba5161..9cfbba5161 100644
--- a/server/src/com/vaadin/event/Transferable.java
+++ b/server/src/main/java/com/vaadin/event/Transferable.java
diff --git a/server/src/com/vaadin/event/TransferableImpl.java b/server/src/main/java/com/vaadin/event/TransferableImpl.java
index 9c8e79f1bf..9c8e79f1bf 100644
--- a/server/src/com/vaadin/event/TransferableImpl.java
+++ b/server/src/main/java/com/vaadin/event/TransferableImpl.java
diff --git a/server/src/com/vaadin/event/UIEvents.java b/server/src/main/java/com/vaadin/event/UIEvents.java
index e986386da8..e986386da8 100644
--- a/server/src/com/vaadin/event/UIEvents.java
+++ b/server/src/main/java/com/vaadin/event/UIEvents.java
diff --git a/server/src/com/vaadin/event/dd/DragAndDropEvent.java b/server/src/main/java/com/vaadin/event/dd/DragAndDropEvent.java
index 661c7ed1cc..661c7ed1cc 100644
--- a/server/src/com/vaadin/event/dd/DragAndDropEvent.java
+++ b/server/src/main/java/com/vaadin/event/dd/DragAndDropEvent.java
diff --git a/server/src/com/vaadin/event/dd/DragSource.java b/server/src/main/java/com/vaadin/event/dd/DragSource.java
index 8e4d43bfc4..8e4d43bfc4 100644
--- a/server/src/com/vaadin/event/dd/DragSource.java
+++ b/server/src/main/java/com/vaadin/event/dd/DragSource.java
diff --git a/server/src/com/vaadin/event/dd/DropHandler.java b/server/src/main/java/com/vaadin/event/dd/DropHandler.java
index c45ae7e7d3..c45ae7e7d3 100644
--- a/server/src/com/vaadin/event/dd/DropHandler.java
+++ b/server/src/main/java/com/vaadin/event/dd/DropHandler.java
diff --git a/server/src/com/vaadin/event/dd/DropTarget.java b/server/src/main/java/com/vaadin/event/dd/DropTarget.java
index f96170cf98..f96170cf98 100644
--- a/server/src/com/vaadin/event/dd/DropTarget.java
+++ b/server/src/main/java/com/vaadin/event/dd/DropTarget.java
diff --git a/server/src/com/vaadin/event/dd/TargetDetails.java b/server/src/main/java/com/vaadin/event/dd/TargetDetails.java
index b5635bc2a8..b5635bc2a8 100644
--- a/server/src/com/vaadin/event/dd/TargetDetails.java
+++ b/server/src/main/java/com/vaadin/event/dd/TargetDetails.java
diff --git a/server/src/com/vaadin/event/dd/TargetDetailsImpl.java b/server/src/main/java/com/vaadin/event/dd/TargetDetailsImpl.java
index 8a6ec506ba..8a6ec506ba 100644
--- a/server/src/com/vaadin/event/dd/TargetDetailsImpl.java
+++ b/server/src/main/java/com/vaadin/event/dd/TargetDetailsImpl.java
diff --git a/server/src/com/vaadin/event/dd/acceptcriteria/AcceptAll.java b/server/src/main/java/com/vaadin/event/dd/acceptcriteria/AcceptAll.java
index fa6a4c2b9a..fa6a4c2b9a 100644
--- a/server/src/com/vaadin/event/dd/acceptcriteria/AcceptAll.java
+++ b/server/src/main/java/com/vaadin/event/dd/acceptcriteria/AcceptAll.java
diff --git a/server/src/com/vaadin/event/dd/acceptcriteria/AcceptCriterion.java b/server/src/main/java/com/vaadin/event/dd/acceptcriteria/AcceptCriterion.java
index a968cd8741..a968cd8741 100644
--- a/server/src/com/vaadin/event/dd/acceptcriteria/AcceptCriterion.java
+++ b/server/src/main/java/com/vaadin/event/dd/acceptcriteria/AcceptCriterion.java
diff --git a/server/src/com/vaadin/event/dd/acceptcriteria/And.java b/server/src/main/java/com/vaadin/event/dd/acceptcriteria/And.java
index b2fc1b1b94..b2fc1b1b94 100644
--- a/server/src/com/vaadin/event/dd/acceptcriteria/And.java
+++ b/server/src/main/java/com/vaadin/event/dd/acceptcriteria/And.java
diff --git a/server/src/com/vaadin/event/dd/acceptcriteria/ClientSideCriterion.java b/server/src/main/java/com/vaadin/event/dd/acceptcriteria/ClientSideCriterion.java
index 6bb227a95e..6bb227a95e 100644
--- a/server/src/com/vaadin/event/dd/acceptcriteria/ClientSideCriterion.java
+++ b/server/src/main/java/com/vaadin/event/dd/acceptcriteria/ClientSideCriterion.java
diff --git a/server/src/com/vaadin/event/dd/acceptcriteria/ContainsDataFlavor.java b/server/src/main/java/com/vaadin/event/dd/acceptcriteria/ContainsDataFlavor.java
index 57f4d8253b..57f4d8253b 100644
--- a/server/src/com/vaadin/event/dd/acceptcriteria/ContainsDataFlavor.java
+++ b/server/src/main/java/com/vaadin/event/dd/acceptcriteria/ContainsDataFlavor.java
diff --git a/server/src/com/vaadin/event/dd/acceptcriteria/Not.java b/server/src/main/java/com/vaadin/event/dd/acceptcriteria/Not.java
index 95f96bbf08..95f96bbf08 100644
--- a/server/src/com/vaadin/event/dd/acceptcriteria/Not.java
+++ b/server/src/main/java/com/vaadin/event/dd/acceptcriteria/Not.java
diff --git a/server/src/com/vaadin/event/dd/acceptcriteria/Or.java b/server/src/main/java/com/vaadin/event/dd/acceptcriteria/Or.java
index e300606464..e300606464 100644
--- a/server/src/com/vaadin/event/dd/acceptcriteria/Or.java
+++ b/server/src/main/java/com/vaadin/event/dd/acceptcriteria/Or.java
diff --git a/server/src/com/vaadin/event/dd/acceptcriteria/ServerSideCriterion.java b/server/src/main/java/com/vaadin/event/dd/acceptcriteria/ServerSideCriterion.java
index 8b769ee031..8b769ee031 100644
--- a/server/src/com/vaadin/event/dd/acceptcriteria/ServerSideCriterion.java
+++ b/server/src/main/java/com/vaadin/event/dd/acceptcriteria/ServerSideCriterion.java
diff --git a/server/src/com/vaadin/event/dd/acceptcriteria/SourceIs.java b/server/src/main/java/com/vaadin/event/dd/acceptcriteria/SourceIs.java
index 8e9fdecdae..8e9fdecdae 100644
--- a/server/src/com/vaadin/event/dd/acceptcriteria/SourceIs.java
+++ b/server/src/main/java/com/vaadin/event/dd/acceptcriteria/SourceIs.java
diff --git a/server/src/com/vaadin/event/dd/acceptcriteria/SourceIsTarget.java b/server/src/main/java/com/vaadin/event/dd/acceptcriteria/SourceIsTarget.java
index c49f126941..c49f126941 100644
--- a/server/src/com/vaadin/event/dd/acceptcriteria/SourceIsTarget.java
+++ b/server/src/main/java/com/vaadin/event/dd/acceptcriteria/SourceIsTarget.java
diff --git a/server/src/com/vaadin/event/dd/acceptcriteria/TargetDetailIs.java b/server/src/main/java/com/vaadin/event/dd/acceptcriteria/TargetDetailIs.java
index 42fb5dfa11..42fb5dfa11 100644
--- a/server/src/com/vaadin/event/dd/acceptcriteria/TargetDetailIs.java
+++ b/server/src/main/java/com/vaadin/event/dd/acceptcriteria/TargetDetailIs.java
diff --git a/server/src/com/vaadin/navigator/NavigationStateManager.java b/server/src/main/java/com/vaadin/navigator/NavigationStateManager.java
index 3e9c54c961..3e9c54c961 100644
--- a/server/src/com/vaadin/navigator/NavigationStateManager.java
+++ b/server/src/main/java/com/vaadin/navigator/NavigationStateManager.java
diff --git a/server/src/com/vaadin/navigator/Navigator.java b/server/src/main/java/com/vaadin/navigator/Navigator.java
index 82e8de920a..82e8de920a 100644
--- a/server/src/com/vaadin/navigator/Navigator.java
+++ b/server/src/main/java/com/vaadin/navigator/Navigator.java
diff --git a/server/src/com/vaadin/navigator/View.java b/server/src/main/java/com/vaadin/navigator/View.java
index 76b76f5520..76b76f5520 100644
--- a/server/src/com/vaadin/navigator/View.java
+++ b/server/src/main/java/com/vaadin/navigator/View.java
diff --git a/server/src/com/vaadin/navigator/ViewChangeListener.java b/server/src/main/java/com/vaadin/navigator/ViewChangeListener.java
index 7d3f2b6044..7d3f2b6044 100644
--- a/server/src/com/vaadin/navigator/ViewChangeListener.java
+++ b/server/src/main/java/com/vaadin/navigator/ViewChangeListener.java
diff --git a/server/src/com/vaadin/navigator/ViewDisplay.java b/server/src/main/java/com/vaadin/navigator/ViewDisplay.java
index 36aa5dadc2..36aa5dadc2 100644
--- a/server/src/com/vaadin/navigator/ViewDisplay.java
+++ b/server/src/main/java/com/vaadin/navigator/ViewDisplay.java
diff --git a/server/src/com/vaadin/navigator/ViewProvider.java b/server/src/main/java/com/vaadin/navigator/ViewProvider.java
index ecf4e51073..ecf4e51073 100644
--- a/server/src/com/vaadin/navigator/ViewProvider.java
+++ b/server/src/main/java/com/vaadin/navigator/ViewProvider.java
diff --git a/server/src/com/vaadin/server/AbstractClientConnector.java b/server/src/main/java/com/vaadin/server/AbstractClientConnector.java
index c624663d50..c624663d50 100644
--- a/server/src/com/vaadin/server/AbstractClientConnector.java
+++ b/server/src/main/java/com/vaadin/server/AbstractClientConnector.java
diff --git a/server/src/com/vaadin/server/AbstractDeploymentConfiguration.java b/server/src/main/java/com/vaadin/server/AbstractDeploymentConfiguration.java
index 2554e421c8..2554e421c8 100644
--- a/server/src/com/vaadin/server/AbstractDeploymentConfiguration.java
+++ b/server/src/main/java/com/vaadin/server/AbstractDeploymentConfiguration.java
diff --git a/server/src/com/vaadin/server/AbstractErrorMessage.java b/server/src/main/java/com/vaadin/server/AbstractErrorMessage.java
index b56521993a..b56521993a 100644
--- a/server/src/com/vaadin/server/AbstractErrorMessage.java
+++ b/server/src/main/java/com/vaadin/server/AbstractErrorMessage.java
diff --git a/server/src/com/vaadin/server/AbstractExtension.java b/server/src/main/java/com/vaadin/server/AbstractExtension.java
index c72cc9cb39..c72cc9cb39 100644
--- a/server/src/com/vaadin/server/AbstractExtension.java
+++ b/server/src/main/java/com/vaadin/server/AbstractExtension.java
diff --git a/server/src/com/vaadin/server/AbstractJavaScriptExtension.java b/server/src/main/java/com/vaadin/server/AbstractJavaScriptExtension.java
index 2fb50fe7dd..2fb50fe7dd 100644
--- a/server/src/com/vaadin/server/AbstractJavaScriptExtension.java
+++ b/server/src/main/java/com/vaadin/server/AbstractJavaScriptExtension.java
diff --git a/server/src/com/vaadin/server/BootstrapFragmentResponse.java b/server/src/main/java/com/vaadin/server/BootstrapFragmentResponse.java
index 14a12a20ec..14a12a20ec 100644
--- a/server/src/com/vaadin/server/BootstrapFragmentResponse.java
+++ b/server/src/main/java/com/vaadin/server/BootstrapFragmentResponse.java
diff --git a/server/src/com/vaadin/server/BootstrapHandler.java b/server/src/main/java/com/vaadin/server/BootstrapHandler.java
index a9343a7e03..a9343a7e03 100644
--- a/server/src/com/vaadin/server/BootstrapHandler.java
+++ b/server/src/main/java/com/vaadin/server/BootstrapHandler.java
diff --git a/server/src/com/vaadin/server/BootstrapListener.java b/server/src/main/java/com/vaadin/server/BootstrapListener.java
index 374268dbdc..374268dbdc 100644
--- a/server/src/com/vaadin/server/BootstrapListener.java
+++ b/server/src/main/java/com/vaadin/server/BootstrapListener.java
diff --git a/server/src/com/vaadin/server/BootstrapPageResponse.java b/server/src/main/java/com/vaadin/server/BootstrapPageResponse.java
index e57ed413f0..e57ed413f0 100644
--- a/server/src/com/vaadin/server/BootstrapPageResponse.java
+++ b/server/src/main/java/com/vaadin/server/BootstrapPageResponse.java
diff --git a/server/src/com/vaadin/server/BootstrapResponse.java b/server/src/main/java/com/vaadin/server/BootstrapResponse.java
index 59e18d4c8a..59e18d4c8a 100644
--- a/server/src/com/vaadin/server/BootstrapResponse.java
+++ b/server/src/main/java/com/vaadin/server/BootstrapResponse.java
diff --git a/server/src/com/vaadin/server/BrowserWindowOpener.java b/server/src/main/java/com/vaadin/server/BrowserWindowOpener.java
index c1b8cbe91e..c1b8cbe91e 100644
--- a/server/src/com/vaadin/server/BrowserWindowOpener.java
+++ b/server/src/main/java/com/vaadin/server/BrowserWindowOpener.java
diff --git a/server/src/com/vaadin/server/ClassResource.java b/server/src/main/java/com/vaadin/server/ClassResource.java
index 5fb30095ed..5fb30095ed 100644
--- a/server/src/com/vaadin/server/ClassResource.java
+++ b/server/src/main/java/com/vaadin/server/ClassResource.java
diff --git a/server/src/com/vaadin/server/ClientConnector.java b/server/src/main/java/com/vaadin/server/ClientConnector.java
index 63483bc254..63483bc254 100644
--- a/server/src/com/vaadin/server/ClientConnector.java
+++ b/server/src/main/java/com/vaadin/server/ClientConnector.java
diff --git a/server/src/com/vaadin/server/ClientMethodInvocation.java b/server/src/main/java/com/vaadin/server/ClientMethodInvocation.java
index 77849c83df..77849c83df 100644
--- a/server/src/com/vaadin/server/ClientMethodInvocation.java
+++ b/server/src/main/java/com/vaadin/server/ClientMethodInvocation.java
diff --git a/server/src/com/vaadin/server/ComponentSizeValidator.java b/server/src/main/java/com/vaadin/server/ComponentSizeValidator.java
index b8b06c780f..b8b06c780f 100644
--- a/server/src/com/vaadin/server/ComponentSizeValidator.java
+++ b/server/src/main/java/com/vaadin/server/ComponentSizeValidator.java
diff --git a/server/src/com/vaadin/server/CompositeErrorMessage.java b/server/src/main/java/com/vaadin/server/CompositeErrorMessage.java
index ee2af74994..ee2af74994 100644
--- a/server/src/com/vaadin/server/CompositeErrorMessage.java
+++ b/server/src/main/java/com/vaadin/server/CompositeErrorMessage.java
diff --git a/server/src/com/vaadin/server/ConnectorResource.java b/server/src/main/java/com/vaadin/server/ConnectorResource.java
index 3c4fb1955f..3c4fb1955f 100644
--- a/server/src/com/vaadin/server/ConnectorResource.java
+++ b/server/src/main/java/com/vaadin/server/ConnectorResource.java
diff --git a/server/src/com/vaadin/server/ConnectorResourceHandler.java b/server/src/main/java/com/vaadin/server/ConnectorResourceHandler.java
index 8715134773..8715134773 100644
--- a/server/src/com/vaadin/server/ConnectorResourceHandler.java
+++ b/server/src/main/java/com/vaadin/server/ConnectorResourceHandler.java
diff --git a/server/src/com/vaadin/server/Constants.java b/server/src/main/java/com/vaadin/server/Constants.java
index 4dd4b45cfd..4dd4b45cfd 100644
--- a/server/src/com/vaadin/server/Constants.java
+++ b/server/src/main/java/com/vaadin/server/Constants.java
diff --git a/server/src/com/vaadin/server/CustomizedSystemMessages.java b/server/src/main/java/com/vaadin/server/CustomizedSystemMessages.java
index 0a7f864f40..0a7f864f40 100644
--- a/server/src/com/vaadin/server/CustomizedSystemMessages.java
+++ b/server/src/main/java/com/vaadin/server/CustomizedSystemMessages.java
diff --git a/server/src/com/vaadin/server/DefaultDeploymentConfiguration.java b/server/src/main/java/com/vaadin/server/DefaultDeploymentConfiguration.java
index b26e048431..b26e048431 100644
--- a/server/src/com/vaadin/server/DefaultDeploymentConfiguration.java
+++ b/server/src/main/java/com/vaadin/server/DefaultDeploymentConfiguration.java
diff --git a/server/src/com/vaadin/server/DefaultErrorHandler.java b/server/src/main/java/com/vaadin/server/DefaultErrorHandler.java
index fa0729e011..fa0729e011 100644
--- a/server/src/com/vaadin/server/DefaultErrorHandler.java
+++ b/server/src/main/java/com/vaadin/server/DefaultErrorHandler.java
diff --git a/server/src/com/vaadin/server/DefaultSystemMessagesProvider.java b/server/src/main/java/com/vaadin/server/DefaultSystemMessagesProvider.java
index 17177c36ca..17177c36ca 100644
--- a/server/src/com/vaadin/server/DefaultSystemMessagesProvider.java
+++ b/server/src/main/java/com/vaadin/server/DefaultSystemMessagesProvider.java
diff --git a/server/src/com/vaadin/server/DefaultUIProvider.java b/server/src/main/java/com/vaadin/server/DefaultUIProvider.java
index 38525fc020..38525fc020 100644
--- a/server/src/com/vaadin/server/DefaultUIProvider.java
+++ b/server/src/main/java/com/vaadin/server/DefaultUIProvider.java
diff --git a/server/src/com/vaadin/server/DeploymentConfiguration.java b/server/src/main/java/com/vaadin/server/DeploymentConfiguration.java
index 968ec7c0c3..968ec7c0c3 100644
--- a/server/src/com/vaadin/server/DeploymentConfiguration.java
+++ b/server/src/main/java/com/vaadin/server/DeploymentConfiguration.java
diff --git a/server/src/com/vaadin/server/DownloadStream.java b/server/src/main/java/com/vaadin/server/DownloadStream.java
index 65ef560974..65ef560974 100644
--- a/server/src/com/vaadin/server/DownloadStream.java
+++ b/server/src/main/java/com/vaadin/server/DownloadStream.java
diff --git a/server/src/com/vaadin/server/DragAndDropService.java b/server/src/main/java/com/vaadin/server/DragAndDropService.java
index 4a894b3bff..4a894b3bff 100644
--- a/server/src/com/vaadin/server/DragAndDropService.java
+++ b/server/src/main/java/com/vaadin/server/DragAndDropService.java
diff --git a/server/src/com/vaadin/server/EncodeResult.java b/server/src/main/java/com/vaadin/server/EncodeResult.java
index bf4fd48438..bf4fd48438 100644
--- a/server/src/com/vaadin/server/EncodeResult.java
+++ b/server/src/main/java/com/vaadin/server/EncodeResult.java
diff --git a/server/src/com/vaadin/server/ErrorEvent.java b/server/src/main/java/com/vaadin/server/ErrorEvent.java
index 5f8cb4eaca..5f8cb4eaca 100644
--- a/server/src/com/vaadin/server/ErrorEvent.java
+++ b/server/src/main/java/com/vaadin/server/ErrorEvent.java
diff --git a/server/src/com/vaadin/server/ErrorHandler.java b/server/src/main/java/com/vaadin/server/ErrorHandler.java
index 9c3af4c999..9c3af4c999 100644
--- a/server/src/com/vaadin/server/ErrorHandler.java
+++ b/server/src/main/java/com/vaadin/server/ErrorHandler.java
diff --git a/server/src/com/vaadin/server/ErrorHandlingRunnable.java b/server/src/main/java/com/vaadin/server/ErrorHandlingRunnable.java
index 8ec24c0bcb..8ec24c0bcb 100644
--- a/server/src/com/vaadin/server/ErrorHandlingRunnable.java
+++ b/server/src/main/java/com/vaadin/server/ErrorHandlingRunnable.java
diff --git a/server/src/com/vaadin/server/ErrorMessage.java b/server/src/main/java/com/vaadin/server/ErrorMessage.java
index 0171b95e54..0171b95e54 100644
--- a/server/src/com/vaadin/server/ErrorMessage.java
+++ b/server/src/main/java/com/vaadin/server/ErrorMessage.java
diff --git a/server/src/com/vaadin/server/Extension.java b/server/src/main/java/com/vaadin/server/Extension.java
index b27c58b4bc..b27c58b4bc 100644
--- a/server/src/com/vaadin/server/Extension.java
+++ b/server/src/main/java/com/vaadin/server/Extension.java
diff --git a/server/src/com/vaadin/server/ExternalResource.java b/server/src/main/java/com/vaadin/server/ExternalResource.java
index e3b026dde8..e3b026dde8 100644
--- a/server/src/com/vaadin/server/ExternalResource.java
+++ b/server/src/main/java/com/vaadin/server/ExternalResource.java
diff --git a/server/src/com/vaadin/server/FileDownloader.java b/server/src/main/java/com/vaadin/server/FileDownloader.java
index b0c3bb1120..b0c3bb1120 100644
--- a/server/src/com/vaadin/server/FileDownloader.java
+++ b/server/src/main/java/com/vaadin/server/FileDownloader.java
diff --git a/server/src/com/vaadin/server/FileResource.java b/server/src/main/java/com/vaadin/server/FileResource.java
index 28de124fe9..28de124fe9 100644
--- a/server/src/com/vaadin/server/FileResource.java
+++ b/server/src/main/java/com/vaadin/server/FileResource.java
diff --git a/server/src/com/vaadin/server/FontAwesome.java b/server/src/main/java/com/vaadin/server/FontAwesome.java
index 2a07a0b1a6..2a07a0b1a6 100644
--- a/server/src/com/vaadin/server/FontAwesome.java
+++ b/server/src/main/java/com/vaadin/server/FontAwesome.java
diff --git a/server/src/com/vaadin/server/FontIcon.java b/server/src/main/java/com/vaadin/server/FontIcon.java
index 2ada45084f..2ada45084f 100644
--- a/server/src/com/vaadin/server/FontIcon.java
+++ b/server/src/main/java/com/vaadin/server/FontIcon.java
diff --git a/server/src/com/vaadin/server/GAEVaadinServlet.java b/server/src/main/java/com/vaadin/server/GAEVaadinServlet.java
index 2429fde746..2429fde746 100644
--- a/server/src/com/vaadin/server/GAEVaadinServlet.java
+++ b/server/src/main/java/com/vaadin/server/GAEVaadinServlet.java
diff --git a/server/src/com/vaadin/server/GenericFontIcon.java b/server/src/main/java/com/vaadin/server/GenericFontIcon.java
index cf435d55e6..cf435d55e6 100644
--- a/server/src/com/vaadin/server/GenericFontIcon.java
+++ b/server/src/main/java/com/vaadin/server/GenericFontIcon.java
diff --git a/server/src/com/vaadin/server/GlobalResourceHandler.java b/server/src/main/java/com/vaadin/server/GlobalResourceHandler.java
index d1ef125534..d1ef125534 100644
--- a/server/src/com/vaadin/server/GlobalResourceHandler.java
+++ b/server/src/main/java/com/vaadin/server/GlobalResourceHandler.java
diff --git a/server/src/com/vaadin/server/JavaScriptCallbackHelper.java b/server/src/main/java/com/vaadin/server/JavaScriptCallbackHelper.java
index ac4a586d00..ac4a586d00 100644
--- a/server/src/com/vaadin/server/JavaScriptCallbackHelper.java
+++ b/server/src/main/java/com/vaadin/server/JavaScriptCallbackHelper.java
diff --git a/server/src/com/vaadin/server/JsonCodec.java b/server/src/main/java/com/vaadin/server/JsonCodec.java
index 8b685bb046..8b685bb046 100644
--- a/server/src/com/vaadin/server/JsonCodec.java
+++ b/server/src/main/java/com/vaadin/server/JsonCodec.java
diff --git a/server/src/com/vaadin/server/JsonPaintTarget.java b/server/src/main/java/com/vaadin/server/JsonPaintTarget.java
index 47c69f1a30..47c69f1a30 100644
--- a/server/src/com/vaadin/server/JsonPaintTarget.java
+++ b/server/src/main/java/com/vaadin/server/JsonPaintTarget.java
diff --git a/server/src/com/vaadin/server/KeyMapper.java b/server/src/main/java/com/vaadin/server/KeyMapper.java
index 0e4b7edc77..0e4b7edc77 100644
--- a/server/src/com/vaadin/server/KeyMapper.java
+++ b/server/src/main/java/com/vaadin/server/KeyMapper.java
diff --git a/server/src/com/vaadin/server/LegacyApplication.java b/server/src/main/java/com/vaadin/server/LegacyApplication.java
index d03b3d7f96..d03b3d7f96 100644
--- a/server/src/com/vaadin/server/LegacyApplication.java
+++ b/server/src/main/java/com/vaadin/server/LegacyApplication.java
diff --git a/server/src/com/vaadin/server/LegacyApplicationUIProvider.java b/server/src/main/java/com/vaadin/server/LegacyApplicationUIProvider.java
index 0977071806..0977071806 100644
--- a/server/src/com/vaadin/server/LegacyApplicationUIProvider.java
+++ b/server/src/main/java/com/vaadin/server/LegacyApplicationUIProvider.java
diff --git a/server/src/com/vaadin/server/LegacyCommunicationManager.java b/server/src/main/java/com/vaadin/server/LegacyCommunicationManager.java
index 87b484a65f..87b484a65f 100644
--- a/server/src/com/vaadin/server/LegacyCommunicationManager.java
+++ b/server/src/main/java/com/vaadin/server/LegacyCommunicationManager.java
diff --git a/server/src/com/vaadin/server/LegacyPaint.java b/server/src/main/java/com/vaadin/server/LegacyPaint.java
index 91ff103db6..91ff103db6 100644
--- a/server/src/com/vaadin/server/LegacyPaint.java
+++ b/server/src/main/java/com/vaadin/server/LegacyPaint.java
diff --git a/server/src/com/vaadin/server/LegacyVaadinPortlet.java b/server/src/main/java/com/vaadin/server/LegacyVaadinPortlet.java
index 606809d893..606809d893 100644
--- a/server/src/com/vaadin/server/LegacyVaadinPortlet.java
+++ b/server/src/main/java/com/vaadin/server/LegacyVaadinPortlet.java
diff --git a/server/src/com/vaadin/server/LegacyVaadinServlet.java b/server/src/main/java/com/vaadin/server/LegacyVaadinServlet.java
index 8ef16b50bc..8ef16b50bc 100644
--- a/server/src/com/vaadin/server/LegacyVaadinServlet.java
+++ b/server/src/main/java/com/vaadin/server/LegacyVaadinServlet.java
diff --git a/server/src/com/vaadin/server/LocaleService.java b/server/src/main/java/com/vaadin/server/LocaleService.java
index ccdc49f690..ccdc49f690 100644
--- a/server/src/com/vaadin/server/LocaleService.java
+++ b/server/src/main/java/com/vaadin/server/LocaleService.java
diff --git a/server/src/com/vaadin/server/NoInputStreamException.java b/server/src/main/java/com/vaadin/server/NoInputStreamException.java
index 9f12c52fdf..9f12c52fdf 100644
--- a/server/src/com/vaadin/server/NoInputStreamException.java
+++ b/server/src/main/java/com/vaadin/server/NoInputStreamException.java
diff --git a/server/src/com/vaadin/server/NoOutputStreamException.java b/server/src/main/java/com/vaadin/server/NoOutputStreamException.java
index 8dce2194e8..8dce2194e8 100644
--- a/server/src/com/vaadin/server/NoOutputStreamException.java
+++ b/server/src/main/java/com/vaadin/server/NoOutputStreamException.java
diff --git a/server/src/com/vaadin/server/Page.java b/server/src/main/java/com/vaadin/server/Page.java
index 74d79ade50..74d79ade50 100644
--- a/server/src/com/vaadin/server/Page.java
+++ b/server/src/main/java/com/vaadin/server/Page.java
diff --git a/server/src/com/vaadin/server/PaintException.java b/server/src/main/java/com/vaadin/server/PaintException.java
index a7025598b2..a7025598b2 100644
--- a/server/src/com/vaadin/server/PaintException.java
+++ b/server/src/main/java/com/vaadin/server/PaintException.java
diff --git a/server/src/com/vaadin/server/PaintTarget.java b/server/src/main/java/com/vaadin/server/PaintTarget.java
index 902cb13816..902cb13816 100644
--- a/server/src/com/vaadin/server/PaintTarget.java
+++ b/server/src/main/java/com/vaadin/server/PaintTarget.java
diff --git a/server/src/com/vaadin/server/RequestHandler.java b/server/src/main/java/com/vaadin/server/RequestHandler.java
index b667ed038c..b667ed038c 100644
--- a/server/src/com/vaadin/server/RequestHandler.java
+++ b/server/src/main/java/com/vaadin/server/RequestHandler.java
diff --git a/server/src/com/vaadin/server/Resource.java b/server/src/main/java/com/vaadin/server/Resource.java
index 20e0bb7f9a..20e0bb7f9a 100644
--- a/server/src/com/vaadin/server/Resource.java
+++ b/server/src/main/java/com/vaadin/server/Resource.java
diff --git a/server/src/com/vaadin/server/ResourceReference.java b/server/src/main/java/com/vaadin/server/ResourceReference.java
index aeb06394b7..aeb06394b7 100644
--- a/server/src/com/vaadin/server/ResourceReference.java
+++ b/server/src/main/java/com/vaadin/server/ResourceReference.java
diff --git a/server/src/com/vaadin/server/Responsive.java b/server/src/main/java/com/vaadin/server/Responsive.java
index 9209f14ff9..9209f14ff9 100644
--- a/server/src/com/vaadin/server/Responsive.java
+++ b/server/src/main/java/com/vaadin/server/Responsive.java
diff --git a/server/src/com/vaadin/server/RestrictedRenderResponse.java b/server/src/main/java/com/vaadin/server/RestrictedRenderResponse.java
index 5bee476cff..5bee476cff 100644
--- a/server/src/com/vaadin/server/RestrictedRenderResponse.java
+++ b/server/src/main/java/com/vaadin/server/RestrictedRenderResponse.java
diff --git a/server/src/com/vaadin/server/Scrollable.java b/server/src/main/java/com/vaadin/server/Scrollable.java
index ae6828e339..ae6828e339 100644
--- a/server/src/com/vaadin/server/Scrollable.java
+++ b/server/src/main/java/com/vaadin/server/Scrollable.java
diff --git a/server/src/com/vaadin/server/ServerRpcManager.java b/server/src/main/java/com/vaadin/server/ServerRpcManager.java
index ae99622a4a..ae99622a4a 100644
--- a/server/src/com/vaadin/server/ServerRpcManager.java
+++ b/server/src/main/java/com/vaadin/server/ServerRpcManager.java
diff --git a/server/src/com/vaadin/server/ServerRpcMethodInvocation.java b/server/src/main/java/com/vaadin/server/ServerRpcMethodInvocation.java
index d3f8531406..d3f8531406 100644
--- a/server/src/com/vaadin/server/ServerRpcMethodInvocation.java
+++ b/server/src/main/java/com/vaadin/server/ServerRpcMethodInvocation.java
diff --git a/server/src/com/vaadin/server/ServiceDestroyEvent.java b/server/src/main/java/com/vaadin/server/ServiceDestroyEvent.java
index 2ed0bbf8f1..2ed0bbf8f1 100644
--- a/server/src/com/vaadin/server/ServiceDestroyEvent.java
+++ b/server/src/main/java/com/vaadin/server/ServiceDestroyEvent.java
diff --git a/server/src/com/vaadin/server/ServiceDestroyListener.java b/server/src/main/java/com/vaadin/server/ServiceDestroyListener.java
index 1549d82d51..1549d82d51 100644
--- a/server/src/com/vaadin/server/ServiceDestroyListener.java
+++ b/server/src/main/java/com/vaadin/server/ServiceDestroyListener.java
diff --git a/server/src/com/vaadin/server/ServiceException.java b/server/src/main/java/com/vaadin/server/ServiceException.java
index 2bc36bc1d7..2bc36bc1d7 100644
--- a/server/src/com/vaadin/server/ServiceException.java
+++ b/server/src/main/java/com/vaadin/server/ServiceException.java
diff --git a/server/src/com/vaadin/server/ServletPortletHelper.java b/server/src/main/java/com/vaadin/server/ServletPortletHelper.java
index 33ecf16e17..33ecf16e17 100644
--- a/server/src/com/vaadin/server/ServletPortletHelper.java
+++ b/server/src/main/java/com/vaadin/server/ServletPortletHelper.java
diff --git a/server/src/com/vaadin/server/SessionDestroyEvent.java b/server/src/main/java/com/vaadin/server/SessionDestroyEvent.java
index a64fce0b64..a64fce0b64 100644
--- a/server/src/com/vaadin/server/SessionDestroyEvent.java
+++ b/server/src/main/java/com/vaadin/server/SessionDestroyEvent.java
diff --git a/server/src/com/vaadin/server/SessionDestroyListener.java b/server/src/main/java/com/vaadin/server/SessionDestroyListener.java
index 29daa60a40..29daa60a40 100644
--- a/server/src/com/vaadin/server/SessionDestroyListener.java
+++ b/server/src/main/java/com/vaadin/server/SessionDestroyListener.java
diff --git a/server/src/com/vaadin/server/SessionExpiredException.java b/server/src/main/java/com/vaadin/server/SessionExpiredException.java
index d70498e7cb..d70498e7cb 100644
--- a/server/src/com/vaadin/server/SessionExpiredException.java
+++ b/server/src/main/java/com/vaadin/server/SessionExpiredException.java
diff --git a/server/src/com/vaadin/server/SessionExpiredHandler.java b/server/src/main/java/com/vaadin/server/SessionExpiredHandler.java
index 3d6de95dea..3d6de95dea 100644
--- a/server/src/com/vaadin/server/SessionExpiredHandler.java
+++ b/server/src/main/java/com/vaadin/server/SessionExpiredHandler.java
diff --git a/server/src/com/vaadin/server/SessionInitEvent.java b/server/src/main/java/com/vaadin/server/SessionInitEvent.java
index 76262c6140..76262c6140 100644
--- a/server/src/com/vaadin/server/SessionInitEvent.java
+++ b/server/src/main/java/com/vaadin/server/SessionInitEvent.java
diff --git a/server/src/com/vaadin/server/SessionInitListener.java b/server/src/main/java/com/vaadin/server/SessionInitListener.java
index 2bbb8e3d1f..2bbb8e3d1f 100644
--- a/server/src/com/vaadin/server/SessionInitListener.java
+++ b/server/src/main/java/com/vaadin/server/SessionInitListener.java
diff --git a/server/src/com/vaadin/server/SizeWithUnit.java b/server/src/main/java/com/vaadin/server/SizeWithUnit.java
index 4c3c51eaec..4c3c51eaec 100644
--- a/server/src/com/vaadin/server/SizeWithUnit.java
+++ b/server/src/main/java/com/vaadin/server/SizeWithUnit.java
diff --git a/server/src/com/vaadin/server/Sizeable.java b/server/src/main/java/com/vaadin/server/Sizeable.java
index ede5e6ab3b..ede5e6ab3b 100644
--- a/server/src/com/vaadin/server/Sizeable.java
+++ b/server/src/main/java/com/vaadin/server/Sizeable.java
diff --git a/server/src/com/vaadin/server/StreamResource.java b/server/src/main/java/com/vaadin/server/StreamResource.java
index 070cfb5138..070cfb5138 100644
--- a/server/src/com/vaadin/server/StreamResource.java
+++ b/server/src/main/java/com/vaadin/server/StreamResource.java
diff --git a/server/src/com/vaadin/server/StreamVariable.java b/server/src/main/java/com/vaadin/server/StreamVariable.java
index c7b84c92d6..c7b84c92d6 100644
--- a/server/src/com/vaadin/server/StreamVariable.java
+++ b/server/src/main/java/com/vaadin/server/StreamVariable.java
diff --git a/server/src/com/vaadin/server/SynchronizedRequestHandler.java b/server/src/main/java/com/vaadin/server/SynchronizedRequestHandler.java
index 56abfbb8f3..56abfbb8f3 100644
--- a/server/src/com/vaadin/server/SynchronizedRequestHandler.java
+++ b/server/src/main/java/com/vaadin/server/SynchronizedRequestHandler.java
diff --git a/server/src/com/vaadin/server/SystemError.java b/server/src/main/java/com/vaadin/server/SystemError.java
index 834055e1e1..834055e1e1 100644
--- a/server/src/com/vaadin/server/SystemError.java
+++ b/server/src/main/java/com/vaadin/server/SystemError.java
diff --git a/server/src/com/vaadin/server/SystemMessageException.java b/server/src/main/java/com/vaadin/server/SystemMessageException.java
index 854d8001f6..854d8001f6 100644
--- a/server/src/com/vaadin/server/SystemMessageException.java
+++ b/server/src/main/java/com/vaadin/server/SystemMessageException.java
diff --git a/server/src/com/vaadin/server/SystemMessages.java b/server/src/main/java/com/vaadin/server/SystemMessages.java
index 3bcf0a90fa..3bcf0a90fa 100644
--- a/server/src/com/vaadin/server/SystemMessages.java
+++ b/server/src/main/java/com/vaadin/server/SystemMessages.java
diff --git a/server/src/com/vaadin/server/SystemMessagesInfo.java b/server/src/main/java/com/vaadin/server/SystemMessagesInfo.java
index 195cf3c711..195cf3c711 100644
--- a/server/src/com/vaadin/server/SystemMessagesInfo.java
+++ b/server/src/main/java/com/vaadin/server/SystemMessagesInfo.java
diff --git a/server/src/com/vaadin/server/SystemMessagesProvider.java b/server/src/main/java/com/vaadin/server/SystemMessagesProvider.java
index a69cc0b159..a69cc0b159 100644
--- a/server/src/com/vaadin/server/SystemMessagesProvider.java
+++ b/server/src/main/java/com/vaadin/server/SystemMessagesProvider.java
diff --git a/server/src/com/vaadin/server/ThemeResource.java b/server/src/main/java/com/vaadin/server/ThemeResource.java
index 45a2736bf3..45a2736bf3 100644
--- a/server/src/com/vaadin/server/ThemeResource.java
+++ b/server/src/main/java/com/vaadin/server/ThemeResource.java
diff --git a/server/src/com/vaadin/server/UIClassSelectionEvent.java b/server/src/main/java/com/vaadin/server/UIClassSelectionEvent.java
index 9c9bbe5bc9..9c9bbe5bc9 100644
--- a/server/src/com/vaadin/server/UIClassSelectionEvent.java
+++ b/server/src/main/java/com/vaadin/server/UIClassSelectionEvent.java
diff --git a/server/src/com/vaadin/server/UICreateEvent.java b/server/src/main/java/com/vaadin/server/UICreateEvent.java
index 1688416ba5..1688416ba5 100644
--- a/server/src/com/vaadin/server/UICreateEvent.java
+++ b/server/src/main/java/com/vaadin/server/UICreateEvent.java
diff --git a/server/src/com/vaadin/server/UIProvider.java b/server/src/main/java/com/vaadin/server/UIProvider.java
index d3d834cad7..d3d834cad7 100644
--- a/server/src/com/vaadin/server/UIProvider.java
+++ b/server/src/main/java/com/vaadin/server/UIProvider.java
diff --git a/server/src/com/vaadin/server/UIProviderEvent.java b/server/src/main/java/com/vaadin/server/UIProviderEvent.java
index 1fcc0a3ddc..1fcc0a3ddc 100644
--- a/server/src/com/vaadin/server/UIProviderEvent.java
+++ b/server/src/main/java/com/vaadin/server/UIProviderEvent.java
diff --git a/server/src/com/vaadin/server/UnsupportedBrowserHandler.java b/server/src/main/java/com/vaadin/server/UnsupportedBrowserHandler.java
index e5ea55b116..e5ea55b116 100644
--- a/server/src/com/vaadin/server/UnsupportedBrowserHandler.java
+++ b/server/src/main/java/com/vaadin/server/UnsupportedBrowserHandler.java
diff --git a/server/src/com/vaadin/server/UploadException.java b/server/src/main/java/com/vaadin/server/UploadException.java
index 1f1073b435..1f1073b435 100644
--- a/server/src/com/vaadin/server/UploadException.java
+++ b/server/src/main/java/com/vaadin/server/UploadException.java
diff --git a/server/src/com/vaadin/server/UserError.java b/server/src/main/java/com/vaadin/server/UserError.java
index ec1ac042f8..ec1ac042f8 100644
--- a/server/src/com/vaadin/server/UserError.java
+++ b/server/src/main/java/com/vaadin/server/UserError.java
diff --git a/server/src/com/vaadin/server/VaadinPortlet.java b/server/src/main/java/com/vaadin/server/VaadinPortlet.java
index 043f95fd7b..043f95fd7b 100644
--- a/server/src/com/vaadin/server/VaadinPortlet.java
+++ b/server/src/main/java/com/vaadin/server/VaadinPortlet.java
diff --git a/server/src/com/vaadin/server/VaadinPortletRequest.java b/server/src/main/java/com/vaadin/server/VaadinPortletRequest.java
index 93e06d7f45..93e06d7f45 100644
--- a/server/src/com/vaadin/server/VaadinPortletRequest.java
+++ b/server/src/main/java/com/vaadin/server/VaadinPortletRequest.java
diff --git a/server/src/com/vaadin/server/VaadinPortletResponse.java b/server/src/main/java/com/vaadin/server/VaadinPortletResponse.java
index 2b6e0c75fb..2b6e0c75fb 100644
--- a/server/src/com/vaadin/server/VaadinPortletResponse.java
+++ b/server/src/main/java/com/vaadin/server/VaadinPortletResponse.java
diff --git a/server/src/com/vaadin/server/VaadinPortletService.java b/server/src/main/java/com/vaadin/server/VaadinPortletService.java
index 5f22dd7d7c..5f22dd7d7c 100644
--- a/server/src/com/vaadin/server/VaadinPortletService.java
+++ b/server/src/main/java/com/vaadin/server/VaadinPortletService.java
diff --git a/server/src/com/vaadin/server/VaadinPortletSession.java b/server/src/main/java/com/vaadin/server/VaadinPortletSession.java
index 23b5027b03..23b5027b03 100644
--- a/server/src/com/vaadin/server/VaadinPortletSession.java
+++ b/server/src/main/java/com/vaadin/server/VaadinPortletSession.java
diff --git a/server/src/com/vaadin/server/VaadinRequest.java b/server/src/main/java/com/vaadin/server/VaadinRequest.java
index 5b7e16ac46..5b7e16ac46 100644
--- a/server/src/com/vaadin/server/VaadinRequest.java
+++ b/server/src/main/java/com/vaadin/server/VaadinRequest.java
diff --git a/server/src/com/vaadin/server/VaadinResponse.java b/server/src/main/java/com/vaadin/server/VaadinResponse.java
index c31c6c05d8..c31c6c05d8 100644
--- a/server/src/com/vaadin/server/VaadinResponse.java
+++ b/server/src/main/java/com/vaadin/server/VaadinResponse.java
diff --git a/server/src/com/vaadin/server/VaadinService.java b/server/src/main/java/com/vaadin/server/VaadinService.java
index 740371aec1..740371aec1 100644
--- a/server/src/com/vaadin/server/VaadinService.java
+++ b/server/src/main/java/com/vaadin/server/VaadinService.java
diff --git a/server/src/com/vaadin/server/VaadinServiceClassLoaderUtil.java b/server/src/main/java/com/vaadin/server/VaadinServiceClassLoaderUtil.java
index 8c85a6b3b3..8c85a6b3b3 100644
--- a/server/src/com/vaadin/server/VaadinServiceClassLoaderUtil.java
+++ b/server/src/main/java/com/vaadin/server/VaadinServiceClassLoaderUtil.java
diff --git a/server/src/com/vaadin/server/VaadinServlet.java b/server/src/main/java/com/vaadin/server/VaadinServlet.java
index cd6e4cd7cd..cd6e4cd7cd 100644
--- a/server/src/com/vaadin/server/VaadinServlet.java
+++ b/server/src/main/java/com/vaadin/server/VaadinServlet.java
diff --git a/server/src/com/vaadin/server/VaadinServletRequest.java b/server/src/main/java/com/vaadin/server/VaadinServletRequest.java
index c68eefedb1..c68eefedb1 100644
--- a/server/src/com/vaadin/server/VaadinServletRequest.java
+++ b/server/src/main/java/com/vaadin/server/VaadinServletRequest.java
diff --git a/server/src/com/vaadin/server/VaadinServletResponse.java b/server/src/main/java/com/vaadin/server/VaadinServletResponse.java
index fd688a594c..fd688a594c 100644
--- a/server/src/com/vaadin/server/VaadinServletResponse.java
+++ b/server/src/main/java/com/vaadin/server/VaadinServletResponse.java
diff --git a/server/src/com/vaadin/server/VaadinServletService.java b/server/src/main/java/com/vaadin/server/VaadinServletService.java
index 5faea1ce6c..5faea1ce6c 100644
--- a/server/src/com/vaadin/server/VaadinServletService.java
+++ b/server/src/main/java/com/vaadin/server/VaadinServletService.java
diff --git a/server/src/com/vaadin/server/VaadinSession.java b/server/src/main/java/com/vaadin/server/VaadinSession.java
index 304dd4bec6..304dd4bec6 100644
--- a/server/src/com/vaadin/server/VaadinSession.java
+++ b/server/src/main/java/com/vaadin/server/VaadinSession.java
diff --git a/server/src/com/vaadin/server/VariableOwner.java b/server/src/main/java/com/vaadin/server/VariableOwner.java
index 87a820e8b7..87a820e8b7 100644
--- a/server/src/com/vaadin/server/VariableOwner.java
+++ b/server/src/main/java/com/vaadin/server/VariableOwner.java
diff --git a/server/src/com/vaadin/server/ViewportGenerator.java b/server/src/main/java/com/vaadin/server/ViewportGenerator.java
index 33cc1341af..33cc1341af 100644
--- a/server/src/com/vaadin/server/ViewportGenerator.java
+++ b/server/src/main/java/com/vaadin/server/ViewportGenerator.java
diff --git a/server/src/com/vaadin/server/WebBrowser.java b/server/src/main/java/com/vaadin/server/WebBrowser.java
index 5b7d795793..5b7d795793 100644
--- a/server/src/com/vaadin/server/WebBrowser.java
+++ b/server/src/main/java/com/vaadin/server/WebBrowser.java
diff --git a/server/src/com/vaadin/server/WrappedHttpSession.java b/server/src/main/java/com/vaadin/server/WrappedHttpSession.java
index db4318e37a..db4318e37a 100644
--- a/server/src/com/vaadin/server/WrappedHttpSession.java
+++ b/server/src/main/java/com/vaadin/server/WrappedHttpSession.java
diff --git a/server/src/com/vaadin/server/WrappedPortletSession.java b/server/src/main/java/com/vaadin/server/WrappedPortletSession.java
index 9f0f1ac10f..9f0f1ac10f 100644
--- a/server/src/com/vaadin/server/WrappedPortletSession.java
+++ b/server/src/main/java/com/vaadin/server/WrappedPortletSession.java
diff --git a/server/src/com/vaadin/server/WrappedSession.java b/server/src/main/java/com/vaadin/server/WrappedSession.java
index b839e5d87a..b839e5d87a 100644
--- a/server/src/com/vaadin/server/WrappedSession.java
+++ b/server/src/main/java/com/vaadin/server/WrappedSession.java
diff --git a/server/src/com/vaadin/server/communication/AbstractStreamingEvent.java b/server/src/main/java/com/vaadin/server/communication/AbstractStreamingEvent.java
index 1f546b2489..1f546b2489 100644
--- a/server/src/com/vaadin/server/communication/AbstractStreamingEvent.java
+++ b/server/src/main/java/com/vaadin/server/communication/AbstractStreamingEvent.java
diff --git a/server/src/com/vaadin/server/communication/AtmospherePushConnection.java b/server/src/main/java/com/vaadin/server/communication/AtmospherePushConnection.java
index 5c0d2e14d4..5c0d2e14d4 100644
--- a/server/src/com/vaadin/server/communication/AtmospherePushConnection.java
+++ b/server/src/main/java/com/vaadin/server/communication/AtmospherePushConnection.java
diff --git a/server/src/com/vaadin/server/communication/ClientRpcWriter.java b/server/src/main/java/com/vaadin/server/communication/ClientRpcWriter.java
index 2ecf81287e..2ecf81287e 100644
--- a/server/src/com/vaadin/server/communication/ClientRpcWriter.java
+++ b/server/src/main/java/com/vaadin/server/communication/ClientRpcWriter.java
diff --git a/server/src/com/vaadin/server/communication/ConnectorHierarchyWriter.java b/server/src/main/java/com/vaadin/server/communication/ConnectorHierarchyWriter.java
index 16ed9985c4..16ed9985c4 100644
--- a/server/src/com/vaadin/server/communication/ConnectorHierarchyWriter.java
+++ b/server/src/main/java/com/vaadin/server/communication/ConnectorHierarchyWriter.java
diff --git a/server/src/com/vaadin/server/communication/ConnectorTypeWriter.java b/server/src/main/java/com/vaadin/server/communication/ConnectorTypeWriter.java
index d534987061..d534987061 100644
--- a/server/src/com/vaadin/server/communication/ConnectorTypeWriter.java
+++ b/server/src/main/java/com/vaadin/server/communication/ConnectorTypeWriter.java
diff --git a/server/src/com/vaadin/server/communication/DateSerializer.java b/server/src/main/java/com/vaadin/server/communication/DateSerializer.java
index 593728bac7..593728bac7 100644
--- a/server/src/com/vaadin/server/communication/DateSerializer.java
+++ b/server/src/main/java/com/vaadin/server/communication/DateSerializer.java
diff --git a/server/src/com/vaadin/server/communication/FileUploadHandler.java b/server/src/main/java/com/vaadin/server/communication/FileUploadHandler.java
index b9eaff3bd1..b9eaff3bd1 100644
--- a/server/src/com/vaadin/server/communication/FileUploadHandler.java
+++ b/server/src/main/java/com/vaadin/server/communication/FileUploadHandler.java
diff --git a/server/src/com/vaadin/server/communication/HeartbeatHandler.java b/server/src/main/java/com/vaadin/server/communication/HeartbeatHandler.java
index c6711d1d18..c6711d1d18 100644
--- a/server/src/com/vaadin/server/communication/HeartbeatHandler.java
+++ b/server/src/main/java/com/vaadin/server/communication/HeartbeatHandler.java
diff --git a/server/src/com/vaadin/server/communication/JSONSerializer.java b/server/src/main/java/com/vaadin/server/communication/JSONSerializer.java
index 7f673d01e8..7f673d01e8 100644
--- a/server/src/com/vaadin/server/communication/JSONSerializer.java
+++ b/server/src/main/java/com/vaadin/server/communication/JSONSerializer.java
diff --git a/server/src/com/vaadin/server/communication/JSR356WebsocketInitializer.java b/server/src/main/java/com/vaadin/server/communication/JSR356WebsocketInitializer.java
index 6d2843a4fc..6d2843a4fc 100644
--- a/server/src/com/vaadin/server/communication/JSR356WebsocketInitializer.java
+++ b/server/src/main/java/com/vaadin/server/communication/JSR356WebsocketInitializer.java
diff --git a/server/src/com/vaadin/server/communication/LegacyUidlWriter.java b/server/src/main/java/com/vaadin/server/communication/LegacyUidlWriter.java
index 3f70a25c5b..3f70a25c5b 100644
--- a/server/src/com/vaadin/server/communication/LegacyUidlWriter.java
+++ b/server/src/main/java/com/vaadin/server/communication/LegacyUidlWriter.java
diff --git a/server/src/com/vaadin/server/communication/MetadataWriter.java b/server/src/main/java/com/vaadin/server/communication/MetadataWriter.java
index 9c46e64692..9c46e64692 100644
--- a/server/src/com/vaadin/server/communication/MetadataWriter.java
+++ b/server/src/main/java/com/vaadin/server/communication/MetadataWriter.java
diff --git a/server/src/com/vaadin/server/communication/PortletBootstrapHandler.java b/server/src/main/java/com/vaadin/server/communication/PortletBootstrapHandler.java
index 289309b631..289309b631 100644
--- a/server/src/com/vaadin/server/communication/PortletBootstrapHandler.java
+++ b/server/src/main/java/com/vaadin/server/communication/PortletBootstrapHandler.java
diff --git a/server/src/com/vaadin/server/communication/PortletDummyRequestHandler.java b/server/src/main/java/com/vaadin/server/communication/PortletDummyRequestHandler.java
index a79f5e96f2..a79f5e96f2 100644
--- a/server/src/com/vaadin/server/communication/PortletDummyRequestHandler.java
+++ b/server/src/main/java/com/vaadin/server/communication/PortletDummyRequestHandler.java
diff --git a/server/src/com/vaadin/server/communication/PortletListenerNotifier.java b/server/src/main/java/com/vaadin/server/communication/PortletListenerNotifier.java
index 3aa3426d2f..3aa3426d2f 100644
--- a/server/src/com/vaadin/server/communication/PortletListenerNotifier.java
+++ b/server/src/main/java/com/vaadin/server/communication/PortletListenerNotifier.java
diff --git a/server/src/com/vaadin/server/communication/PortletStateAwareRequestHandler.java b/server/src/main/java/com/vaadin/server/communication/PortletStateAwareRequestHandler.java
index a1276025d8..a1276025d8 100644
--- a/server/src/com/vaadin/server/communication/PortletStateAwareRequestHandler.java
+++ b/server/src/main/java/com/vaadin/server/communication/PortletStateAwareRequestHandler.java
diff --git a/server/src/com/vaadin/server/communication/PortletUIInitHandler.java b/server/src/main/java/com/vaadin/server/communication/PortletUIInitHandler.java
index b3cda44592..b3cda44592 100644
--- a/server/src/com/vaadin/server/communication/PortletUIInitHandler.java
+++ b/server/src/main/java/com/vaadin/server/communication/PortletUIInitHandler.java
diff --git a/server/src/com/vaadin/server/communication/PublishedFileHandler.java b/server/src/main/java/com/vaadin/server/communication/PublishedFileHandler.java
index 56edffd16d..56edffd16d 100644
--- a/server/src/com/vaadin/server/communication/PublishedFileHandler.java
+++ b/server/src/main/java/com/vaadin/server/communication/PublishedFileHandler.java
diff --git a/server/src/com/vaadin/server/communication/PushAtmosphereHandler.java b/server/src/main/java/com/vaadin/server/communication/PushAtmosphereHandler.java
index 50279a1a74..50279a1a74 100644
--- a/server/src/com/vaadin/server/communication/PushAtmosphereHandler.java
+++ b/server/src/main/java/com/vaadin/server/communication/PushAtmosphereHandler.java
diff --git a/server/src/com/vaadin/server/communication/PushConnection.java b/server/src/main/java/com/vaadin/server/communication/PushConnection.java
index d5a0d6e9bc..d5a0d6e9bc 100644
--- a/server/src/com/vaadin/server/communication/PushConnection.java
+++ b/server/src/main/java/com/vaadin/server/communication/PushConnection.java
diff --git a/server/src/com/vaadin/server/communication/PushHandler.java b/server/src/main/java/com/vaadin/server/communication/PushHandler.java
index 0b4fe28b77..0b4fe28b77 100644
--- a/server/src/com/vaadin/server/communication/PushHandler.java
+++ b/server/src/main/java/com/vaadin/server/communication/PushHandler.java
diff --git a/server/src/com/vaadin/server/communication/PushRequestHandler.java b/server/src/main/java/com/vaadin/server/communication/PushRequestHandler.java
index 84b81c8963..84b81c8963 100644
--- a/server/src/com/vaadin/server/communication/PushRequestHandler.java
+++ b/server/src/main/java/com/vaadin/server/communication/PushRequestHandler.java
diff --git a/server/src/com/vaadin/server/communication/ResourceWriter.java b/server/src/main/java/com/vaadin/server/communication/ResourceWriter.java
index 2c5d1b409b..2c5d1b409b 100644
--- a/server/src/com/vaadin/server/communication/ResourceWriter.java
+++ b/server/src/main/java/com/vaadin/server/communication/ResourceWriter.java
diff --git a/server/src/com/vaadin/server/communication/ServerRpcHandler.java b/server/src/main/java/com/vaadin/server/communication/ServerRpcHandler.java
index 593b1f544f..593b1f544f 100644
--- a/server/src/com/vaadin/server/communication/ServerRpcHandler.java
+++ b/server/src/main/java/com/vaadin/server/communication/ServerRpcHandler.java
diff --git a/server/src/com/vaadin/server/communication/ServletBootstrapHandler.java b/server/src/main/java/com/vaadin/server/communication/ServletBootstrapHandler.java
index 46909cecee..46909cecee 100644
--- a/server/src/com/vaadin/server/communication/ServletBootstrapHandler.java
+++ b/server/src/main/java/com/vaadin/server/communication/ServletBootstrapHandler.java
diff --git a/server/src/com/vaadin/server/communication/ServletUIInitHandler.java b/server/src/main/java/com/vaadin/server/communication/ServletUIInitHandler.java
index b3b1684809..b3b1684809 100644
--- a/server/src/com/vaadin/server/communication/ServletUIInitHandler.java
+++ b/server/src/main/java/com/vaadin/server/communication/ServletUIInitHandler.java
diff --git a/server/src/com/vaadin/server/communication/SessionRequestHandler.java b/server/src/main/java/com/vaadin/server/communication/SessionRequestHandler.java
index 383ad2d541..383ad2d541 100644
--- a/server/src/com/vaadin/server/communication/SessionRequestHandler.java
+++ b/server/src/main/java/com/vaadin/server/communication/SessionRequestHandler.java
diff --git a/server/src/com/vaadin/server/communication/SharedStateWriter.java b/server/src/main/java/com/vaadin/server/communication/SharedStateWriter.java
index 06b59ad4cc..06b59ad4cc 100644
--- a/server/src/com/vaadin/server/communication/SharedStateWriter.java
+++ b/server/src/main/java/com/vaadin/server/communication/SharedStateWriter.java
diff --git a/server/src/com/vaadin/server/communication/StreamingEndEventImpl.java b/server/src/main/java/com/vaadin/server/communication/StreamingEndEventImpl.java
index 6d87d0cc8b..6d87d0cc8b 100644
--- a/server/src/com/vaadin/server/communication/StreamingEndEventImpl.java
+++ b/server/src/main/java/com/vaadin/server/communication/StreamingEndEventImpl.java
diff --git a/server/src/com/vaadin/server/communication/StreamingErrorEventImpl.java b/server/src/main/java/com/vaadin/server/communication/StreamingErrorEventImpl.java
index a96f759216..a96f759216 100644
--- a/server/src/com/vaadin/server/communication/StreamingErrorEventImpl.java
+++ b/server/src/main/java/com/vaadin/server/communication/StreamingErrorEventImpl.java
diff --git a/server/src/com/vaadin/server/communication/StreamingProgressEventImpl.java b/server/src/main/java/com/vaadin/server/communication/StreamingProgressEventImpl.java
index 7f2428a55d..7f2428a55d 100644
--- a/server/src/com/vaadin/server/communication/StreamingProgressEventImpl.java
+++ b/server/src/main/java/com/vaadin/server/communication/StreamingProgressEventImpl.java
diff --git a/server/src/com/vaadin/server/communication/StreamingStartEventImpl.java b/server/src/main/java/com/vaadin/server/communication/StreamingStartEventImpl.java
index a2ce075458..a2ce075458 100644
--- a/server/src/com/vaadin/server/communication/StreamingStartEventImpl.java
+++ b/server/src/main/java/com/vaadin/server/communication/StreamingStartEventImpl.java
diff --git a/server/src/com/vaadin/server/communication/UIInitHandler.java b/server/src/main/java/com/vaadin/server/communication/UIInitHandler.java
index f380a6df6e..f380a6df6e 100644
--- a/server/src/com/vaadin/server/communication/UIInitHandler.java
+++ b/server/src/main/java/com/vaadin/server/communication/UIInitHandler.java
diff --git a/server/src/com/vaadin/server/communication/UidlRequestHandler.java b/server/src/main/java/com/vaadin/server/communication/UidlRequestHandler.java
index dda3d81453..dda3d81453 100644
--- a/server/src/com/vaadin/server/communication/UidlRequestHandler.java
+++ b/server/src/main/java/com/vaadin/server/communication/UidlRequestHandler.java
diff --git a/server/src/com/vaadin/server/communication/UidlWriter.java b/server/src/main/java/com/vaadin/server/communication/UidlWriter.java
index b117cb4b4d..b117cb4b4d 100644
--- a/server/src/com/vaadin/server/communication/UidlWriter.java
+++ b/server/src/main/java/com/vaadin/server/communication/UidlWriter.java
diff --git a/server/src/com/vaadin/server/communication/data/DataGenerator.java b/server/src/main/java/com/vaadin/server/communication/data/DataGenerator.java
index 58ba1b3b00..58ba1b3b00 100644
--- a/server/src/com/vaadin/server/communication/data/DataGenerator.java
+++ b/server/src/main/java/com/vaadin/server/communication/data/DataGenerator.java
diff --git a/server/src/com/vaadin/server/communication/data/RpcDataProviderExtension.java b/server/src/main/java/com/vaadin/server/communication/data/RpcDataProviderExtension.java
index 1b78ca4518..1b78ca4518 100644
--- a/server/src/com/vaadin/server/communication/data/RpcDataProviderExtension.java
+++ b/server/src/main/java/com/vaadin/server/communication/data/RpcDataProviderExtension.java
diff --git a/server/src/com/vaadin/server/themeutils/SASSAddonImportFileCreator.java b/server/src/main/java/com/vaadin/server/themeutils/SASSAddonImportFileCreator.java
index cfee2a320e..cfee2a320e 100644
--- a/server/src/com/vaadin/server/themeutils/SASSAddonImportFileCreator.java
+++ b/server/src/main/java/com/vaadin/server/themeutils/SASSAddonImportFileCreator.java
diff --git a/server/src/com/vaadin/server/widgetsetutils/ClassPathExplorer.java b/server/src/main/java/com/vaadin/server/widgetsetutils/ClassPathExplorer.java
index 063f4f5346..063f4f5346 100644
--- a/server/src/com/vaadin/server/widgetsetutils/ClassPathExplorer.java
+++ b/server/src/main/java/com/vaadin/server/widgetsetutils/ClassPathExplorer.java
diff --git a/server/src/com/vaadin/server/widgetsetutils/WidgetSetBuilder.java b/server/src/main/java/com/vaadin/server/widgetsetutils/WidgetSetBuilder.java
index f810a63a38..f810a63a38 100644
--- a/server/src/com/vaadin/server/widgetsetutils/WidgetSetBuilder.java
+++ b/server/src/main/java/com/vaadin/server/widgetsetutils/WidgetSetBuilder.java
diff --git a/server/src/com/vaadin/ui/AbsoluteLayout.java b/server/src/main/java/com/vaadin/ui/AbsoluteLayout.java
index c62da24612..c62da24612 100644
--- a/server/src/com/vaadin/ui/AbsoluteLayout.java
+++ b/server/src/main/java/com/vaadin/ui/AbsoluteLayout.java
diff --git a/server/src/com/vaadin/ui/AbstractColorPicker.java b/server/src/main/java/com/vaadin/ui/AbstractColorPicker.java
index 4ce4e46d6a..4ce4e46d6a 100644
--- a/server/src/com/vaadin/ui/AbstractColorPicker.java
+++ b/server/src/main/java/com/vaadin/ui/AbstractColorPicker.java
diff --git a/server/src/com/vaadin/ui/AbstractComponent.java b/server/src/main/java/com/vaadin/ui/AbstractComponent.java
index d3506e9097..d3506e9097 100644
--- a/server/src/com/vaadin/ui/AbstractComponent.java
+++ b/server/src/main/java/com/vaadin/ui/AbstractComponent.java
diff --git a/server/src/com/vaadin/ui/AbstractComponentContainer.java b/server/src/main/java/com/vaadin/ui/AbstractComponentContainer.java
index 1095331602..1095331602 100644
--- a/server/src/com/vaadin/ui/AbstractComponentContainer.java
+++ b/server/src/main/java/com/vaadin/ui/AbstractComponentContainer.java
diff --git a/server/src/com/vaadin/ui/AbstractEmbedded.java b/server/src/main/java/com/vaadin/ui/AbstractEmbedded.java
index a38e9bb788..a38e9bb788 100644
--- a/server/src/com/vaadin/ui/AbstractEmbedded.java
+++ b/server/src/main/java/com/vaadin/ui/AbstractEmbedded.java
diff --git a/server/src/com/vaadin/ui/AbstractField.java b/server/src/main/java/com/vaadin/ui/AbstractField.java
index e69322b1cc..e69322b1cc 100644
--- a/server/src/com/vaadin/ui/AbstractField.java
+++ b/server/src/main/java/com/vaadin/ui/AbstractField.java
diff --git a/server/src/com/vaadin/ui/AbstractFocusable.java b/server/src/main/java/com/vaadin/ui/AbstractFocusable.java
index ad3b96f29b..ad3b96f29b 100644
--- a/server/src/com/vaadin/ui/AbstractFocusable.java
+++ b/server/src/main/java/com/vaadin/ui/AbstractFocusable.java
diff --git a/server/src/com/vaadin/ui/AbstractJavaScriptComponent.java b/server/src/main/java/com/vaadin/ui/AbstractJavaScriptComponent.java
index 68ff947137..68ff947137 100644
--- a/server/src/com/vaadin/ui/AbstractJavaScriptComponent.java
+++ b/server/src/main/java/com/vaadin/ui/AbstractJavaScriptComponent.java
diff --git a/server/src/com/vaadin/ui/AbstractLayout.java b/server/src/main/java/com/vaadin/ui/AbstractLayout.java
index 0770670680..0770670680 100644
--- a/server/src/com/vaadin/ui/AbstractLayout.java
+++ b/server/src/main/java/com/vaadin/ui/AbstractLayout.java
diff --git a/server/src/com/vaadin/ui/AbstractMedia.java b/server/src/main/java/com/vaadin/ui/AbstractMedia.java
index a0344624d7..a0344624d7 100644
--- a/server/src/com/vaadin/ui/AbstractMedia.java
+++ b/server/src/main/java/com/vaadin/ui/AbstractMedia.java
diff --git a/server/src/com/vaadin/ui/AbstractOrderedLayout.java b/server/src/main/java/com/vaadin/ui/AbstractOrderedLayout.java
index e0dbcb004b..e0dbcb004b 100644
--- a/server/src/com/vaadin/ui/AbstractOrderedLayout.java
+++ b/server/src/main/java/com/vaadin/ui/AbstractOrderedLayout.java
diff --git a/server/src/com/vaadin/ui/AbstractSelect.java b/server/src/main/java/com/vaadin/ui/AbstractSelect.java
index 9babf7e876..9babf7e876 100644
--- a/server/src/com/vaadin/ui/AbstractSelect.java
+++ b/server/src/main/java/com/vaadin/ui/AbstractSelect.java
diff --git a/server/src/com/vaadin/ui/AbstractSingleComponentContainer.java b/server/src/main/java/com/vaadin/ui/AbstractSingleComponentContainer.java
index 0854ffe9c2..0854ffe9c2 100644
--- a/server/src/com/vaadin/ui/AbstractSingleComponentContainer.java
+++ b/server/src/main/java/com/vaadin/ui/AbstractSingleComponentContainer.java
diff --git a/server/src/com/vaadin/ui/AbstractSplitPanel.java b/server/src/main/java/com/vaadin/ui/AbstractSplitPanel.java
index 0561996277..0561996277 100644
--- a/server/src/com/vaadin/ui/AbstractSplitPanel.java
+++ b/server/src/main/java/com/vaadin/ui/AbstractSplitPanel.java
diff --git a/server/src/com/vaadin/ui/AbstractTextField.java b/server/src/main/java/com/vaadin/ui/AbstractTextField.java
index 5fbe60937a..5fbe60937a 100644
--- a/server/src/com/vaadin/ui/AbstractTextField.java
+++ b/server/src/main/java/com/vaadin/ui/AbstractTextField.java
diff --git a/server/src/com/vaadin/ui/Accordion.java b/server/src/main/java/com/vaadin/ui/Accordion.java
index 1d53937d24..1d53937d24 100644
--- a/server/src/com/vaadin/ui/Accordion.java
+++ b/server/src/main/java/com/vaadin/ui/Accordion.java
diff --git a/server/src/com/vaadin/ui/Alignment.java b/server/src/main/java/com/vaadin/ui/Alignment.java
index 57131494ac..57131494ac 100644
--- a/server/src/com/vaadin/ui/Alignment.java
+++ b/server/src/main/java/com/vaadin/ui/Alignment.java
diff --git a/server/src/com/vaadin/ui/Audio.java b/server/src/main/java/com/vaadin/ui/Audio.java
index 8b9fad2196..8b9fad2196 100644
--- a/server/src/com/vaadin/ui/Audio.java
+++ b/server/src/main/java/com/vaadin/ui/Audio.java
diff --git a/server/src/com/vaadin/ui/BrowserFrame.java b/server/src/main/java/com/vaadin/ui/BrowserFrame.java
index 5717941ac5..5717941ac5 100644
--- a/server/src/com/vaadin/ui/BrowserFrame.java
+++ b/server/src/main/java/com/vaadin/ui/BrowserFrame.java
diff --git a/server/src/com/vaadin/ui/Button.java b/server/src/main/java/com/vaadin/ui/Button.java
index 677e8cac7d..677e8cac7d 100644
--- a/server/src/com/vaadin/ui/Button.java
+++ b/server/src/main/java/com/vaadin/ui/Button.java
diff --git a/server/src/com/vaadin/ui/Calendar.java b/server/src/main/java/com/vaadin/ui/Calendar.java
index 028a094cb5..028a094cb5 100644
--- a/server/src/com/vaadin/ui/Calendar.java
+++ b/server/src/main/java/com/vaadin/ui/Calendar.java
diff --git a/server/src/com/vaadin/ui/CheckBox.java b/server/src/main/java/com/vaadin/ui/CheckBox.java
index 8b31edcbb4..8b31edcbb4 100644
--- a/server/src/com/vaadin/ui/CheckBox.java
+++ b/server/src/main/java/com/vaadin/ui/CheckBox.java
diff --git a/server/src/com/vaadin/ui/ColorPicker.java b/server/src/main/java/com/vaadin/ui/ColorPicker.java
index 9e46c4e718..9e46c4e718 100644
--- a/server/src/com/vaadin/ui/ColorPicker.java
+++ b/server/src/main/java/com/vaadin/ui/ColorPicker.java
diff --git a/server/src/com/vaadin/ui/ColorPickerArea.java b/server/src/main/java/com/vaadin/ui/ColorPickerArea.java
index 94f64cf256..94f64cf256 100644
--- a/server/src/com/vaadin/ui/ColorPickerArea.java
+++ b/server/src/main/java/com/vaadin/ui/ColorPickerArea.java
diff --git a/server/src/com/vaadin/ui/ComboBox.java b/server/src/main/java/com/vaadin/ui/ComboBox.java
index b632cb0d8d..b632cb0d8d 100644
--- a/server/src/com/vaadin/ui/ComboBox.java
+++ b/server/src/main/java/com/vaadin/ui/ComboBox.java
diff --git a/server/src/com/vaadin/ui/Component.java b/server/src/main/java/com/vaadin/ui/Component.java
index 5db48806c3..5db48806c3 100644
--- a/server/src/com/vaadin/ui/Component.java
+++ b/server/src/main/java/com/vaadin/ui/Component.java
diff --git a/server/src/com/vaadin/ui/ComponentContainer.java b/server/src/main/java/com/vaadin/ui/ComponentContainer.java
index 2d5b4ffa9a..2d5b4ffa9a 100644
--- a/server/src/com/vaadin/ui/ComponentContainer.java
+++ b/server/src/main/java/com/vaadin/ui/ComponentContainer.java
diff --git a/server/src/com/vaadin/ui/ConnectorTracker.java b/server/src/main/java/com/vaadin/ui/ConnectorTracker.java
index 159bd09c0d..159bd09c0d 100644
--- a/server/src/com/vaadin/ui/ConnectorTracker.java
+++ b/server/src/main/java/com/vaadin/ui/ConnectorTracker.java
diff --git a/server/src/com/vaadin/ui/CssLayout.java b/server/src/main/java/com/vaadin/ui/CssLayout.java
index dbedfa53ff..dbedfa53ff 100644
--- a/server/src/com/vaadin/ui/CssLayout.java
+++ b/server/src/main/java/com/vaadin/ui/CssLayout.java
diff --git a/server/src/com/vaadin/ui/CustomComponent.java b/server/src/main/java/com/vaadin/ui/CustomComponent.java
index 55f9d7db03..55f9d7db03 100644
--- a/server/src/com/vaadin/ui/CustomComponent.java
+++ b/server/src/main/java/com/vaadin/ui/CustomComponent.java
diff --git a/server/src/com/vaadin/ui/CustomField.java b/server/src/main/java/com/vaadin/ui/CustomField.java
index 12f00ac23f..12f00ac23f 100644
--- a/server/src/com/vaadin/ui/CustomField.java
+++ b/server/src/main/java/com/vaadin/ui/CustomField.java
diff --git a/server/src/com/vaadin/ui/CustomLayout.java b/server/src/main/java/com/vaadin/ui/CustomLayout.java
index d64f70e95e..d64f70e95e 100644
--- a/server/src/com/vaadin/ui/CustomLayout.java
+++ b/server/src/main/java/com/vaadin/ui/CustomLayout.java
diff --git a/server/src/com/vaadin/ui/DateField.java b/server/src/main/java/com/vaadin/ui/DateField.java
index 052539cd28..052539cd28 100644
--- a/server/src/com/vaadin/ui/DateField.java
+++ b/server/src/main/java/com/vaadin/ui/DateField.java
diff --git a/server/src/com/vaadin/ui/DefaultFieldFactory.java b/server/src/main/java/com/vaadin/ui/DefaultFieldFactory.java
index 535943bcd5..535943bcd5 100644
--- a/server/src/com/vaadin/ui/DefaultFieldFactory.java
+++ b/server/src/main/java/com/vaadin/ui/DefaultFieldFactory.java
diff --git a/server/src/com/vaadin/ui/DragAndDropWrapper.java b/server/src/main/java/com/vaadin/ui/DragAndDropWrapper.java
index 90b3b56ef6..90b3b56ef6 100644
--- a/server/src/com/vaadin/ui/DragAndDropWrapper.java
+++ b/server/src/main/java/com/vaadin/ui/DragAndDropWrapper.java
diff --git a/server/src/com/vaadin/ui/Embedded.java b/server/src/main/java/com/vaadin/ui/Embedded.java
index d83eef9c4d..d83eef9c4d 100644
--- a/server/src/com/vaadin/ui/Embedded.java
+++ b/server/src/main/java/com/vaadin/ui/Embedded.java
diff --git a/server/src/com/vaadin/ui/Field.java b/server/src/main/java/com/vaadin/ui/Field.java
index 8a9acd570f..8a9acd570f 100644
--- a/server/src/com/vaadin/ui/Field.java
+++ b/server/src/main/java/com/vaadin/ui/Field.java
diff --git a/server/src/com/vaadin/ui/Flash.java b/server/src/main/java/com/vaadin/ui/Flash.java
index 6e99d2fe35..6e99d2fe35 100644
--- a/server/src/com/vaadin/ui/Flash.java
+++ b/server/src/main/java/com/vaadin/ui/Flash.java
diff --git a/server/src/com/vaadin/ui/Form.java b/server/src/main/java/com/vaadin/ui/Form.java
index 45532756e5..45532756e5 100644
--- a/server/src/com/vaadin/ui/Form.java
+++ b/server/src/main/java/com/vaadin/ui/Form.java
diff --git a/server/src/com/vaadin/ui/FormFieldFactory.java b/server/src/main/java/com/vaadin/ui/FormFieldFactory.java
index 124e0fcb9a..124e0fcb9a 100644
--- a/server/src/com/vaadin/ui/FormFieldFactory.java
+++ b/server/src/main/java/com/vaadin/ui/FormFieldFactory.java
diff --git a/server/src/com/vaadin/ui/FormLayout.java b/server/src/main/java/com/vaadin/ui/FormLayout.java
index f6f711d658..f6f711d658 100644
--- a/server/src/com/vaadin/ui/FormLayout.java
+++ b/server/src/main/java/com/vaadin/ui/FormLayout.java
diff --git a/server/src/com/vaadin/ui/Grid.java b/server/src/main/java/com/vaadin/ui/Grid.java
index 4074672675..4074672675 100644
--- a/server/src/com/vaadin/ui/Grid.java
+++ b/server/src/main/java/com/vaadin/ui/Grid.java
diff --git a/server/src/com/vaadin/ui/GridLayout.java b/server/src/main/java/com/vaadin/ui/GridLayout.java
index 8517962e91..8517962e91 100644
--- a/server/src/com/vaadin/ui/GridLayout.java
+++ b/server/src/main/java/com/vaadin/ui/GridLayout.java
diff --git a/server/src/com/vaadin/ui/HasChildMeasurementHint.java b/server/src/main/java/com/vaadin/ui/HasChildMeasurementHint.java
index 86d33f57b2..86d33f57b2 100644
--- a/server/src/com/vaadin/ui/HasChildMeasurementHint.java
+++ b/server/src/main/java/com/vaadin/ui/HasChildMeasurementHint.java
diff --git a/server/src/com/vaadin/ui/HasComponents.java b/server/src/main/java/com/vaadin/ui/HasComponents.java
index 6273e8053b..6273e8053b 100644
--- a/server/src/com/vaadin/ui/HasComponents.java
+++ b/server/src/main/java/com/vaadin/ui/HasComponents.java
diff --git a/server/src/com/vaadin/ui/HorizontalLayout.java b/server/src/main/java/com/vaadin/ui/HorizontalLayout.java
index 616fa09225..616fa09225 100644
--- a/server/src/com/vaadin/ui/HorizontalLayout.java
+++ b/server/src/main/java/com/vaadin/ui/HorizontalLayout.java
diff --git a/server/src/com/vaadin/ui/HorizontalSplitPanel.java b/server/src/main/java/com/vaadin/ui/HorizontalSplitPanel.java
index 922986eeda..922986eeda 100644
--- a/server/src/com/vaadin/ui/HorizontalSplitPanel.java
+++ b/server/src/main/java/com/vaadin/ui/HorizontalSplitPanel.java
diff --git a/server/src/com/vaadin/ui/Html5File.java b/server/src/main/java/com/vaadin/ui/Html5File.java
index 87ea83c8c9..87ea83c8c9 100644
--- a/server/src/com/vaadin/ui/Html5File.java
+++ b/server/src/main/java/com/vaadin/ui/Html5File.java
diff --git a/server/src/com/vaadin/ui/Image.java b/server/src/main/java/com/vaadin/ui/Image.java
index 7b0294a450..7b0294a450 100644
--- a/server/src/com/vaadin/ui/Image.java
+++ b/server/src/main/java/com/vaadin/ui/Image.java
diff --git a/server/src/com/vaadin/ui/InlineDateField.java b/server/src/main/java/com/vaadin/ui/InlineDateField.java
index e6f0f5d7a0..e6f0f5d7a0 100644
--- a/server/src/com/vaadin/ui/InlineDateField.java
+++ b/server/src/main/java/com/vaadin/ui/InlineDateField.java
diff --git a/server/src/com/vaadin/ui/JavaScript.java b/server/src/main/java/com/vaadin/ui/JavaScript.java
index 668ae67056..668ae67056 100644
--- a/server/src/com/vaadin/ui/JavaScript.java
+++ b/server/src/main/java/com/vaadin/ui/JavaScript.java
diff --git a/server/src/com/vaadin/ui/JavaScriptFunction.java b/server/src/main/java/com/vaadin/ui/JavaScriptFunction.java
index 071c88350b..071c88350b 100644
--- a/server/src/com/vaadin/ui/JavaScriptFunction.java
+++ b/server/src/main/java/com/vaadin/ui/JavaScriptFunction.java
diff --git a/server/src/com/vaadin/ui/Label.java b/server/src/main/java/com/vaadin/ui/Label.java
index 1498246ec5..1498246ec5 100644
--- a/server/src/com/vaadin/ui/Label.java
+++ b/server/src/main/java/com/vaadin/ui/Label.java
diff --git a/server/src/com/vaadin/ui/Layout.java b/server/src/main/java/com/vaadin/ui/Layout.java
index 6cf2cec249..6cf2cec249 100644
--- a/server/src/com/vaadin/ui/Layout.java
+++ b/server/src/main/java/com/vaadin/ui/Layout.java
diff --git a/server/src/com/vaadin/ui/LegacyComponent.java b/server/src/main/java/com/vaadin/ui/LegacyComponent.java
index 7f71162c94..7f71162c94 100644
--- a/server/src/com/vaadin/ui/LegacyComponent.java
+++ b/server/src/main/java/com/vaadin/ui/LegacyComponent.java
diff --git a/server/src/com/vaadin/ui/LegacyWindow.java b/server/src/main/java/com/vaadin/ui/LegacyWindow.java
index fe71d14430..fe71d14430 100644
--- a/server/src/com/vaadin/ui/LegacyWindow.java
+++ b/server/src/main/java/com/vaadin/ui/LegacyWindow.java
diff --git a/server/src/com/vaadin/ui/Link.java b/server/src/main/java/com/vaadin/ui/Link.java
index c100336180..c100336180 100644
--- a/server/src/com/vaadin/ui/Link.java
+++ b/server/src/main/java/com/vaadin/ui/Link.java
diff --git a/server/src/com/vaadin/ui/ListSelect.java b/server/src/main/java/com/vaadin/ui/ListSelect.java
index 9f44407db9..9f44407db9 100644
--- a/server/src/com/vaadin/ui/ListSelect.java
+++ b/server/src/main/java/com/vaadin/ui/ListSelect.java
diff --git a/server/src/com/vaadin/ui/LoadingIndicatorConfiguration.java b/server/src/main/java/com/vaadin/ui/LoadingIndicatorConfiguration.java
index 46fe7ead35..46fe7ead35 100644
--- a/server/src/com/vaadin/ui/LoadingIndicatorConfiguration.java
+++ b/server/src/main/java/com/vaadin/ui/LoadingIndicatorConfiguration.java
diff --git a/server/src/com/vaadin/ui/LoginForm.java b/server/src/main/java/com/vaadin/ui/LoginForm.java
index 1f0e3fc3b3..1f0e3fc3b3 100644
--- a/server/src/com/vaadin/ui/LoginForm.java
+++ b/server/src/main/java/com/vaadin/ui/LoginForm.java
diff --git a/server/src/com/vaadin/ui/MenuBar.java b/server/src/main/java/com/vaadin/ui/MenuBar.java
index 9f05df7869..9f05df7869 100644
--- a/server/src/com/vaadin/ui/MenuBar.java
+++ b/server/src/main/java/com/vaadin/ui/MenuBar.java
diff --git a/server/src/com/vaadin/ui/NativeButton.java b/server/src/main/java/com/vaadin/ui/NativeButton.java
index 3c220719b5..3c220719b5 100644
--- a/server/src/com/vaadin/ui/NativeButton.java
+++ b/server/src/main/java/com/vaadin/ui/NativeButton.java
diff --git a/server/src/com/vaadin/ui/NativeSelect.java b/server/src/main/java/com/vaadin/ui/NativeSelect.java
index 137d57f677..137d57f677 100644
--- a/server/src/com/vaadin/ui/NativeSelect.java
+++ b/server/src/main/java/com/vaadin/ui/NativeSelect.java
diff --git a/server/src/com/vaadin/ui/Notification.java b/server/src/main/java/com/vaadin/ui/Notification.java
index aaf25a9e9d..aaf25a9e9d 100644
--- a/server/src/com/vaadin/ui/Notification.java
+++ b/server/src/main/java/com/vaadin/ui/Notification.java
diff --git a/server/src/com/vaadin/ui/NotificationConfiguration.java b/server/src/main/java/com/vaadin/ui/NotificationConfiguration.java
index 925c888a51..925c888a51 100644
--- a/server/src/com/vaadin/ui/NotificationConfiguration.java
+++ b/server/src/main/java/com/vaadin/ui/NotificationConfiguration.java
diff --git a/server/src/com/vaadin/ui/OptionGroup.java b/server/src/main/java/com/vaadin/ui/OptionGroup.java
index 81e81c9a3a..81e81c9a3a 100644
--- a/server/src/com/vaadin/ui/OptionGroup.java
+++ b/server/src/main/java/com/vaadin/ui/OptionGroup.java
diff --git a/server/src/com/vaadin/ui/Panel.java b/server/src/main/java/com/vaadin/ui/Panel.java
index 6458d5f57d..6458d5f57d 100644
--- a/server/src/com/vaadin/ui/Panel.java
+++ b/server/src/main/java/com/vaadin/ui/Panel.java
diff --git a/server/src/com/vaadin/ui/PasswordField.java b/server/src/main/java/com/vaadin/ui/PasswordField.java
index 385649c318..385649c318 100644
--- a/server/src/com/vaadin/ui/PasswordField.java
+++ b/server/src/main/java/com/vaadin/ui/PasswordField.java
diff --git a/server/src/com/vaadin/ui/PopupDateField.java b/server/src/main/java/com/vaadin/ui/PopupDateField.java
index f07ac84160..f07ac84160 100644
--- a/server/src/com/vaadin/ui/PopupDateField.java
+++ b/server/src/main/java/com/vaadin/ui/PopupDateField.java
diff --git a/server/src/com/vaadin/ui/PopupView.java b/server/src/main/java/com/vaadin/ui/PopupView.java
index 73c93b29f3..73c93b29f3 100644
--- a/server/src/com/vaadin/ui/PopupView.java
+++ b/server/src/main/java/com/vaadin/ui/PopupView.java
diff --git a/server/src/com/vaadin/ui/ProgressBar.java b/server/src/main/java/com/vaadin/ui/ProgressBar.java
index d38067d51e..d38067d51e 100644
--- a/server/src/com/vaadin/ui/ProgressBar.java
+++ b/server/src/main/java/com/vaadin/ui/ProgressBar.java
diff --git a/server/src/com/vaadin/ui/ProgressIndicator.java b/server/src/main/java/com/vaadin/ui/ProgressIndicator.java
index 6e436169e3..6e436169e3 100644
--- a/server/src/com/vaadin/ui/ProgressIndicator.java
+++ b/server/src/main/java/com/vaadin/ui/ProgressIndicator.java
diff --git a/server/src/com/vaadin/ui/PushConfiguration.java b/server/src/main/java/com/vaadin/ui/PushConfiguration.java
index 6ef323cea8..6ef323cea8 100644
--- a/server/src/com/vaadin/ui/PushConfiguration.java
+++ b/server/src/main/java/com/vaadin/ui/PushConfiguration.java
diff --git a/server/src/com/vaadin/ui/ReconnectDialogConfiguration.java b/server/src/main/java/com/vaadin/ui/ReconnectDialogConfiguration.java
index 92eb1e785f..92eb1e785f 100644
--- a/server/src/com/vaadin/ui/ReconnectDialogConfiguration.java
+++ b/server/src/main/java/com/vaadin/ui/ReconnectDialogConfiguration.java
diff --git a/server/src/com/vaadin/ui/RichTextArea.java b/server/src/main/java/com/vaadin/ui/RichTextArea.java
index 2f0ba215b9..2f0ba215b9 100644
--- a/server/src/com/vaadin/ui/RichTextArea.java
+++ b/server/src/main/java/com/vaadin/ui/RichTextArea.java
diff --git a/server/src/com/vaadin/ui/Select.java b/server/src/main/java/com/vaadin/ui/Select.java
index e63cba3eaa..e63cba3eaa 100644
--- a/server/src/com/vaadin/ui/Select.java
+++ b/server/src/main/java/com/vaadin/ui/Select.java
diff --git a/server/src/com/vaadin/ui/SelectiveRenderer.java b/server/src/main/java/com/vaadin/ui/SelectiveRenderer.java
index 5c4d052a53..5c4d052a53 100644
--- a/server/src/com/vaadin/ui/SelectiveRenderer.java
+++ b/server/src/main/java/com/vaadin/ui/SelectiveRenderer.java
diff --git a/server/src/com/vaadin/ui/SingleComponentContainer.java b/server/src/main/java/com/vaadin/ui/SingleComponentContainer.java
index 9feee84f15..9feee84f15 100644
--- a/server/src/com/vaadin/ui/SingleComponentContainer.java
+++ b/server/src/main/java/com/vaadin/ui/SingleComponentContainer.java
diff --git a/server/src/com/vaadin/ui/Slider.java b/server/src/main/java/com/vaadin/ui/Slider.java
index 1fd6d425fe..1fd6d425fe 100644
--- a/server/src/com/vaadin/ui/Slider.java
+++ b/server/src/main/java/com/vaadin/ui/Slider.java
diff --git a/server/src/com/vaadin/ui/TabSheet.java b/server/src/main/java/com/vaadin/ui/TabSheet.java
index 66784aaa02..66784aaa02 100644
--- a/server/src/com/vaadin/ui/TabSheet.java
+++ b/server/src/main/java/com/vaadin/ui/TabSheet.java
diff --git a/server/src/com/vaadin/ui/Table.java b/server/src/main/java/com/vaadin/ui/Table.java
index b303fddd81..b303fddd81 100644
--- a/server/src/com/vaadin/ui/Table.java
+++ b/server/src/main/java/com/vaadin/ui/Table.java
diff --git a/server/src/com/vaadin/ui/TableFieldFactory.java b/server/src/main/java/com/vaadin/ui/TableFieldFactory.java
index 3c946dcec2..3c946dcec2 100644
--- a/server/src/com/vaadin/ui/TableFieldFactory.java
+++ b/server/src/main/java/com/vaadin/ui/TableFieldFactory.java
diff --git a/server/src/com/vaadin/ui/TextArea.java b/server/src/main/java/com/vaadin/ui/TextArea.java
index d66fbf0668..d66fbf0668 100644
--- a/server/src/com/vaadin/ui/TextArea.java
+++ b/server/src/main/java/com/vaadin/ui/TextArea.java
diff --git a/server/src/com/vaadin/ui/TextField.java b/server/src/main/java/com/vaadin/ui/TextField.java
index 8772f95f3d..8772f95f3d 100644
--- a/server/src/com/vaadin/ui/TextField.java
+++ b/server/src/main/java/com/vaadin/ui/TextField.java
diff --git a/server/src/com/vaadin/ui/TooltipConfiguration.java b/server/src/main/java/com/vaadin/ui/TooltipConfiguration.java
index ecb8ac7534..ecb8ac7534 100644
--- a/server/src/com/vaadin/ui/TooltipConfiguration.java
+++ b/server/src/main/java/com/vaadin/ui/TooltipConfiguration.java
diff --git a/server/src/com/vaadin/ui/Tree.java b/server/src/main/java/com/vaadin/ui/Tree.java
index 5e6ac55027..5e6ac55027 100644
--- a/server/src/com/vaadin/ui/Tree.java
+++ b/server/src/main/java/com/vaadin/ui/Tree.java
diff --git a/server/src/com/vaadin/ui/TreeTable.java b/server/src/main/java/com/vaadin/ui/TreeTable.java
index bf38148aa9..bf38148aa9 100644
--- a/server/src/com/vaadin/ui/TreeTable.java
+++ b/server/src/main/java/com/vaadin/ui/TreeTable.java
diff --git a/server/src/com/vaadin/ui/TwinColSelect.java b/server/src/main/java/com/vaadin/ui/TwinColSelect.java
index 8086220c94..8086220c94 100644
--- a/server/src/com/vaadin/ui/TwinColSelect.java
+++ b/server/src/main/java/com/vaadin/ui/TwinColSelect.java
diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/main/java/com/vaadin/ui/UI.java
index c429b64491..c429b64491 100644
--- a/server/src/com/vaadin/ui/UI.java
+++ b/server/src/main/java/com/vaadin/ui/UI.java
diff --git a/server/src/com/vaadin/ui/UIDetachedException.java b/server/src/main/java/com/vaadin/ui/UIDetachedException.java
index 7cd7f0889e..7cd7f0889e 100644
--- a/server/src/com/vaadin/ui/UIDetachedException.java
+++ b/server/src/main/java/com/vaadin/ui/UIDetachedException.java
diff --git a/server/src/com/vaadin/ui/UniqueSerializable.java b/server/src/main/java/com/vaadin/ui/UniqueSerializable.java
index f5d68e8a71..f5d68e8a71 100644
--- a/server/src/com/vaadin/ui/UniqueSerializable.java
+++ b/server/src/main/java/com/vaadin/ui/UniqueSerializable.java
diff --git a/server/src/com/vaadin/ui/Upload.java b/server/src/main/java/com/vaadin/ui/Upload.java
index a61bcf1bd9..a61bcf1bd9 100644
--- a/server/src/com/vaadin/ui/Upload.java
+++ b/server/src/main/java/com/vaadin/ui/Upload.java
diff --git a/server/src/com/vaadin/ui/VerticalLayout.java b/server/src/main/java/com/vaadin/ui/VerticalLayout.java
index 7002fbc7e6..7002fbc7e6 100644
--- a/server/src/com/vaadin/ui/VerticalLayout.java
+++ b/server/src/main/java/com/vaadin/ui/VerticalLayout.java
diff --git a/server/src/com/vaadin/ui/VerticalSplitPanel.java b/server/src/main/java/com/vaadin/ui/VerticalSplitPanel.java
index e5e6eb60e1..e5e6eb60e1 100644
--- a/server/src/com/vaadin/ui/VerticalSplitPanel.java
+++ b/server/src/main/java/com/vaadin/ui/VerticalSplitPanel.java
diff --git a/server/src/com/vaadin/ui/Video.java b/server/src/main/java/com/vaadin/ui/Video.java
index 46a4293b36..46a4293b36 100644
--- a/server/src/com/vaadin/ui/Video.java
+++ b/server/src/main/java/com/vaadin/ui/Video.java
diff --git a/server/src/com/vaadin/ui/Window.java b/server/src/main/java/com/vaadin/ui/Window.java
index b5cd384f53..b5cd384f53 100644
--- a/server/src/com/vaadin/ui/Window.java
+++ b/server/src/main/java/com/vaadin/ui/Window.java
diff --git a/server/src/com/vaadin/ui/components/calendar/CalendarComponentEvent.java b/server/src/main/java/com/vaadin/ui/components/calendar/CalendarComponentEvent.java
index dfb59e148b..dfb59e148b 100644
--- a/server/src/com/vaadin/ui/components/calendar/CalendarComponentEvent.java
+++ b/server/src/main/java/com/vaadin/ui/components/calendar/CalendarComponentEvent.java
diff --git a/server/src/com/vaadin/ui/components/calendar/CalendarComponentEvents.java b/server/src/main/java/com/vaadin/ui/components/calendar/CalendarComponentEvents.java
index f01b465dd2..f01b465dd2 100644
--- a/server/src/com/vaadin/ui/components/calendar/CalendarComponentEvents.java
+++ b/server/src/main/java/com/vaadin/ui/components/calendar/CalendarComponentEvents.java
diff --git a/server/src/com/vaadin/ui/components/calendar/CalendarDateRange.java b/server/src/main/java/com/vaadin/ui/components/calendar/CalendarDateRange.java
index 18b98e1f6c..18b98e1f6c 100644
--- a/server/src/com/vaadin/ui/components/calendar/CalendarDateRange.java
+++ b/server/src/main/java/com/vaadin/ui/components/calendar/CalendarDateRange.java
diff --git a/server/src/com/vaadin/ui/components/calendar/CalendarTargetDetails.java b/server/src/main/java/com/vaadin/ui/components/calendar/CalendarTargetDetails.java
index 3ea6c4d8f4..3ea6c4d8f4 100644
--- a/server/src/com/vaadin/ui/components/calendar/CalendarTargetDetails.java
+++ b/server/src/main/java/com/vaadin/ui/components/calendar/CalendarTargetDetails.java
diff --git a/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java b/server/src/main/java/com/vaadin/ui/components/calendar/ContainerEventProvider.java
index 2f51b21f7c..2f51b21f7c 100644
--- a/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java
+++ b/server/src/main/java/com/vaadin/ui/components/calendar/ContainerEventProvider.java
diff --git a/server/src/com/vaadin/ui/components/calendar/event/BasicEvent.java b/server/src/main/java/com/vaadin/ui/components/calendar/event/BasicEvent.java
index a1ccad2712..a1ccad2712 100644
--- a/server/src/com/vaadin/ui/components/calendar/event/BasicEvent.java
+++ b/server/src/main/java/com/vaadin/ui/components/calendar/event/BasicEvent.java
diff --git a/server/src/com/vaadin/ui/components/calendar/event/BasicEventProvider.java b/server/src/main/java/com/vaadin/ui/components/calendar/event/BasicEventProvider.java
index 9fa6baadad..9fa6baadad 100644
--- a/server/src/com/vaadin/ui/components/calendar/event/BasicEventProvider.java
+++ b/server/src/main/java/com/vaadin/ui/components/calendar/event/BasicEventProvider.java
diff --git a/server/src/com/vaadin/ui/components/calendar/event/CalendarEditableEventProvider.java b/server/src/main/java/com/vaadin/ui/components/calendar/event/CalendarEditableEventProvider.java
index 920600368e..920600368e 100644
--- a/server/src/com/vaadin/ui/components/calendar/event/CalendarEditableEventProvider.java
+++ b/server/src/main/java/com/vaadin/ui/components/calendar/event/CalendarEditableEventProvider.java
diff --git a/server/src/com/vaadin/ui/components/calendar/event/CalendarEvent.java b/server/src/main/java/com/vaadin/ui/components/calendar/event/CalendarEvent.java
index 2ad8c777ff..2ad8c777ff 100644
--- a/server/src/com/vaadin/ui/components/calendar/event/CalendarEvent.java
+++ b/server/src/main/java/com/vaadin/ui/components/calendar/event/CalendarEvent.java
diff --git a/server/src/com/vaadin/ui/components/calendar/event/CalendarEventProvider.java b/server/src/main/java/com/vaadin/ui/components/calendar/event/CalendarEventProvider.java
index 2a8ec7e834..2a8ec7e834 100644
--- a/server/src/com/vaadin/ui/components/calendar/event/CalendarEventProvider.java
+++ b/server/src/main/java/com/vaadin/ui/components/calendar/event/CalendarEventProvider.java
diff --git a/server/src/com/vaadin/ui/components/calendar/event/EditableCalendarEvent.java b/server/src/main/java/com/vaadin/ui/components/calendar/event/EditableCalendarEvent.java
index df708697b8..df708697b8 100644
--- a/server/src/com/vaadin/ui/components/calendar/event/EditableCalendarEvent.java
+++ b/server/src/main/java/com/vaadin/ui/components/calendar/event/EditableCalendarEvent.java
diff --git a/server/src/com/vaadin/ui/components/calendar/handler/BasicBackwardHandler.java b/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicBackwardHandler.java
index 0e99b26856..0e99b26856 100644
--- a/server/src/com/vaadin/ui/components/calendar/handler/BasicBackwardHandler.java
+++ b/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicBackwardHandler.java
diff --git a/server/src/com/vaadin/ui/components/calendar/handler/BasicDateClickHandler.java b/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicDateClickHandler.java
index 8d366ed52f..8d366ed52f 100644
--- a/server/src/com/vaadin/ui/components/calendar/handler/BasicDateClickHandler.java
+++ b/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicDateClickHandler.java
diff --git a/server/src/com/vaadin/ui/components/calendar/handler/BasicEventMoveHandler.java b/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicEventMoveHandler.java
index 418e03d24a..418e03d24a 100644
--- a/server/src/com/vaadin/ui/components/calendar/handler/BasicEventMoveHandler.java
+++ b/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicEventMoveHandler.java
diff --git a/server/src/com/vaadin/ui/components/calendar/handler/BasicEventResizeHandler.java b/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicEventResizeHandler.java
index 6141c84c5b..6141c84c5b 100644
--- a/server/src/com/vaadin/ui/components/calendar/handler/BasicEventResizeHandler.java
+++ b/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicEventResizeHandler.java
diff --git a/server/src/com/vaadin/ui/components/calendar/handler/BasicForwardHandler.java b/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicForwardHandler.java
index 45b44cb673..45b44cb673 100644
--- a/server/src/com/vaadin/ui/components/calendar/handler/BasicForwardHandler.java
+++ b/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicForwardHandler.java
diff --git a/server/src/com/vaadin/ui/components/calendar/handler/BasicWeekClickHandler.java b/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicWeekClickHandler.java
index c52d0a5a82..c52d0a5a82 100644
--- a/server/src/com/vaadin/ui/components/calendar/handler/BasicWeekClickHandler.java
+++ b/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicWeekClickHandler.java
diff --git a/server/src/com/vaadin/ui/components/colorpicker/ColorChangeEvent.java b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorChangeEvent.java
index b55b55357f..b55b55357f 100644
--- a/server/src/com/vaadin/ui/components/colorpicker/ColorChangeEvent.java
+++ b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorChangeEvent.java
diff --git a/server/src/com/vaadin/ui/components/colorpicker/ColorChangeListener.java b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorChangeListener.java
index 6db148989c..6db148989c 100644
--- a/server/src/com/vaadin/ui/components/colorpicker/ColorChangeListener.java
+++ b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorChangeListener.java
diff --git a/server/src/com/vaadin/ui/components/colorpicker/ColorPickerGradient.java b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerGradient.java
index 81b178e4f0..81b178e4f0 100644
--- a/server/src/com/vaadin/ui/components/colorpicker/ColorPickerGradient.java
+++ b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerGradient.java
diff --git a/server/src/com/vaadin/ui/components/colorpicker/ColorPickerGrid.java b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerGrid.java
index 002f36d99d..002f36d99d 100644
--- a/server/src/com/vaadin/ui/components/colorpicker/ColorPickerGrid.java
+++ b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerGrid.java
diff --git a/server/src/com/vaadin/ui/components/colorpicker/ColorPickerHistory.java b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerHistory.java
index a3297a282c..a3297a282c 100644
--- a/server/src/com/vaadin/ui/components/colorpicker/ColorPickerHistory.java
+++ b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerHistory.java
diff --git a/server/src/com/vaadin/ui/components/colorpicker/ColorPickerPopup.java b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerPopup.java
index 86ac0111ad..86ac0111ad 100644
--- a/server/src/com/vaadin/ui/components/colorpicker/ColorPickerPopup.java
+++ b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerPopup.java
diff --git a/server/src/com/vaadin/ui/components/colorpicker/ColorPickerPreview.java b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerPreview.java
index 21a3630de2..21a3630de2 100644
--- a/server/src/com/vaadin/ui/components/colorpicker/ColorPickerPreview.java
+++ b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerPreview.java
diff --git a/server/src/com/vaadin/ui/components/colorpicker/ColorPickerSelect.java b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerSelect.java
index 8e441b25ee..8e441b25ee 100644
--- a/server/src/com/vaadin/ui/components/colorpicker/ColorPickerSelect.java
+++ b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerSelect.java
diff --git a/server/src/com/vaadin/ui/components/colorpicker/ColorSelector.java b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorSelector.java
index c282c22f62..c282c22f62 100644
--- a/server/src/com/vaadin/ui/components/colorpicker/ColorSelector.java
+++ b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorSelector.java
diff --git a/server/src/com/vaadin/ui/components/colorpicker/HasColorChangeListener.java b/server/src/main/java/com/vaadin/ui/components/colorpicker/HasColorChangeListener.java
index eb16d8cbbe..eb16d8cbbe 100644
--- a/server/src/com/vaadin/ui/components/colorpicker/HasColorChangeListener.java
+++ b/server/src/main/java/com/vaadin/ui/components/colorpicker/HasColorChangeListener.java
diff --git a/server/src/com/vaadin/ui/declarative/Design.java b/server/src/main/java/com/vaadin/ui/declarative/Design.java
index 5ce1f5dc60..5ce1f5dc60 100644
--- a/server/src/com/vaadin/ui/declarative/Design.java
+++ b/server/src/main/java/com/vaadin/ui/declarative/Design.java
diff --git a/server/src/com/vaadin/ui/declarative/DesignAttributeHandler.java b/server/src/main/java/com/vaadin/ui/declarative/DesignAttributeHandler.java
index cee2ebe381..cee2ebe381 100644
--- a/server/src/com/vaadin/ui/declarative/DesignAttributeHandler.java
+++ b/server/src/main/java/com/vaadin/ui/declarative/DesignAttributeHandler.java
diff --git a/server/src/com/vaadin/ui/declarative/DesignContext.java b/server/src/main/java/com/vaadin/ui/declarative/DesignContext.java
index d72ec77d4a..d72ec77d4a 100644
--- a/server/src/com/vaadin/ui/declarative/DesignContext.java
+++ b/server/src/main/java/com/vaadin/ui/declarative/DesignContext.java
diff --git a/server/src/com/vaadin/ui/declarative/DesignException.java b/server/src/main/java/com/vaadin/ui/declarative/DesignException.java
index 01482f84b0..01482f84b0 100644
--- a/server/src/com/vaadin/ui/declarative/DesignException.java
+++ b/server/src/main/java/com/vaadin/ui/declarative/DesignException.java
diff --git a/server/src/com/vaadin/ui/declarative/DesignFormatter.java b/server/src/main/java/com/vaadin/ui/declarative/DesignFormatter.java
index 509015130d..509015130d 100644
--- a/server/src/com/vaadin/ui/declarative/DesignFormatter.java
+++ b/server/src/main/java/com/vaadin/ui/declarative/DesignFormatter.java
diff --git a/server/src/com/vaadin/ui/declarative/FieldBinder.java b/server/src/main/java/com/vaadin/ui/declarative/FieldBinder.java
index 3766458175..3766458175 100644
--- a/server/src/com/vaadin/ui/declarative/FieldBinder.java
+++ b/server/src/main/java/com/vaadin/ui/declarative/FieldBinder.java
diff --git a/server/src/com/vaadin/ui/declarative/FieldBindingException.java b/server/src/main/java/com/vaadin/ui/declarative/FieldBindingException.java
index d8b587a14c..d8b587a14c 100644
--- a/server/src/com/vaadin/ui/declarative/FieldBindingException.java
+++ b/server/src/main/java/com/vaadin/ui/declarative/FieldBindingException.java
diff --git a/server/src/com/vaadin/ui/declarative/ShouldWriteDataDelegate.java b/server/src/main/java/com/vaadin/ui/declarative/ShouldWriteDataDelegate.java
index 9cb1f1c605..9cb1f1c605 100644
--- a/server/src/com/vaadin/ui/declarative/ShouldWriteDataDelegate.java
+++ b/server/src/main/java/com/vaadin/ui/declarative/ShouldWriteDataDelegate.java
diff --git a/server/src/com/vaadin/ui/declarative/converters/DesignDateConverter.java b/server/src/main/java/com/vaadin/ui/declarative/converters/DesignDateConverter.java
index d2d63ad16e..d2d63ad16e 100644
--- a/server/src/com/vaadin/ui/declarative/converters/DesignDateConverter.java
+++ b/server/src/main/java/com/vaadin/ui/declarative/converters/DesignDateConverter.java
diff --git a/server/src/com/vaadin/ui/declarative/converters/DesignEnumConverter.java b/server/src/main/java/com/vaadin/ui/declarative/converters/DesignEnumConverter.java
index 9f07ff9560..9f07ff9560 100644
--- a/server/src/com/vaadin/ui/declarative/converters/DesignEnumConverter.java
+++ b/server/src/main/java/com/vaadin/ui/declarative/converters/DesignEnumConverter.java
diff --git a/server/src/com/vaadin/ui/declarative/converters/DesignObjectConverter.java b/server/src/main/java/com/vaadin/ui/declarative/converters/DesignObjectConverter.java
index f11585d6b8..f11585d6b8 100644
--- a/server/src/com/vaadin/ui/declarative/converters/DesignObjectConverter.java
+++ b/server/src/main/java/com/vaadin/ui/declarative/converters/DesignObjectConverter.java
diff --git a/server/src/com/vaadin/ui/declarative/converters/DesignResourceConverter.java b/server/src/main/java/com/vaadin/ui/declarative/converters/DesignResourceConverter.java
index ffa51fedd1..ffa51fedd1 100644
--- a/server/src/com/vaadin/ui/declarative/converters/DesignResourceConverter.java
+++ b/server/src/main/java/com/vaadin/ui/declarative/converters/DesignResourceConverter.java
diff --git a/server/src/com/vaadin/ui/declarative/converters/DesignShortcutActionConverter.java b/server/src/main/java/com/vaadin/ui/declarative/converters/DesignShortcutActionConverter.java
index d6f2f65938..d6f2f65938 100644
--- a/server/src/com/vaadin/ui/declarative/converters/DesignShortcutActionConverter.java
+++ b/server/src/main/java/com/vaadin/ui/declarative/converters/DesignShortcutActionConverter.java
diff --git a/server/src/com/vaadin/ui/declarative/converters/DesignTimeZoneConverter.java b/server/src/main/java/com/vaadin/ui/declarative/converters/DesignTimeZoneConverter.java
index 51f47edac9..51f47edac9 100644
--- a/server/src/com/vaadin/ui/declarative/converters/DesignTimeZoneConverter.java
+++ b/server/src/main/java/com/vaadin/ui/declarative/converters/DesignTimeZoneConverter.java
diff --git a/server/src/com/vaadin/ui/declarative/converters/DesignToStringConverter.java b/server/src/main/java/com/vaadin/ui/declarative/converters/DesignToStringConverter.java
index 0c6cf55bed..0c6cf55bed 100644
--- a/server/src/com/vaadin/ui/declarative/converters/DesignToStringConverter.java
+++ b/server/src/main/java/com/vaadin/ui/declarative/converters/DesignToStringConverter.java
diff --git a/server/src/com/vaadin/ui/declarative/converters/ShortcutKeyMapper.java b/server/src/main/java/com/vaadin/ui/declarative/converters/ShortcutKeyMapper.java
index 2940c82c06..2940c82c06 100644
--- a/server/src/com/vaadin/ui/declarative/converters/ShortcutKeyMapper.java
+++ b/server/src/main/java/com/vaadin/ui/declarative/converters/ShortcutKeyMapper.java
diff --git a/server/src/com/vaadin/ui/renderers/AbstractJavaScriptRenderer.java b/server/src/main/java/com/vaadin/ui/renderers/AbstractJavaScriptRenderer.java
index 91a5c0ea45..91a5c0ea45 100644
--- a/server/src/com/vaadin/ui/renderers/AbstractJavaScriptRenderer.java
+++ b/server/src/main/java/com/vaadin/ui/renderers/AbstractJavaScriptRenderer.java
diff --git a/server/src/com/vaadin/ui/renderers/ButtonRenderer.java b/server/src/main/java/com/vaadin/ui/renderers/ButtonRenderer.java
index e7e723ebd6..e7e723ebd6 100644
--- a/server/src/com/vaadin/ui/renderers/ButtonRenderer.java
+++ b/server/src/main/java/com/vaadin/ui/renderers/ButtonRenderer.java
diff --git a/server/src/com/vaadin/ui/renderers/ClickableRenderer.java b/server/src/main/java/com/vaadin/ui/renderers/ClickableRenderer.java
index 7210eb7840..7210eb7840 100644
--- a/server/src/com/vaadin/ui/renderers/ClickableRenderer.java
+++ b/server/src/main/java/com/vaadin/ui/renderers/ClickableRenderer.java
diff --git a/server/src/com/vaadin/ui/renderers/DateRenderer.java b/server/src/main/java/com/vaadin/ui/renderers/DateRenderer.java
index dddeb6cd77..dddeb6cd77 100644
--- a/server/src/com/vaadin/ui/renderers/DateRenderer.java
+++ b/server/src/main/java/com/vaadin/ui/renderers/DateRenderer.java
diff --git a/server/src/com/vaadin/ui/renderers/HtmlRenderer.java b/server/src/main/java/com/vaadin/ui/renderers/HtmlRenderer.java
index 2ec43800c0..2ec43800c0 100644
--- a/server/src/com/vaadin/ui/renderers/HtmlRenderer.java
+++ b/server/src/main/java/com/vaadin/ui/renderers/HtmlRenderer.java
diff --git a/server/src/com/vaadin/ui/renderers/ImageRenderer.java b/server/src/main/java/com/vaadin/ui/renderers/ImageRenderer.java
index ad7d5cae2b..ad7d5cae2b 100644
--- a/server/src/com/vaadin/ui/renderers/ImageRenderer.java
+++ b/server/src/main/java/com/vaadin/ui/renderers/ImageRenderer.java
diff --git a/server/src/com/vaadin/ui/renderers/NumberRenderer.java b/server/src/main/java/com/vaadin/ui/renderers/NumberRenderer.java
index b1ba309c9a..b1ba309c9a 100644
--- a/server/src/com/vaadin/ui/renderers/NumberRenderer.java
+++ b/server/src/main/java/com/vaadin/ui/renderers/NumberRenderer.java
diff --git a/server/src/com/vaadin/ui/renderers/ProgressBarRenderer.java b/server/src/main/java/com/vaadin/ui/renderers/ProgressBarRenderer.java
index 1566c47222..1566c47222 100644
--- a/server/src/com/vaadin/ui/renderers/ProgressBarRenderer.java
+++ b/server/src/main/java/com/vaadin/ui/renderers/ProgressBarRenderer.java
diff --git a/server/src/com/vaadin/ui/renderers/Renderer.java b/server/src/main/java/com/vaadin/ui/renderers/Renderer.java
index ac85174618..ac85174618 100644
--- a/server/src/com/vaadin/ui/renderers/Renderer.java
+++ b/server/src/main/java/com/vaadin/ui/renderers/Renderer.java
diff --git a/server/src/com/vaadin/ui/renderers/TextRenderer.java b/server/src/main/java/com/vaadin/ui/renderers/TextRenderer.java
index ce8a73d057..ce8a73d057 100644
--- a/server/src/com/vaadin/ui/renderers/TextRenderer.java
+++ b/server/src/main/java/com/vaadin/ui/renderers/TextRenderer.java
diff --git a/server/src/com/vaadin/ui/themes/BaseTheme.java b/server/src/main/java/com/vaadin/ui/themes/BaseTheme.java
index 9421cf2341..9421cf2341 100644
--- a/server/src/com/vaadin/ui/themes/BaseTheme.java
+++ b/server/src/main/java/com/vaadin/ui/themes/BaseTheme.java
diff --git a/server/src/com/vaadin/ui/themes/ChameleonTheme.java b/server/src/main/java/com/vaadin/ui/themes/ChameleonTheme.java
index 6e230c426e..6e230c426e 100644
--- a/server/src/com/vaadin/ui/themes/ChameleonTheme.java
+++ b/server/src/main/java/com/vaadin/ui/themes/ChameleonTheme.java
diff --git a/server/src/com/vaadin/ui/themes/LiferayTheme.java b/server/src/main/java/com/vaadin/ui/themes/LiferayTheme.java
index de56be39ac..de56be39ac 100644
--- a/server/src/com/vaadin/ui/themes/LiferayTheme.java
+++ b/server/src/main/java/com/vaadin/ui/themes/LiferayTheme.java
diff --git a/server/src/com/vaadin/ui/themes/Reindeer.java b/server/src/main/java/com/vaadin/ui/themes/Reindeer.java
index e0ab792a15..e0ab792a15 100644
--- a/server/src/com/vaadin/ui/themes/Reindeer.java
+++ b/server/src/main/java/com/vaadin/ui/themes/Reindeer.java
diff --git a/server/src/com/vaadin/ui/themes/Runo.java b/server/src/main/java/com/vaadin/ui/themes/Runo.java
index 6f8d5f37d9..6f8d5f37d9 100644
--- a/server/src/com/vaadin/ui/themes/Runo.java
+++ b/server/src/main/java/com/vaadin/ui/themes/Runo.java
diff --git a/server/src/com/vaadin/ui/themes/ValoTheme.java b/server/src/main/java/com/vaadin/ui/themes/ValoTheme.java
index 3a9986c632..3a9986c632 100644
--- a/server/src/com/vaadin/ui/themes/ValoTheme.java
+++ b/server/src/main/java/com/vaadin/ui/themes/ValoTheme.java
diff --git a/server/src/com/vaadin/util/ConnectorHelper.java b/server/src/main/java/com/vaadin/util/ConnectorHelper.java
index b3457068c3..b3457068c3 100644
--- a/server/src/com/vaadin/util/ConnectorHelper.java
+++ b/server/src/main/java/com/vaadin/util/ConnectorHelper.java
diff --git a/server/src/com/vaadin/util/CurrentInstance.java b/server/src/main/java/com/vaadin/util/CurrentInstance.java
index e6b58ec65c..e6b58ec65c 100644
--- a/server/src/com/vaadin/util/CurrentInstance.java
+++ b/server/src/main/java/com/vaadin/util/CurrentInstance.java
diff --git a/server/src/com/vaadin/util/FileTypeResolver.java b/server/src/main/java/com/vaadin/util/FileTypeResolver.java
index a49a0e2d01..a49a0e2d01 100644
--- a/server/src/com/vaadin/util/FileTypeResolver.java
+++ b/server/src/main/java/com/vaadin/util/FileTypeResolver.java
diff --git a/server/src/com/vaadin/util/ReflectTools.java b/server/src/main/java/com/vaadin/util/ReflectTools.java
index 2e2d3fe238..2e2d3fe238 100644
--- a/server/src/com/vaadin/util/ReflectTools.java
+++ b/server/src/main/java/com/vaadin/util/ReflectTools.java
diff --git a/server/src/com/vaadin/util/SerializerHelper.java b/server/src/main/java/com/vaadin/util/SerializerHelper.java
index 793488d892..793488d892 100644
--- a/server/src/com/vaadin/util/SerializerHelper.java
+++ b/server/src/main/java/com/vaadin/util/SerializerHelper.java
diff --git a/server/src/main/resources/VAADIN/vaadinBootstrap.js b/server/src/main/resources/VAADIN/vaadinBootstrap.js
new file mode 100644
index 0000000000..89514dbcc2
--- /dev/null
+++ b/server/src/main/resources/VAADIN/vaadinBootstrap.js
@@ -0,0 +1,359 @@
+(function() {
+ var apps = {};
+ var themesLoaded = {};
+ var widgetsets = {};
+
+
+ var log;
+ if (typeof console === "undefined" || !window.location.search.match(/[&?]debug(&|$)/)) {
+ //If no console.log present, just use a no-op
+ log = function() {};
+ } else if (typeof console.log === "function") {
+ //If it's a function, use it with apply
+ log = function() {
+ console.log.apply(console, arguments);
+ };
+ } else {
+ //In IE, its a native function for which apply is not defined, but it works without a proper 'this' reference
+ log = console.log;
+ }
+
+ var loadTheme = function(url, version) {
+ if(!themesLoaded[url]) {
+ log("loadTheme", url, version);
+
+ var href = url + '/styles.css';
+ if (version) {
+ href += '?v=' + version;
+ }
+
+ var stylesheet = document.createElement('link');
+ stylesheet.setAttribute('rel', 'stylesheet');
+ stylesheet.setAttribute('type', 'text/css');
+ stylesheet.setAttribute('href', href);
+ document.getElementsByTagName('head')[0].appendChild(stylesheet);
+ themesLoaded[url] = true;
+ }
+ };
+
+ var isWidgetsetLoaded = function(widgetset) {
+ var className = widgetset.replace(/\./g, "_");
+ return (typeof window[className]) != "undefined";
+ };
+
+ var loadWidgetset = function(url, widgetset) {
+ if (widgetsets[widgetset]) {
+ return;
+ }
+ log("load widgetset", url, widgetset);
+ setTimeout(function() {
+ if (!isWidgetsetLoaded(widgetset)) {
+ alert("Failed to load the widgetset: " + url);
+ }
+ }, 15000);
+
+ var scriptTag = document.createElement('script');
+ scriptTag.setAttribute('type', 'text/javascript');
+ scriptTag.setAttribute('src', url);
+ document.getElementsByTagName('head')[0].appendChild(scriptTag);
+
+ widgetsets[widgetset] = {
+ pendingApps: []
+ };
+ };
+
+ var isInitializedInDom = function(appId) {
+ var appDiv = document.getElementById(appId);
+ if (!appDiv) {
+ return false;
+ }
+ for ( var i = 0; i < appDiv.childElementCount; i++) {
+ var className = appDiv.childNodes[i].className;
+ // If the app div contains a child with the class
+ // "v-app-loading" we have only received the HTML
+ // but not yet started the widget set
+ // (UIConnector removes the v-app-loading div).
+ if (className && className.indexOf("v-app-loading") != -1) {
+ return false;
+ }
+ }
+ return true;
+ };
+
+ window.vaadin = window.vaadin || {
+ initApplication: function(appId, config) {
+ var testbenchId = appId.replace(/-\d+$/, '');
+
+ if (apps[appId]) {
+ if (window.vaadin && window.vaadin.clients && window.vaadin.clients[testbenchId] && window.vaadin.clients[testbenchId].initializing) {
+ throw "Application " + appId + " is already being initialized";
+ }
+ if (isInitializedInDom(appId)) {
+ throw "Application " + appId + " already initialized";
+ }
+ }
+
+ log("init application", appId, config);
+
+ window.vaadin.clients[testbenchId] = {
+ isActive: function() {
+ return true;
+ },
+ initializing: true
+ };
+
+ var getConfig = function(name) {
+ var value = config[name];
+ return value;
+ };
+
+ var fetchRootConfig = function(callback) {
+ log('Fetching root config');
+ var url = getConfig('browserDetailsUrl');
+ if (!url) {
+ // No special url defined, use the same URL that loaded this page (without the fragment)
+ url = window.location.href.replace(/#.*/,'');
+ }
+ // Timestamp to avoid caching
+ url += ((/\?/).test(url) ? "&" : "?") + "v-" + (new Date()).getTime();
+
+ var params = "v-browserDetails=1";
+ var rootId = getConfig("v-rootId");
+ if (rootId !== undefined) {
+ params += "&v-rootId=" + rootId;
+ }
+
+ // Tell the UI what theme it is configured to use
+ var theme = getConfig('theme');
+ if (theme !== undefined) {
+ params += '&theme=' + encodeURIComponent(theme);
+ }
+
+ params += "&v-appId=" + appId;
+
+ var extraParams = getConfig('extraParams')
+ if (extraParams !== undefined) {
+ params += extraParams;
+ }
+
+ params += '&' + vaadin.getBrowserDetailsParameters(appId, getConfig('sendUrlsAsParameters'));
+
+ var r;
+ try {
+ r = new XMLHttpRequest();
+ } catch (e) {
+ r = new ActiveXObject("MSXML2.XMLHTTP.3.0");
+ }
+ r.open('POST', url, true);
+ r.onreadystatechange = function (aEvt) {
+ if (r.readyState == 4) {
+ // Save responseStatus so as Offline Applications know what happened
+ // when loading root configuration from server, and depending on the
+ // error status display an error message or the offline UI.
+ config.rootResponseStatus = r.status;
+ config.rootResponseText = r.responseText;
+
+ var text = r.responseText;
+ if (r.status == 200){
+ log("Got root config response", text);
+ var updatedConfig = JSON.parse(text);
+
+ // Copy new properties to the config object
+ for (var property in updatedConfig) {
+ if (updatedConfig.hasOwnProperty(property)) {
+ config[property] = updatedConfig[property];
+ }
+ }
+
+ // Try bootstrapping again, this time without fetching missing info
+ bootstrapApp(false);
+ } else {
+ log('Error', r.statusText, text);
+
+ //Let TB waitForVaadin work again
+ delete window.vaadin.clients[testbenchId];
+
+ // Show the error in the app's div
+ var appDiv = document.getElementById(appId);
+ appDiv.innerHTML = text;
+ appDiv.style['overflow'] = 'auto';
+ }
+
+ // Run the fetchRootConfig callback if present.
+ callback && callback(r);
+ }
+ };
+ // send parameters as POST data
+ r.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
+ r.send(params);
+
+ log('sending request to ', url);
+ };
+
+ //Export public data
+ var app = {
+ getConfig: getConfig,
+ // Used when the app was started in offline, so as it is possible
+ // to defer root configuration loading until network is available.
+ fetchRootConfig: fetchRootConfig
+ };
+ apps[appId] = app;
+
+ if (!window.name) {
+ window.name = appId + '-' + Math.random();
+ }
+
+ var bootstrapApp = function(mayDefer) {
+ var vaadinDir = getConfig('vaadinDir');
+
+ var versionInfo = getConfig('versionInfo');
+
+ var themeUri = vaadinDir + 'themes/' + getConfig('theme');
+ loadTheme(themeUri, versionInfo && versionInfo['vaadinVersion']);
+
+ var widgetset = getConfig('widgetset');
+ var widgetsetUrl = getConfig('widgetsetUrl');
+ if (!widgetsetUrl) {
+ widgetsetUrl = vaadinDir + 'widgetsets/' + widgetset + "/" + widgetset + ".nocache.js?" + new Date().getTime();
+ }
+ loadWidgetset(widgetsetUrl, widgetset);
+
+ if (getConfig('uidl') === undefined) {
+ if (mayDefer) {
+ fetchRootConfig();
+ } else {
+ throw "May not defer bootstrap any more";
+ }
+ } else {
+ if (widgetsets[widgetset].callback) {
+ log("Starting from bootstrap", appId);
+ widgetsets[widgetset].callback(appId);
+ } else {
+ log("Setting pending startup", appId);
+ widgetsets[widgetset].pendingApps.push(appId);
+ }
+ }
+ };
+ bootstrapApp(true);
+
+ if (getConfig("debug")) {
+ // TODO debug state is now global for the entire page, but should somehow only be set for the current application
+ window.vaadin.debug = true;
+ }
+
+ return app;
+ },
+ clients: {},
+ getAppIds: function() {
+ var ids = [ ];
+ for (var id in apps) {
+ if (apps.hasOwnProperty(id)) {
+ ids.push(id);
+ }
+ }
+ return ids;
+ },
+ getApp: function(appId) {
+ return apps[appId];
+ },
+ loadTheme: loadTheme,
+ registerWidgetset: function(widgetset, callback) {
+ log("Widgetset registered", widgetset);
+ var ws = widgetsets[widgetset];
+ if (ws && ws.pendingApps) {
+ ws.callback = callback;
+ for(var i = 0; i < ws.pendingApps.length; i++) {
+ var appId = ws.pendingApps[i];
+ log("Starting from register widgetset", appId);
+ callback(appId);
+ }
+ ws.pendingApps = null;
+ }
+ },
+ getBrowserDetailsParameters: function(parentElementId, sendUrlsAsParameters) {
+ // Screen height and width
+ var params = 'v-sh=' + window.screen.height;
+ params += '&v-sw=' + window.screen.width;
+
+ // Window height and width
+ var cw = 0;
+ var ch = 0;
+ if(typeof(window.innerWidth) == 'number') {
+ // Modern browsers
+ cw = window.innerWidth;
+ ch = window.innerHeight;
+ } else {
+ // IE 8
+ cw = document.documentElement.clientWidth;
+ ch = document.documentElement.clientHeight;
+ }
+ params += '&v-cw=' + cw + '&v-ch=' + ch;
+
+
+ var d = new Date();
+
+ params += '&v-curdate=' + d.getTime();
+
+ var tzo1 = d.getTimezoneOffset(); // current offset
+ var dstDiff = 0;
+ var rtzo = tzo1;
+
+ for (var m=12;m>0;m--) {
+ d.setUTCMonth(m);
+ var tzo2 = d.getTimezoneOffset();
+ if (tzo1 != tzo2) {
+ dstDiff = (tzo1 > tzo2 ? tzo1-tzo2 : tzo2-tzo1); // offset w/o DST
+ rtzo = (tzo1 > tzo2 ? tzo1 : tzo2); // offset w/o DST
+ break;
+ }
+ }
+
+ // Time zone offset
+ params += '&v-tzo=' + tzo1;
+
+ // DST difference
+ params += '&v-dstd=' + dstDiff;
+
+ // Raw time zone offset
+ params += '&v-rtzo=' + rtzo;
+
+ // DST in effect?
+ params += '&v-dston=' + (tzo1 != rtzo);
+
+ var pe = document.getElementById(parentElementId);
+ if (pe) {
+ params += '&v-vw=' + pe.offsetWidth;
+ params += '&v-vh=' + pe.offsetHeight;
+ }
+
+ // Location
+ if (sendUrlsAsParameters !== false) {
+ params += '&v-loc=' + encodeURIComponent(location.href);
+ }
+
+ // Window name
+ if (window.name) {
+ params += '&v-wn=' + encodeURIComponent(window.name);
+ }
+
+ // Detect touch device support
+ var supportsTouch = false;
+ try {
+ document.createEvent("TouchEvent");
+ supportsTouch = true;
+ } catch (e) {
+ // Chrome and IE10 touch detection
+ supportsTouch = 'ontouchstart' in window
+ || navigator.msMaxTouchPoints;
+ }
+
+ if (supportsTouch) {
+ params += "&v-td=1";
+ }
+
+ return params;
+ }
+ };
+
+ log('Vaadin bootstrap loaded');
+})();
diff --git a/server/src/com/vaadin/annotations/package.html b/server/src/main/resources/com/vaadin/annotations/package.html
index d789e9b5df..d789e9b5df 100644
--- a/server/src/com/vaadin/annotations/package.html
+++ b/server/src/main/resources/com/vaadin/annotations/package.html
diff --git a/server/src/com/vaadin/data/package.html b/server/src/main/resources/com/vaadin/data/package.html
index a14ea1ac88..a14ea1ac88 100644
--- a/server/src/com/vaadin/data/package.html
+++ b/server/src/main/resources/com/vaadin/data/package.html
diff --git a/server/src/com/vaadin/data/util/package.html b/server/src/main/resources/com/vaadin/data/util/package.html
index 07e3acde9e..07e3acde9e 100644
--- a/server/src/com/vaadin/data/util/package.html
+++ b/server/src/main/resources/com/vaadin/data/util/package.html
diff --git a/server/src/com/vaadin/data/validator/package.html b/server/src/main/resources/com/vaadin/data/validator/package.html
index c991bfc82a..c991bfc82a 100644
--- a/server/src/com/vaadin/data/validator/package.html
+++ b/server/src/main/resources/com/vaadin/data/validator/package.html
diff --git a/server/src/com/vaadin/event/package.html b/server/src/main/resources/com/vaadin/event/package.html
index 2e7e17b892..2e7e17b892 100644
--- a/server/src/com/vaadin/event/package.html
+++ b/server/src/main/resources/com/vaadin/event/package.html
diff --git a/server/src/com/vaadin/package.html b/server/src/main/resources/com/vaadin/package.html
index 097fd94aca..097fd94aca 100644
--- a/server/src/com/vaadin/package.html
+++ b/server/src/main/resources/com/vaadin/package.html
diff --git a/server/src/com/vaadin/server/package.html b/server/src/main/resources/com/vaadin/server/package.html
index 83514a0de5..83514a0de5 100644
--- a/server/src/com/vaadin/server/package.html
+++ b/server/src/main/resources/com/vaadin/server/package.html
diff --git a/server/src/com/vaadin/ui/doc-files/component_class_hierarchy.gif b/server/src/main/resources/com/vaadin/ui/doc-files/component_class_hierarchy.gif
index 936c220d11..936c220d11 100644
--- a/server/src/com/vaadin/ui/doc-files/component_class_hierarchy.gif
+++ b/server/src/main/resources/com/vaadin/ui/doc-files/component_class_hierarchy.gif
Binary files differ
diff --git a/server/src/com/vaadin/ui/doc-files/component_interfaces.gif b/server/src/main/resources/com/vaadin/ui/doc-files/component_interfaces.gif
index 44c99826bb..44c99826bb 100644
--- a/server/src/com/vaadin/ui/doc-files/component_interfaces.gif
+++ b/server/src/main/resources/com/vaadin/ui/doc-files/component_interfaces.gif
Binary files differ
diff --git a/server/src/com/vaadin/ui/package.html b/server/src/main/resources/com/vaadin/ui/package.html
index 6b19a28fe7..6b19a28fe7 100644
--- a/server/src/com/vaadin/ui/package.html
+++ b/server/src/main/resources/com/vaadin/ui/package.html
diff --git a/server/src/test/java/ClassInDefaultPackage.java b/server/src/test/java/ClassInDefaultPackage.java
new file mode 100644
index 0000000000..52dc87e0e2
--- /dev/null
+++ b/server/src/test/java/ClassInDefaultPackage.java
@@ -0,0 +1,29 @@
+import org.junit.Ignore;
+
+/*
+ * Copyright 2000-2014 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.
+ */
+
+/**
+ *
+ * This class is test data. Don't delete it.
+ *
+ * @author Vaadin Ltd
+ * @since 7.2
+ */
+@Ignore
+public class ClassInDefaultPackage {
+
+}
diff --git a/server/src/test/java/com/vaadin/benchmarks/PerformanceTester8759.java b/server/src/test/java/com/vaadin/benchmarks/PerformanceTester8759.java
new file mode 100644
index 0000000000..968edd4b24
--- /dev/null
+++ b/server/src/test/java/com/vaadin/benchmarks/PerformanceTester8759.java
@@ -0,0 +1,52 @@
+package com.vaadin.benchmarks;
+
+import com.vaadin.ui.Label;
+
+/*
+ * This simple test shows the performance difference between the StringTokenizer implementation and the String.split() implementation in AbstractComponent.
+ * Your results will vary.
+ * The real world use case motivating it was a 10k Row table, which generated labels for 10 columns.
+ * This is 1/10th of what this performance tester demonstrates.
+ *
+ * Please run with -server and -Xloggc:/tmp/gclog.vgc -verbose:gc -XX:+PrintCompilation
+ *
+ * My results Win 7 64, i7 2760QM 2.4Ghz, Java 7 21.
+ *
+ * Proposed Patch with StringTokenizer:
+ * 13 GC activations, 1.009GB allocated memory over time, total time 948ms
+ *
+ * Current String.split implementation:
+ * 31 GC activations, 2.277 GB allocated memory over time, total time 1557ms
+ *
+ */
+public class PerformanceTester8759 {
+
+ public static void main(String[] args) throws InterruptedException {
+ warmup();
+
+ long start = System.currentTimeMillis();
+ runBenchmark(1000000);
+ long end = System.currentTimeMillis();
+ System.out.println("took " + (end - start) + " ms");
+
+ }
+
+ private static void warmup() throws InterruptedException {
+ runBenchmark(10000);
+ System.gc();
+ System.out.println("warmup and gc complete. sleeping 5 seconds.");
+ Thread.sleep(5000l);
+ System.out.println("woke up - go.");
+ }
+
+ private static void runBenchmark(int loops) {
+ Label label = null;
+ for (int i = 0; i < loops; i++) {
+ label = new Label();
+ label.setStyleName("mainStyle");
+ label.addStyleName("foo bar baz");
+ label.addStyleName("vaadin");
+ }
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/data/DefaultFieldGroupFieldFactoryTest.java b/server/src/test/java/com/vaadin/data/DefaultFieldGroupFieldFactoryTest.java
new file mode 100644
index 0000000000..fc258ab138
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/DefaultFieldGroupFieldFactoryTest.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.data;
+
+import java.lang.reflect.Constructor;
+import java.util.Date;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.fieldgroup.DefaultFieldGroupFieldFactory;
+import com.vaadin.ui.AbstractSelect;
+import com.vaadin.ui.ComboBox;
+import com.vaadin.ui.DateField;
+import com.vaadin.ui.Field;
+import com.vaadin.ui.InlineDateField;
+import com.vaadin.ui.ListSelect;
+import com.vaadin.ui.PopupDateField;
+import com.vaadin.ui.TextField;
+
+public class DefaultFieldGroupFieldFactoryTest {
+
+ private DefaultFieldGroupFieldFactory fieldFactory;
+
+ @Before
+ public void setupFieldFactory() {
+ fieldFactory = DefaultFieldGroupFieldFactory.get();
+ }
+
+ @Test
+ public void noPublicConstructor() {
+ Class<DefaultFieldGroupFieldFactory> clazz = DefaultFieldGroupFieldFactory.class;
+ Constructor<?>[] constructors = clazz.getConstructors();
+ Assert.assertEquals(
+ "DefaultFieldGroupFieldFactory contains public constructors",
+ 0, constructors.length);
+ }
+
+ @Test
+ public void testSameInstance() {
+ DefaultFieldGroupFieldFactory factory1 = DefaultFieldGroupFieldFactory
+ .get();
+ DefaultFieldGroupFieldFactory factory2 = DefaultFieldGroupFieldFactory
+ .get();
+ Assert.assertTrue(
+ "DefaultFieldGroupFieldFactory.get() method returns different instances",
+ factory1 == factory2);
+ Assert.assertNotNull(
+ "DefaultFieldGroupFieldFactory.get() method returns null",
+ factory1);
+ }
+
+ @Test
+ public void testDateGenerationForPopupDateField() {
+ Field f = fieldFactory.createField(Date.class, DateField.class);
+ Assert.assertNotNull(f);
+ Assert.assertEquals(PopupDateField.class, f.getClass());
+ }
+
+ @Test
+ public void testDateGenerationForInlineDateField() {
+ Field f = fieldFactory.createField(Date.class, InlineDateField.class);
+ Assert.assertNotNull(f);
+ Assert.assertEquals(InlineDateField.class, f.getClass());
+ }
+
+ @Test
+ public void testDateGenerationForTextField() {
+ Field f = fieldFactory.createField(Date.class, TextField.class);
+ Assert.assertNotNull(f);
+ Assert.assertEquals(TextField.class, f.getClass());
+ }
+
+ @Test
+ public void testDateGenerationForField() {
+ Field f = fieldFactory.createField(Date.class, Field.class);
+ Assert.assertNotNull(f);
+ Assert.assertEquals(PopupDateField.class, f.getClass());
+ }
+
+ public enum SomeEnum {
+ FOO, BAR;
+ }
+
+ @Test
+ public void testEnumComboBox() {
+ Field f = fieldFactory.createField(SomeEnum.class, ComboBox.class);
+ Assert.assertNotNull(f);
+ Assert.assertEquals(ComboBox.class, f.getClass());
+ }
+
+ @Test
+ public void testEnumAnySelect() {
+ Field f = fieldFactory
+ .createField(SomeEnum.class, AbstractSelect.class);
+ Assert.assertNotNull(f);
+ Assert.assertEquals(ListSelect.class, f.getClass());
+ }
+
+ @Test
+ public void testEnumAnyField() {
+ Field f = fieldFactory.createField(SomeEnum.class, Field.class);
+ Assert.assertNotNull(f);
+ Assert.assertEquals(ListSelect.class, f.getClass());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/data/fieldgroup/BeanFieldGroupTest.java b/server/src/test/java/com/vaadin/data/fieldgroup/BeanFieldGroupTest.java
new file mode 100644
index 0000000000..3333cd7744
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/fieldgroup/BeanFieldGroupTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2012 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.data.fieldgroup;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class BeanFieldGroupTest {
+
+ class Main {
+ private String mainField;
+
+ public String getMainField() {
+ return mainField;
+ }
+
+ public void setMainField(String mainField) {
+ this.mainField = mainField;
+ }
+
+ }
+
+ class Sub1 extends Main {
+ private Integer sub1Field;
+
+ public Integer getSub1Field() {
+ return sub1Field;
+ }
+
+ public void setSub1Field(Integer sub1Field) {
+ this.sub1Field = sub1Field;
+ }
+
+ }
+
+ class Sub2 extends Sub1 {
+ private boolean sub2field;
+
+ public boolean isSub2field() {
+ return sub2field;
+ }
+
+ public void setSub2field(boolean sub2field) {
+ this.sub2field = sub2field;
+ }
+
+ }
+
+ @Test
+ public void propertyTypeWithoutItem() {
+ BeanFieldGroup<Sub2> s = new BeanFieldGroup<BeanFieldGroupTest.Sub2>(
+ Sub2.class);
+ Assert.assertEquals(boolean.class, s.getPropertyType("sub2field"));
+ Assert.assertEquals(Integer.class, s.getPropertyType("sub1Field"));
+ Assert.assertEquals(String.class, s.getPropertyType("mainField"));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/data/fieldgroup/FieldGroupDateTest.java b/server/src/test/java/com/vaadin/data/fieldgroup/FieldGroupDateTest.java
new file mode 100644
index 0000000000..ce76f8427b
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/fieldgroup/FieldGroupDateTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.data.fieldgroup;
+
+import java.util.Date;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.util.BeanItem;
+import com.vaadin.ui.Field;
+import com.vaadin.ui.PopupDateField;
+
+public class FieldGroupDateTest {
+
+ private FieldGroup fieldGroup;
+
+ public class TestBean {
+ private Date javaDate;
+ private java.sql.Date sqlDate;
+
+ public TestBean(Date javaDate, java.sql.Date sqlDate) {
+ super();
+ this.javaDate = javaDate;
+ this.sqlDate = sqlDate;
+ }
+
+ public java.sql.Date getSqlDate() {
+ return sqlDate;
+ }
+
+ public void setSqlDate(java.sql.Date sqlDate) {
+ this.sqlDate = sqlDate;
+ }
+
+ public Date getJavaDate() {
+ return javaDate;
+ }
+
+ public void setJavaDate(Date date) {
+ javaDate = date;
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ @Before
+ public void setup() {
+ fieldGroup = new FieldGroup();
+ fieldGroup.setItemDataSource(new BeanItem<TestBean>(new TestBean(
+ new Date(2010, 5, 7), new java.sql.Date(2011, 6, 8))));
+ }
+
+ @Test
+ public void testBuildAndBindDate() {
+ Field f = fieldGroup.buildAndBind("javaDate");
+ Assert.assertNotNull(f);
+ Assert.assertEquals(PopupDateField.class, f.getClass());
+ }
+
+ @Test
+ public void testBuildAndBindSqlDate() {
+ Field f = fieldGroup.buildAndBind("sqlDate");
+ Assert.assertNotNull(f);
+ Assert.assertEquals(PopupDateField.class, f.getClass());
+ }
+
+ @Test
+ public void clearFields() {
+ PopupDateField sqlDate = new PopupDateField();
+ PopupDateField javaDate = new PopupDateField();
+ fieldGroup.bind(sqlDate, "sqlDate");
+ fieldGroup.bind(javaDate, "javaDate");
+
+ Assert.assertEquals(new Date(2010, 5, 7), javaDate.getValue());
+ Assert.assertEquals(new Date(2011, 6, 8), sqlDate.getValue());
+
+ fieldGroup.clear();
+ Assert.assertEquals(null, javaDate.getValue());
+ Assert.assertEquals(null, sqlDate.getValue());
+
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/data/fieldgroup/FieldGroupExceptionTest.java b/server/src/test/java/com/vaadin/data/fieldgroup/FieldGroupExceptionTest.java
new file mode 100644
index 0000000000..636162de54
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/fieldgroup/FieldGroupExceptionTest.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.data.fieldgroup;
+
+import org.junit.Test;
+
+import com.vaadin.data.fieldgroup.FieldGroup.CommitException;
+import com.vaadin.ui.PopupDateField;
+
+public class FieldGroupExceptionTest {
+
+ @Test(expected = CommitException.class)
+ public void testUnboundCommitException() throws CommitException {
+ FieldGroup fieldGroup = new FieldGroup();
+ PopupDateField dateField = new PopupDateField();
+ fieldGroup.bind(dateField, "date");
+ fieldGroup.commit();
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/data/fieldgroup/FieldGroupTests.java b/server/src/test/java/com/vaadin/data/fieldgroup/FieldGroupTests.java
new file mode 100644
index 0000000000..dce9f656b9
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/fieldgroup/FieldGroupTests.java
@@ -0,0 +1,95 @@
+package com.vaadin.data.fieldgroup;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNull.nullValue;
+import static org.mockito.Mockito.mock;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.Property;
+import com.vaadin.data.Property.Transactional;
+import com.vaadin.data.util.BeanItem;
+import com.vaadin.data.util.TransactionalPropertyWrapper;
+import com.vaadin.ui.Field;
+import com.vaadin.ui.TextField;
+
+public class FieldGroupTests {
+
+ private FieldGroup sut;
+ private Field field;
+
+ @Before
+ public void setup() {
+ sut = new FieldGroup();
+ field = mock(Field.class);
+ }
+
+ @Test
+ public void fieldIsBound() {
+ sut.bind(field, "foobar");
+
+ assertThat(sut.getField("foobar"), is(field));
+ }
+
+ @Test(expected = FieldGroup.BindException.class)
+ public void cannotBindToAlreadyBoundProperty() {
+ sut.bind(field, "foobar");
+ sut.bind(mock(Field.class), "foobar");
+ }
+
+ @Test(expected = FieldGroup.BindException.class)
+ public void cannotBindNullField() {
+ sut.bind(null, "foobar");
+ }
+
+ public void canUnbindWithoutItem() {
+ sut.bind(field, "foobar");
+
+ sut.unbind(field);
+ assertThat(sut.getField("foobar"), is(nullValue()));
+ }
+
+ @Test
+ public void wrapInTransactionalProperty_provideCustomImpl_customTransactionalWrapperIsUsed() {
+ Bean bean = new Bean();
+ FieldGroup group = new FieldGroup() {
+ @Override
+ protected <T> Transactional<T> wrapInTransactionalProperty(
+ Property<T> itemProperty) {
+ return new TransactionalPropertyImpl(itemProperty);
+ }
+ };
+ group.setItemDataSource(new BeanItem<Bean>(bean));
+ TextField field = new TextField();
+ group.bind(field, "name");
+
+ Property propertyDataSource = field.getPropertyDataSource();
+ Assert.assertTrue("Custom implementation of transactional property "
+ + "has not been used",
+ propertyDataSource instanceof TransactionalPropertyImpl);
+ }
+
+ public static class TransactionalPropertyImpl<T> extends
+ TransactionalPropertyWrapper<T> {
+
+ public TransactionalPropertyImpl(Property<T> wrappedProperty) {
+ super(wrappedProperty);
+ }
+
+ }
+
+ public static class Bean {
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/data/util/AbstractBeanContainerTestBase.java b/server/src/test/java/com/vaadin/data/util/AbstractBeanContainerTestBase.java
new file mode 100644
index 0000000000..3d8f08a7ef
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/AbstractBeanContainerTestBase.java
@@ -0,0 +1,77 @@
+package com.vaadin.data.util;
+
+/**
+ * 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 AbstractBeanContainerTestBase extends
+ AbstractInMemoryContainerTestBase {
+
+ 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 = AbstractContainerTestBase
+ .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/src/test/java/com/vaadin/data/util/AbstractContainerTestBase.java b/server/src/test/java/com/vaadin/data/util/AbstractContainerTestBase.java
new file mode 100644
index 0000000000..52acc5ab76
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/AbstractContainerTestBase.java
@@ -0,0 +1,856 @@
+package com.vaadin.data.util;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.junit.Assert;
+
+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.Ordered;
+import com.vaadin.data.Container.Sortable;
+import com.vaadin.data.Item;
+import com.vaadin.data.util.filter.SimpleStringFilter;
+
+public abstract class AbstractContainerTestBase 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);
+
+ validateRemovingItems(container);
+ validateAddItem(container);
+ if (container instanceof Container.Indexed) {
+ validateAddItemAt((Container.Indexed) container);
+ }
+ if (container instanceof Container.Ordered) {
+ validateAddItemAfter((Container.Ordered) container);
+ }
+
+ }
+
+ protected void validateRemovingItems(Container container) {
+ int sizeBeforeRemoving = container.size();
+
+ List<Object> itemIdList = new ArrayList<Object>(container.getItemIds());
+ // There should be at least four items in the list
+ Object first = itemIdList.get(0);
+ Object middle = itemIdList.get(2);
+ Object last = itemIdList.get(itemIdList.size() - 1);
+
+ container.removeItem(first);
+ container.removeItem(middle); // Middle now that first has been removed
+ container.removeItem(last);
+
+ assertEquals(sizeBeforeRemoving - 3, container.size());
+
+ container.removeAllItems();
+
+ assertEquals(0, container.size());
+ }
+
+ protected void validateAddItem(Container container) {
+ try {
+ container.removeAllItems();
+
+ Object id = container.addItem();
+ Assert.assertTrue(container.containsId(id));
+ Assert.assertNotNull(container.getItem(id));
+
+ Item item = container.addItem("foo");
+ Assert.assertNotNull(item);
+ Assert.assertTrue(container.containsId("foo"));
+ Assert.assertEquals(item, container.getItem("foo"));
+
+ // Add again
+ Item item2 = container.addItem("foo");
+ Assert.assertNull(item2);
+ } catch (UnsupportedOperationException e) {
+ // Ignore contains which do not support addItem*
+ }
+ }
+
+ protected void validateAddItemAt(Container.Indexed container) {
+ try {
+ container.removeAllItems();
+
+ Object id = container.addItemAt(0);
+ Assert.assertTrue(container.containsId(id));
+ Assert.assertEquals(id, container.getIdByIndex(0));
+ Assert.assertNotNull(container.getItem(id));
+
+ Item item = container.addItemAt(0, "foo");
+ Assert.assertNotNull(item);
+ Assert.assertTrue(container.containsId("foo"));
+ Assert.assertEquals(item, container.getItem("foo"));
+ Assert.assertEquals("foo", container.getIdByIndex(0));
+
+ Item itemAtEnd = container.addItemAt(2, "atend");
+ Assert.assertNotNull(itemAtEnd);
+ Assert.assertTrue(container.containsId("atend"));
+ Assert.assertEquals(itemAtEnd, container.getItem("atend"));
+ Assert.assertEquals("atend", container.getIdByIndex(2));
+
+ // Add again
+ Item item2 = container.addItemAt(0, "foo");
+ Assert.assertNull(item2);
+ } catch (UnsupportedOperationException e) {
+ // Ignore contains which do not support addItem*
+ }
+ }
+
+ protected void validateAddItemAfter(Container.Ordered container) {
+ if (container instanceof AbstractBeanContainer) {
+ // Doesn't work as bean container requires beans
+ return;
+ }
+ if (container instanceof ContainerOrderedWrapper) {
+ // Doesn't work because of #19427
+ return;
+ }
+
+ try {
+ container.removeAllItems();
+
+ Assert.assertNotNull(container.addItem(0));
+
+ Item item = container.addItemAfter(null, "foo");
+ Assert.assertNotNull(item);
+ Assert.assertTrue(container.containsId("foo"));
+ Assert.assertEquals(item, container.getItem("foo"));
+ Assert.assertEquals("foo", container.getItemIds().iterator().next());
+
+ Item itemAtEnd = container.addItemAfter(0, "atend");
+ Assert.assertNotNull(itemAtEnd);
+ Assert.assertTrue(container.containsId("atend"));
+ Assert.assertEquals(itemAtEnd, container.getItem("atend"));
+ Iterator<?> i = container.getItemIds().iterator();
+ i.next();
+ i.next();
+ Assert.assertEquals("atend", i.next());
+
+ // Add again
+ Assert.assertNull(container.addItemAfter(null, "foo"));
+ Assert.assertNull(container.addItemAfter("atend", "foo"));
+ Assert.assertNull(container.addItemAfter("nonexistant", "123123"));
+ } catch (UnsupportedOperationException e) {
+ // Ignore contains which do not support addItem*
+ }
+ }
+
+ protected void testContainerOrdered(Container.Ordered container) {
+ // addItem with empty container
+ Object id = container.addItem();
+ assertOrderedContents(container, id);
+ Item item = container.getItem(id);
+ assertNotNull(item);
+
+ // addItemAfter with empty container
+ container.removeAllItems();
+ assertOrderedContents(container);
+ id = container.addItemAfter(null);
+ assertOrderedContents(container, id);
+ item = container.getItem(id);
+ assertNotNull(item);
+
+ // Add a new item before the first
+ // addItemAfter
+ Object newFirstId = container.addItemAfter(null);
+ assertOrderedContents(container, newFirstId, id);
+
+ // addItemAfter(Object)
+ Object newSecondItemId = container.addItemAfter(newFirstId);
+ // order is now: newFirstId, newSecondItemId, id
+ assertOrderedContents(container, newFirstId, newSecondItemId, id);
+
+ // 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));
+ assertOrderedContents(container, newFirstId, fourthId, newSecondItemId,
+ id);
+
+ // 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));
+ assertOrderedContents(container, fifthId, newFirstId, fourthId,
+ newSecondItemId, id);
+
+ // addItemAfter(Object,Object)
+ Object sixthId = new Object();
+ Item sixth = container.addItemAfter(id, sixthId);
+ // order is now: fifthId, newFirstId, fourthId, newSecondItemId, id,
+ // sixthId
+ assertNotNull(sixth);
+ assertEquals(sixth, container.getItem(sixthId));
+ assertOrderedContents(container, fifthId, newFirstId, fourthId,
+ newSecondItemId, id, sixthId);
+
+ // Test order after removing first item 'fifthId'
+ container.removeItem(fifthId);
+ // order is now: newFirstId, fourthId, newSecondItemId, id, sixthId
+ assertOrderedContents(container, newFirstId, fourthId, newSecondItemId,
+ id, sixthId);
+
+ // Test order after removing last item 'sixthId'
+ container.removeItem(sixthId);
+ // order is now: newFirstId, fourthId, newSecondItemId, id
+ assertOrderedContents(container, newFirstId, fourthId, newSecondItemId,
+ id);
+
+ // Test order after removing item from the middle 'fourthId'
+ container.removeItem(fourthId);
+ // order is now: newFirstId, newSecondItemId, id
+ assertOrderedContents(container, newFirstId, newSecondItemId, id);
+
+ // Delete remaining items
+ container.removeItem(newFirstId);
+ container.removeItem(newSecondItemId);
+ container.removeItem(id);
+ assertOrderedContents(container);
+
+ Object finalItem = container.addItem();
+ assertOrderedContents(container, finalItem);
+ }
+
+ private void assertOrderedContents(Ordered container, Object... ids) {
+ assertEquals(ids.length, container.size());
+ for (int i = 0; i < ids.length - 1; i++) {
+ assertNotNull("The item id should not be null", ids[i]);
+ }
+ if (ids.length == 0) {
+ assertNull("The first id is wrong", container.firstItemId());
+ assertNull("The last id is wrong", container.lastItemId());
+ return;
+ }
+
+ assertEquals("The first id is wrong", ids[0], container.firstItemId());
+ assertEquals("The last id is wrong", ids[ids.length - 1],
+ container.lastItemId());
+
+ // isFirstId & isLastId
+ assertTrue(container.isFirstId(container.firstItemId()));
+ assertTrue(container.isLastId(container.lastItemId()));
+
+ // nextId
+ Object ref = container.firstItemId();
+ for (int i = 1; i < ids.length; i++) {
+ Object next = container.nextItemId(ref);
+ assertEquals("The id after " + ref + " is wrong", ids[i], next);
+ ref = next;
+ }
+ assertNull("The last id should not have a next id",
+ container.nextItemId(ids[ids.length - 1]));
+ assertNull(container.nextItemId("not-in-container"));
+
+ // prevId
+ ref = container.lastItemId();
+ for (int i = ids.length - 2; i >= 0; i--) {
+ Object prev = container.prevItemId(ref);
+ assertEquals("The id before " + ref + " is wrong", ids[i], prev);
+ ref = prev;
+ }
+ assertNull("The first id should not have a prev id",
+ container.prevItemId(ids[0]));
+ assertNull(container.prevItemId("not-in-container"));
+
+ }
+
+ 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"
+ SimpleStringFilter filter1 = new SimpleStringFilter(
+ FULLY_QUALIFIED_NAME, "ab", false, false);
+ container.addContainerFilter(filter1);
+
+ assertTrue(container.getContainerFilters().size() == 1);
+ assertEquals(filter1, container.getContainerFilters().iterator().next());
+
+ validateContainer(container, "com.vaadin.data.BufferedValidatable",
+ "com.vaadin.ui.TabSheet",
+ "com.vaadin.terminal.gwt.client.Focusable",
+ "com.vaadin.data.Buffered", isFilteredOutItemNull(), 20);
+
+ // Filter by "contains da" (reversed as ad here)
+ container.removeAllContainerFilters();
+
+ assertTrue(container.getContainerFilters().isEmpty());
+
+ SimpleStringFilter filter2 = new SimpleStringFilter(
+ REVERSE_FULLY_QUALIFIED_NAME, "ad", false, false);
+ container.addContainerFilter(filter2);
+
+ assertTrue(container.getContainerFilters().size() == 1);
+ assertEquals(filter2, container.getContainerFilters().iterator().next());
+
+ validateContainer(container, "com.vaadin.data.Buffered",
+ "com.vaadin.server.ComponentSizeValidator",
+ "com.vaadin.data.util.IndexedContainer",
+ "com.vaadin.terminal.gwt.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.terminal.gwt.client.ApplicationConfiguration",
+ "com.vaadin.terminal.gwt.client.ApplicationConnection",
+ "com.vaadin.terminal.gwt.client.BrowserInfo",
+ "com.vaadin.terminal.gwt.client.ClientExceptionHandler",
+ "com.vaadin.terminal.gwt.client.ComponentDetail",
+ "com.vaadin.terminal.gwt.client.ComponentDetailMap",
+ "com.vaadin.terminal.gwt.client.ComponentLocator",
+ "com.vaadin.terminal.gwt.client.Console",
+ "com.vaadin.terminal.gwt.client.Container",
+ "com.vaadin.terminal.gwt.client.ContainerResizedListener",
+ "com.vaadin.terminal.gwt.client.CSSRule",
+ "com.vaadin.terminal.gwt.client.DateTimeService",
+ "com.vaadin.terminal.gwt.client.DefaultWidgetSet",
+ "com.vaadin.terminal.gwt.client.Focusable",
+ "com.vaadin.terminal.gwt.client.HistoryImplIEVaadin",
+ "com.vaadin.terminal.gwt.client.LocaleNotLoadedException",
+ "com.vaadin.terminal.gwt.client.LocaleService",
+ "com.vaadin.terminal.gwt.client.MouseEventDetails",
+ "com.vaadin.terminal.gwt.client.NullConsole",
+ "com.vaadin.terminal.gwt.client.Paintable",
+ "com.vaadin.terminal.gwt.client.RenderInformation",
+ "com.vaadin.terminal.gwt.client.RenderSpace",
+ "com.vaadin.terminal.gwt.client.StyleConstants",
+ "com.vaadin.terminal.gwt.client.TooltipInfo",
+ "com.vaadin.terminal.gwt.client.ui.Action",
+ "com.vaadin.terminal.gwt.client.ui.ActionOwner",
+ "com.vaadin.terminal.gwt.client.ui.AlignmentInfo",
+ "com.vaadin.terminal.gwt.client.ui.CalendarEntry",
+ "com.vaadin.terminal.gwt.client.ui.ClickEventHandler",
+ "com.vaadin.terminal.gwt.client.ui.Field",
+ "com.vaadin.terminal.gwt.client.ui.Icon",
+ "com.vaadin.terminal.gwt.client.ui.layout.CellBasedLayout",
+ "com.vaadin.terminal.gwt.client.ui.layout.ChildComponentContainer",
+ "com.vaadin.terminal.gwt.client.ui.layout.Margins",
+ "com.vaadin.terminal.gwt.client.ui.LayoutClickEventHandler",
+ "com.vaadin.terminal.gwt.client.ui.MenuBar",
+ "com.vaadin.terminal.gwt.client.ui.MenuItem",
+ "com.vaadin.terminal.gwt.client.ui.richtextarea.VRichTextToolbar",
+ "com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler",
+ "com.vaadin.terminal.gwt.client.ui.SubPartAware",
+ "com.vaadin.terminal.gwt.client.ui.Table",
+ "com.vaadin.terminal.gwt.client.ui.TreeAction",
+ "com.vaadin.terminal.gwt.client.ui.TreeImages",
+ "com.vaadin.terminal.gwt.client.ui.VAbsoluteLayout",
+ "com.vaadin.terminal.gwt.client.ui.VAccordion",
+ "com.vaadin.terminal.gwt.client.ui.VButton",
+ "com.vaadin.terminal.gwt.client.ui.VCalendarPanel",
+ "com.vaadin.terminal.gwt.client.ui.VCheckBox",
+ "com.vaadin.terminal.gwt.client.ui.VContextMenu",
+ "com.vaadin.terminal.gwt.client.ui.VCssLayout",
+ "com.vaadin.terminal.gwt.client.ui.VCustomComponent",
+ "com.vaadin.terminal.gwt.client.ui.VCustomLayout",
+ "com.vaadin.terminal.gwt.client.ui.VDateField",
+ "com.vaadin.terminal.gwt.client.ui.VDateFieldCalendar",
+ "com.vaadin.terminal.gwt.client.ui.VEmbedded",
+ "com.vaadin.terminal.gwt.client.ui.VFilterSelect",
+ "com.vaadin.terminal.gwt.client.ui.VForm",
+ "com.vaadin.terminal.gwt.client.ui.VFormLayout",
+ "com.vaadin.terminal.gwt.client.ui.VGridLayout",
+ "com.vaadin.terminal.gwt.client.ui.VHorizontalLayout",
+ "com.vaadin.terminal.gwt.client.ui.VLabel",
+ "com.vaadin.terminal.gwt.client.ui.VLink",
+ "com.vaadin.terminal.gwt.client.ui.VListSelect",
+ "com.vaadin.terminal.gwt.client.ui.VMarginInfo",
+ "com.vaadin.terminal.gwt.client.ui.VMenuBar",
+ "com.vaadin.terminal.gwt.client.ui.VNativeButton",
+ "com.vaadin.terminal.gwt.client.ui.VNativeSelect",
+ "com.vaadin.terminal.gwt.client.ui.VNotification",
+ "com.vaadin.terminal.gwt.client.ui.VOptionGroup",
+ "com.vaadin.terminal.gwt.client.ui.VOptionGroupBase",
+ "com.vaadin.terminal.gwt.client.ui.VOrderedLayout",
+ "com.vaadin.terminal.gwt.client.ui.VOverlay",
+ "com.vaadin.terminal.gwt.client.ui.VPanel",
+ "com.vaadin.terminal.gwt.client.ui.VPasswordField",
+ "com.vaadin.terminal.gwt.client.ui.VPopupCalendar",
+ "com.vaadin.terminal.gwt.client.ui.VPopupView",
+ "com.vaadin.terminal.gwt.client.ui.VProgressIndicator",
+ "com.vaadin.terminal.gwt.client.ui.VRichTextArea",
+ "com.vaadin.terminal.gwt.client.ui.VScrollTable",
+ "com.vaadin.terminal.gwt.client.ui.VSlider",
+ "com.vaadin.terminal.gwt.client.ui.VSplitPanel",
+ "com.vaadin.terminal.gwt.client.ui.VSplitPanelHorizontal",
+ "com.vaadin.terminal.gwt.client.ui.VSplitPanelVertical",
+ "com.vaadin.terminal.gwt.client.ui.VTablePaging",
+ "com.vaadin.terminal.gwt.client.ui.VTabsheet",
+ "com.vaadin.terminal.gwt.client.ui.VTabsheetBase",
+ "com.vaadin.terminal.gwt.client.ui.VTabsheetPanel",
+ "com.vaadin.terminal.gwt.client.ui.VTextArea",
+ "com.vaadin.terminal.gwt.client.ui.VTextField",
+ "com.vaadin.terminal.gwt.client.ui.VTextualDate",
+ "com.vaadin.terminal.gwt.client.ui.VTime",
+ "com.vaadin.terminal.gwt.client.ui.VTree",
+ "com.vaadin.terminal.gwt.client.ui.VTwinColSelect",
+ "com.vaadin.terminal.gwt.client.ui.VUnknownComponent",
+ "com.vaadin.terminal.gwt.client.ui.VUpload",
+ "com.vaadin.terminal.gwt.client.ui.VUriFragmentUtility",
+ "com.vaadin.terminal.gwt.client.ui.VVerticalLayout",
+ "com.vaadin.terminal.gwt.client.ui.VView",
+ "com.vaadin.terminal.gwt.client.ui.VWindow",
+ "com.vaadin.terminal.gwt.client.UIDL",
+ "com.vaadin.terminal.gwt.client.Util",
+ "com.vaadin.terminal.gwt.client.ValueMap",
+ "com.vaadin.terminal.gwt.client.VCaption",
+ "com.vaadin.terminal.gwt.client.VCaptionWrapper",
+ "com.vaadin.terminal.gwt.client.VDebugConsole",
+ "com.vaadin.terminal.gwt.client.VErrorMessage",
+ "com.vaadin.terminal.gwt.client.VTooltip",
+ "com.vaadin.terminal.gwt.client.VUIDLBrowser",
+ "com.vaadin.terminal.gwt.client.WidgetMap",
+ "com.vaadin.terminal.gwt.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/src/test/java/com/vaadin/data/util/AbstractHierarchicalContainerTestBase.java b/server/src/test/java/com/vaadin/data/util/AbstractHierarchicalContainerTestBase.java
new file mode 100644
index 0000000000..9cede77162
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/AbstractHierarchicalContainerTestBase.java
@@ -0,0 +1,285 @@
+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 AbstractHierarchicalContainerTestBase extends
+ AbstractContainerTestBase {
+
+ /**
+ * @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);
+ }
+ }
+
+ protected void testRemoveHierarchicalWrapperSubtree(
+ Container.Hierarchical container) {
+ initializeContainer(container);
+
+ // remove root item
+ removeItemRecursively(container, "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());
+ }
+
+ private void removeItemRecursively(Container.Hierarchical container,
+ Object itemId) {
+ if (container instanceof ContainerHierarchicalWrapper) {
+ ((ContainerHierarchicalWrapper) container)
+ .removeItemRecursively("org");
+ } else {
+ HierarchicalContainer.removeItemRecursively(container, itemId);
+ }
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/data/util/AbstractInMemoryContainerTestBase.java b/server/src/test/java/com/vaadin/data/util/AbstractInMemoryContainerTestBase.java
new file mode 100644
index 0000000000..d2c1a17bf8
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/AbstractInMemoryContainerTestBase.java
@@ -0,0 +1,6 @@
+package com.vaadin.data.util;
+
+public abstract class AbstractInMemoryContainerTestBase extends
+ AbstractContainerTestBase {
+
+}
diff --git a/server/src/test/java/com/vaadin/data/util/BeanContainerTest.java b/server/src/test/java/com/vaadin/data/util/BeanContainerTest.java
new file mode 100644
index 0000000000..3d755f4397
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/BeanContainerTest.java
@@ -0,0 +1,488 @@
+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 org.junit.Assert;
+
+import com.vaadin.data.Container;
+import com.vaadin.data.Item;
+import com.vaadin.data.util.AbstractBeanContainer.BeanIdResolver;
+
+public class BeanContainerTest extends AbstractBeanContainerTestBase {
+
+ 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 testGetType_existingProperty_typeReturned() {
+ BeanContainer<String, ClassName> container = getContainer();
+ Assert.assertEquals(
+ "Unexpected type is returned for property 'simpleName'",
+ String.class, container.getType("simpleName"));
+ }
+
+ public void testGetType_notExistingProperty_nullReturned() {
+ BeanContainer<String, ClassName> container = getContainer();
+ Assert.assertNull("Not null type is returned for property ''",
+ container.getType(""));
+ }
+
+ 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, AbstractBeanContainerTestBase.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());
+ }
+
+ public void testNestedContainerPropertyWithNullBean() {
+ BeanContainer<String, NestedMethodPropertyTest.Person> container = new BeanContainer<String, NestedMethodPropertyTest.Person>(
+ NestedMethodPropertyTest.Person.class);
+ container.setBeanIdProperty("name");
+
+ container.addBean(new NestedMethodPropertyTest.Person("John", null));
+ assertTrue(container
+ .addNestedContainerProperty("address.postalCodeObject"));
+ assertTrue(container.addNestedContainerProperty("address.street"));
+ // the nested properties added with allowNullBean setting should return
+ // null
+ assertNull(container.getContainerProperty("John", "address.street")
+ .getValue());
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/data/util/BeanItemContainerGenerator.java b/server/src/test/java/com/vaadin/data/util/BeanItemContainerGenerator.java
new file mode 100644
index 0000000000..a5bdcc7cf9
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/BeanItemContainerGenerator.java
@@ -0,0 +1,150 @@
+package com.vaadin.data.util;
+
+import java.util.Date;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class BeanItemContainerGenerator {
+
+ public static class PortableRandom {
+ private final static long multiplier = 0x5DEECE66DL;
+ private final static long addend = 0xBL;
+ private final static long mask = (1L << 48) - 1;
+ private AtomicLong seed;
+
+ public PortableRandom(long seed) {
+ this.seed = new AtomicLong(0L);
+ setSeed(seed);
+ }
+
+ synchronized public void setSeed(long seed) {
+ seed = (seed ^ multiplier) & mask;
+ this.seed.set(seed);
+ }
+
+ public int nextInt(int n) {
+ if (n <= 0) {
+ throw new IllegalArgumentException("n must be positive");
+ }
+
+ if ((n & -n) == n) {
+ return (int) ((n * (long) next(31)) >> 31);
+ }
+
+ int bits, val;
+ do {
+ bits = next(31);
+ val = bits % n;
+ } while (bits - val + (n - 1) < 0);
+ return val;
+ }
+
+ protected int next(int bits) {
+ long oldseed, nextseed;
+ AtomicLong seed = this.seed;
+ do {
+ oldseed = seed.get();
+ nextseed = (oldseed * multiplier + addend) & mask;
+ } while (!seed.compareAndSet(oldseed, nextseed));
+ return (int) (nextseed >>> (48 - bits));
+ }
+
+ public boolean nextBoolean() {
+ return next(1) != 0;
+ }
+
+ }
+
+ public static BeanItemContainer<TestBean> createContainer(int size) {
+ return createContainer(size, new Date().getTime());
+ }
+
+ public static BeanItemContainer<TestBean> createContainer(int size,
+ long seed) {
+
+ BeanItemContainer<TestBean> container = new BeanItemContainer<TestBean>(
+ TestBean.class);
+ PortableRandom r = new PortableRandom(seed);
+ for (int i = 0; i < size; i++) {
+ container.addBean(new TestBean(r));
+ }
+
+ return container;
+
+ }
+
+ public static class TestBean {
+ private String name, address, city, country;
+ private int age, shoesize;
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public int getShoesize() {
+ return shoesize;
+ }
+
+ public void setShoesize(int shoesize) {
+ this.shoesize = shoesize;
+ }
+
+ public TestBean(PortableRandom r) {
+ age = r.nextInt(100) + 5;
+ shoesize = r.nextInt(10) + 35;
+ name = createRandomString(r, r.nextInt(5) + 5);
+ address = createRandomString(r, r.nextInt(15) + 5) + " "
+ + r.nextInt(100) + 1;
+ city = createRandomString(r, r.nextInt(7) + 3);
+ if (r.nextBoolean()) {
+ country = createRandomString(r, r.nextInt(4) + 4);
+ }
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ public String getCountry() {
+ return country;
+ }
+
+ public void setCountry(String country) {
+ this.country = country;
+ }
+
+ }
+
+ public static String createRandomString(PortableRandom r, int len) {
+ StringBuilder b = new StringBuilder();
+ for (int i = 0; i < len; i++) {
+ b.append((char) (r.nextInt('z' - 'a') + 'a'));
+ }
+
+ return b.toString();
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/data/util/BeanItemContainerSortTest.java b/server/src/test/java/com/vaadin/data/util/BeanItemContainerSortTest.java
new file mode 100644
index 0000000000..4f4e35258f
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/BeanItemContainerSortTest.java
@@ -0,0 +1,166 @@
+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 org.junit.Assert;
+import org.junit.Test;
+
+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/src/test/java/com/vaadin/data/util/BeanItemContainerTest.java b/server/src/test/java/com/vaadin/data/util/BeanItemContainerTest.java
new file mode 100644
index 0000000000..3c30b41d39
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/BeanItemContainerTest.java
@@ -0,0 +1,969 @@
+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 org.easymock.Capture;
+import org.easymock.EasyMock;
+import org.junit.Assert;
+
+import com.vaadin.data.Container;
+import com.vaadin.data.Container.Indexed.ItemAddEvent;
+import com.vaadin.data.Container.Indexed.ItemRemoveEvent;
+import com.vaadin.data.Container.ItemSetChangeListener;
+import com.vaadin.data.Item;
+import com.vaadin.data.util.NestedMethodPropertyTest.Address;
+import com.vaadin.data.util.filter.Compare;
+
+/**
+ * Test basic functionality of BeanItemContainer.
+ *
+ * Most sorting related tests are in {@link BeanItemContainerSortTest}.
+ */
+public class BeanItemContainerTest extends AbstractBeanContainerTestBase {
+
+ // 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 testGetType_existingProperty_typeReturned() {
+ BeanItemContainer<ClassName> container = getContainer();
+ Assert.assertEquals(
+ "Unexpected type is returned for property 'simpleName'",
+ String.class, container.getType("simpleName"));
+ }
+
+ public void testGetType_notExistingProperty_nullReturned() {
+ BeanItemContainer<ClassName> container = getContainer();
+ Assert.assertNull("Not null type is returned for property ''",
+ container.getType(""));
+ }
+
+ 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());
+ }
+
+ public void testNestedContainerPropertyWithNullBean() {
+ BeanItemContainer<NestedMethodPropertyTest.Person> container = new BeanItemContainer<NestedMethodPropertyTest.Person>(
+ NestedMethodPropertyTest.Person.class);
+ NestedMethodPropertyTest.Person john = new NestedMethodPropertyTest.Person(
+ "John", null);
+ assertNotNull(container.addBean(john));
+ assertTrue(container
+ .addNestedContainerProperty("address.postalCodeObject"));
+ assertTrue(container.addNestedContainerProperty("address.street"));
+ // the nested properties should return null
+ assertNull(container.getContainerProperty(john, "address.street")
+ .getValue());
+ }
+
+ public void testItemAddedEvent() {
+ BeanItemContainer<Person> container = new BeanItemContainer<Person>(
+ Person.class);
+ Person bean = new Person("John");
+ ItemSetChangeListener addListener = createListenerMockFor(container);
+ addListener.containerItemSetChange(EasyMock.isA(ItemAddEvent.class));
+ EasyMock.replay(addListener);
+
+ container.addItem(bean);
+
+ EasyMock.verify(addListener);
+ }
+
+ public void testItemAddedEvent_AddedItem() {
+ BeanItemContainer<Person> container = new BeanItemContainer<Person>(
+ Person.class);
+ Person bean = new Person("John");
+ ItemSetChangeListener addListener = createListenerMockFor(container);
+ Capture<ItemAddEvent> capturedEvent = captureAddEvent(addListener);
+ EasyMock.replay(addListener);
+
+ container.addItem(bean);
+
+ assertEquals(bean, capturedEvent.getValue().getFirstItemId());
+ }
+
+ public void testItemAddedEvent_addItemAt_IndexOfAddedItem() {
+ BeanItemContainer<Person> container = new BeanItemContainer<Person>(
+ Person.class);
+ Person bean = new Person("John");
+ container.addItem(bean);
+ ItemSetChangeListener addListener = createListenerMockFor(container);
+ Capture<ItemAddEvent> capturedEvent = captureAddEvent(addListener);
+ EasyMock.replay(addListener);
+
+ container.addItemAt(1, new Person(""));
+
+ assertEquals(1, capturedEvent.getValue().getFirstIndex());
+ }
+
+ public void testItemAddedEvent_addItemAfter_IndexOfAddedItem() {
+ BeanItemContainer<Person> container = new BeanItemContainer<Person>(
+ Person.class);
+ Person bean = new Person("John");
+ container.addItem(bean);
+ ItemSetChangeListener addListener = createListenerMockFor(container);
+ Capture<ItemAddEvent> capturedEvent = captureAddEvent(addListener);
+ EasyMock.replay(addListener);
+
+ container.addItemAfter(bean, new Person(""));
+
+ assertEquals(1, capturedEvent.getValue().getFirstIndex());
+ }
+
+ public void testItemAddedEvent_amountOfAddedItems() {
+ BeanItemContainer<Person> container = new BeanItemContainer<Person>(
+ Person.class);
+ ItemSetChangeListener addListener = createListenerMockFor(container);
+ Capture<ItemAddEvent> capturedEvent = captureAddEvent(addListener);
+ EasyMock.replay(addListener);
+ List<Person> beans = Arrays.asList(new Person("Jack"), new Person(
+ "John"));
+
+ container.addAll(beans);
+
+ assertEquals(2, capturedEvent.getValue().getAddedItemsCount());
+ }
+
+ public void testItemAddedEvent_someItemsAreFiltered_amountOfAddedItemsIsReducedByAmountOfFilteredItems() {
+ BeanItemContainer<Person> container = new BeanItemContainer<Person>(
+ Person.class);
+ ItemSetChangeListener addListener = createListenerMockFor(container);
+ Capture<ItemAddEvent> capturedEvent = captureAddEvent(addListener);
+ EasyMock.replay(addListener);
+ List<Person> beans = Arrays.asList(new Person("Jack"), new Person(
+ "John"));
+ container.addFilter(new Compare.Equal("name", "John"));
+
+ container.addAll(beans);
+
+ assertEquals(1, capturedEvent.getValue().getAddedItemsCount());
+ }
+
+ public void testItemAddedEvent_someItemsAreFiltered_addedItemIsTheFirstVisibleItem() {
+ BeanItemContainer<Person> container = new BeanItemContainer<Person>(
+ Person.class);
+ Person bean = new Person("John");
+ ItemSetChangeListener addListener = createListenerMockFor(container);
+ Capture<ItemAddEvent> capturedEvent = captureAddEvent(addListener);
+ EasyMock.replay(addListener);
+ List<Person> beans = Arrays.asList(new Person("Jack"), bean);
+ container.addFilter(new Compare.Equal("name", "John"));
+
+ container.addAll(beans);
+
+ assertEquals(bean, capturedEvent.getValue().getFirstItemId());
+ }
+
+ public void testItemRemovedEvent() {
+ BeanItemContainer<Person> container = new BeanItemContainer<Person>(
+ Person.class);
+ Person bean = new Person("John");
+ container.addItem(bean);
+ ItemSetChangeListener removeListener = createListenerMockFor(container);
+ removeListener.containerItemSetChange(EasyMock
+ .isA(ItemRemoveEvent.class));
+ EasyMock.replay(removeListener);
+
+ container.removeItem(bean);
+
+ EasyMock.verify(removeListener);
+ }
+
+ public void testItemRemovedEvent_RemovedItem() {
+ BeanItemContainer<Person> container = new BeanItemContainer<Person>(
+ Person.class);
+ Person bean = new Person("John");
+ container.addItem(bean);
+ ItemSetChangeListener removeListener = createListenerMockFor(container);
+ Capture<ItemRemoveEvent> capturedEvent = captureRemoveEvent(removeListener);
+ EasyMock.replay(removeListener);
+
+ container.removeItem(bean);
+
+ assertEquals(bean, capturedEvent.getValue().getFirstItemId());
+ }
+
+ public void testItemRemovedEvent_indexOfRemovedItem() {
+ BeanItemContainer<Person> container = new BeanItemContainer<Person>(
+ Person.class);
+ container.addItem(new Person("Jack"));
+ Person secondBean = new Person("John");
+ container.addItem(secondBean);
+ ItemSetChangeListener removeListener = createListenerMockFor(container);
+ Capture<ItemRemoveEvent> capturedEvent = captureRemoveEvent(removeListener);
+ EasyMock.replay(removeListener);
+
+ container.removeItem(secondBean);
+
+ assertEquals(1, capturedEvent.getValue().getFirstIndex());
+ }
+
+ public void testItemRemovedEvent_amountOfRemovedItems() {
+ BeanItemContainer<Person> container = new BeanItemContainer<Person>(
+ Person.class);
+ container.addItem(new Person("Jack"));
+ container.addItem(new Person("John"));
+ ItemSetChangeListener removeListener = createListenerMockFor(container);
+ Capture<ItemRemoveEvent> capturedEvent = captureRemoveEvent(removeListener);
+ EasyMock.replay(removeListener);
+
+ container.removeAllItems();
+
+ assertEquals(2, capturedEvent.getValue().getRemovedItemsCount());
+ }
+
+ private Capture<ItemAddEvent> captureAddEvent(
+ ItemSetChangeListener addListener) {
+ Capture<ItemAddEvent> capturedEvent = new Capture<ItemAddEvent>();
+ addListener.containerItemSetChange(EasyMock.capture(capturedEvent));
+ return capturedEvent;
+ }
+
+ private Capture<ItemRemoveEvent> captureRemoveEvent(
+ ItemSetChangeListener removeListener) {
+ Capture<ItemRemoveEvent> capturedEvent = new Capture<ItemRemoveEvent>();
+ removeListener.containerItemSetChange(EasyMock.capture(capturedEvent));
+ return capturedEvent;
+ }
+
+ private ItemSetChangeListener createListenerMockFor(
+ BeanItemContainer<Person> container) {
+ ItemSetChangeListener listener = EasyMock
+ .createNiceMock(ItemSetChangeListener.class);
+ container.addItemSetChangeListener(listener);
+ return listener;
+ }
+
+ public void testAddNestedContainerBeanBeforeData() {
+ BeanItemContainer<NestedMethodPropertyTest.Person> container = new BeanItemContainer<NestedMethodPropertyTest.Person>(
+ NestedMethodPropertyTest.Person.class);
+
+ container.addNestedContainerBean("address");
+
+ assertTrue(container.getContainerPropertyIds().contains(
+ "address.street"));
+
+ NestedMethodPropertyTest.Person john = new NestedMethodPropertyTest.Person(
+ "John", new Address("streetname", 12345));
+ container.addBean(john);
+
+ assertTrue(container.getItem(john).getItemPropertyIds()
+ .contains("address.street"));
+ assertEquals("streetname",
+ container.getItem(john).getItemProperty("address.street")
+ .getValue());
+
+ }
+
+ public void testAddNestedContainerBeanAfterData() {
+ BeanItemContainer<NestedMethodPropertyTest.Person> container = new BeanItemContainer<NestedMethodPropertyTest.Person>(
+ NestedMethodPropertyTest.Person.class);
+
+ NestedMethodPropertyTest.Person john = new NestedMethodPropertyTest.Person(
+ "John", new Address("streetname", 12345));
+ container.addBean(john);
+
+ container.addNestedContainerBean("address");
+
+ assertTrue(container.getContainerPropertyIds().contains(
+ "address.street"));
+ assertTrue(container.getItem(john).getItemPropertyIds()
+ .contains("address.street"));
+ assertEquals("streetname",
+ container.getItem(john).getItemProperty("address.street")
+ .getValue());
+
+ }
+}
diff --git a/server/src/test/java/com/vaadin/data/util/BeanItemTest.java b/server/src/test/java/com/vaadin/data/util/BeanItemTest.java
new file mode 100644
index 0000000000..89c56b1779
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/BeanItemTest.java
@@ -0,0 +1,375 @@
+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.TestCase;
+
+import org.junit.Assert;
+
+import com.vaadin.data.Property;
+
+/**
+ * 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 class Generic<T> {
+
+ public T getProperty() {
+ return null;
+ }
+
+ public void setProperty(T t) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ protected static class SubClass extends Generic<String> {
+
+ @Override
+ // Has a bridged method
+ public String getProperty() {
+ return "";
+ }
+
+ @Override
+ // Has a bridged method
+ public void setProperty(String t) {
+ }
+ }
+
+ 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"));
+ }
+
+ public void testOverridenGenericMethods() {
+ BeanItem<SubClass> item = new BeanItem<SubClass>(new SubClass());
+
+ Property<?> property = item.getItemProperty("property");
+ Assert.assertEquals("Unexpected class for property type", String.class,
+ property.getType());
+
+ Assert.assertEquals("Unexpected property value", "",
+ property.getValue());
+
+ // Should not be exception
+ property.setValue(null);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/data/util/ContainerHierarchicalWrapperTest.java b/server/src/test/java/com/vaadin/data/util/ContainerHierarchicalWrapperTest.java
new file mode 100644
index 0000000000..8e554d5030
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/ContainerHierarchicalWrapperTest.java
@@ -0,0 +1,22 @@
+package com.vaadin.data.util;
+
+
+public class ContainerHierarchicalWrapperTest extends
+ AbstractHierarchicalContainerTestBase {
+
+ public void testBasicOperations() {
+ testBasicContainerOperations(new ContainerHierarchicalWrapper(
+ new IndexedContainer()));
+ }
+
+ public void testHierarchicalContainer() {
+ testHierarchicalContainer(new ContainerHierarchicalWrapper(
+ new IndexedContainer()));
+ }
+
+ public void testRemoveSubtree() {
+ testRemoveHierarchicalWrapperSubtree(new ContainerHierarchicalWrapper(
+ new IndexedContainer()));
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/data/util/ContainerOrderedWrapperTest.java b/server/src/test/java/com/vaadin/data/util/ContainerOrderedWrapperTest.java
new file mode 100644
index 0000000000..422e9756f8
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/ContainerOrderedWrapperTest.java
@@ -0,0 +1,102 @@
+package com.vaadin.data.util;
+
+import java.util.Collection;
+
+import com.vaadin.data.Container;
+import com.vaadin.data.Item;
+import com.vaadin.data.Property;
+
+public class ContainerOrderedWrapperTest extends AbstractContainerTestBase {
+
+ // This class is needed to get an implementation of container
+ // which is not an implementation of Ordered interface.
+ private class NotOrderedContainer implements Container {
+
+ private IndexedContainer container;
+
+ public NotOrderedContainer() {
+ container = new IndexedContainer();
+ }
+
+ @Override
+ public Item getItem(Object itemId) {
+ return container.getItem(itemId);
+ }
+
+ @Override
+ public Collection<?> getContainerPropertyIds() {
+ return container.getContainerPropertyIds();
+ }
+
+ @Override
+ public Collection<?> getItemIds() {
+ return container.getItemIds();
+ }
+
+ @Override
+ public Property getContainerProperty(Object itemId, Object propertyId) {
+ return container.getContainerProperty(itemId, propertyId);
+ }
+
+ @Override
+ public Class<?> getType(Object propertyId) {
+ return container.getType(propertyId);
+ }
+
+ @Override
+ public int size() {
+ return container.size();
+ }
+
+ @Override
+ public boolean containsId(Object itemId) {
+ return container.containsId(itemId);
+ }
+
+ @Override
+ public Item addItem(Object itemId) throws UnsupportedOperationException {
+ return container.addItem(itemId);
+ }
+
+ @Override
+ public Object addItem() throws UnsupportedOperationException {
+ return container.addItem();
+ }
+
+ @Override
+ public boolean removeItem(Object itemId)
+ throws UnsupportedOperationException {
+ return container.removeItem(itemId);
+ }
+
+ @Override
+ public boolean addContainerProperty(Object propertyId, Class<?> type,
+ Object defaultValue) throws UnsupportedOperationException {
+ return container.addContainerProperty(propertyId, type,
+ defaultValue);
+ }
+
+ @Override
+ public boolean removeContainerProperty(Object propertyId)
+ throws UnsupportedOperationException {
+ return container.removeContainerProperty(propertyId);
+ }
+
+ @Override
+ public boolean removeAllItems() throws UnsupportedOperationException {
+ return container.removeAllItems();
+ }
+
+ }
+
+ public void testBasicOperations() {
+ testBasicContainerOperations(new ContainerOrderedWrapper(
+ new NotOrderedContainer()));
+ }
+
+ public void testOrdered() {
+ testContainerOrdered(new ContainerOrderedWrapper(
+ new NotOrderedContainer()));
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/data/util/ContainerSizeAssertTest.java b/server/src/test/java/com/vaadin/data/util/ContainerSizeAssertTest.java
new file mode 100644
index 0000000000..04fd8d3cd1
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/ContainerSizeAssertTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.data.util;
+
+import org.junit.Test;
+
+import com.vaadin.data.Container;
+import com.vaadin.ui.Table;
+
+public class ContainerSizeAssertTest {
+
+ @Test(expected = AssertionError.class)
+ public void testNegativeSizeAssert() {
+ Table table = createAttachedTable();
+
+ table.setContainerDataSource(createNegativeSizeContainer());
+ }
+
+ @Test
+ public void testZeroSizeNoAssert() {
+ Table table = createAttachedTable();
+
+ table.setContainerDataSource(new IndexedContainer());
+ }
+
+ private Container createNegativeSizeContainer() {
+ return new IndexedContainer() {
+ @Override
+ public int size() {
+ return -1;
+ }
+ };
+ }
+
+ private Table createAttachedTable() {
+ return new Table() {
+ private boolean initialized = true;
+
+ @Override
+ public boolean isAttached() {
+ // This returns false until the super constructor has finished
+ return initialized;
+ }
+ };
+ }
+}
diff --git a/server/src/test/java/com/vaadin/data/util/ContainerSortingTest.java b/server/src/test/java/com/vaadin/data/util/ContainerSortingTest.java
new file mode 100644
index 0000000000..dd713dd7b0
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/ContainerSortingTest.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 ContainerSortingTest 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/src/test/java/com/vaadin/data/util/FileSystemContainerTest.java b/server/src/test/java/com/vaadin/data/util/FileSystemContainerTest.java
new file mode 100644
index 0000000000..f4bb794e5c
--- /dev/null
+++ b/server/src/test/java/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/src/test/java/com/vaadin/data/util/GeneratedPropertyContainerBasicTest.java b/server/src/test/java/com/vaadin/data/util/GeneratedPropertyContainerBasicTest.java
new file mode 100644
index 0000000000..90ec893f4d
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/GeneratedPropertyContainerBasicTest.java
@@ -0,0 +1,561 @@
+package com.vaadin.data.util;
+
+import java.util.List;
+
+import org.easymock.Capture;
+import org.easymock.EasyMock;
+import org.junit.Assert;
+
+import com.vaadin.data.Container;
+import com.vaadin.data.Container.Indexed.ItemAddEvent;
+import com.vaadin.data.Container.Indexed.ItemRemoveEvent;
+import com.vaadin.data.Container.ItemSetChangeListener;
+import com.vaadin.data.Container.ItemSetChangeNotifier;
+import com.vaadin.data.Item;
+import com.vaadin.data.util.filter.SimpleStringFilter;
+
+public class GeneratedPropertyContainerBasicTest extends
+ AbstractInMemoryContainerTestBase {
+
+ public void testBasicOperations() {
+ testBasicContainerOperations(createContainer());
+ }
+
+ private GeneratedPropertyContainer createContainer() {
+ return new GeneratedPropertyContainer(new IndexedContainer());
+ }
+
+ public void testFiltering() {
+ testContainerFiltering(createContainer());
+ }
+
+ public void testSorting() {
+ testContainerSorting(createContainer());
+ }
+
+ public void testSortingAndFiltering() {
+ testContainerSortingAndFiltering(createContainer());
+ }
+
+ public void testContainerOrdered() {
+ testContainerOrdered(createContainer());
+ }
+
+ public void testContainerIndexed() {
+ testContainerIndexed(createContainer(), sampleData[2], 2, true,
+ "newItemId", true);
+ }
+
+ public void testItemSetChangeListeners() {
+ GeneratedPropertyContainer container = createContainer();
+ 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() {
+ GeneratedPropertyContainer container = createContainer();
+ ItemSetChangeCounter counter = new ItemSetChangeCounter();
+ container.addListener(counter);
+
+ // simply adding or removing container filters should cause events
+ // (content changes)
+
+ initializeContainer(container);
+ counter.reset();
+ SimpleStringFilter filter = new SimpleStringFilter(SIMPLE_NAME, "a",
+ true, false);
+ container.addContainerFilter(filter);
+ counter.assertOnce();
+ container.removeContainerFilter(filter);
+ counter.assertOnce();
+ container.addContainerFilter(new SimpleStringFilter(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() {
+ Container.Indexed container = createContainer();
+ ItemSetChangeCounter counter = new ItemSetChangeCounter();
+ ((GeneratedPropertyContainer) container).addListener(counter);
+
+ counter.reset();
+ ((Container.Filterable) container)
+ .addContainerFilter(new SimpleStringFilter(
+ 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();
+ }
+
+ public void testItemAdd_idSequence() {
+ GeneratedPropertyContainer container = createContainer();
+ Object itemId;
+
+ itemId = container.addItem();
+ assertEquals(Integer.valueOf(1), itemId);
+
+ itemId = container.addItem();
+ assertEquals(Integer.valueOf(2), itemId);
+
+ itemId = container.addItemAfter(null);
+ assertEquals(Integer.valueOf(3), itemId);
+
+ itemId = container.addItemAt(2);
+ assertEquals(Integer.valueOf(4), itemId);
+ }
+
+ public void testItemAddRemove_idSequence() {
+ GeneratedPropertyContainer container = createContainer();
+ Object itemId;
+
+ itemId = container.addItem();
+ assertEquals(Integer.valueOf(1), itemId);
+
+ container.removeItem(itemId);
+
+ itemId = container.addItem();
+ assertEquals(
+ "Id sequence should continue from the previous value even if an item is removed",
+ Integer.valueOf(2), itemId);
+ }
+
+ public void testItemAddedEvent() {
+ GeneratedPropertyContainer container = createContainer();
+ ItemSetChangeListener addListener = createListenerMockFor(container);
+ addListener.containerItemSetChange(EasyMock.isA(ItemAddEvent.class));
+ EasyMock.replay(addListener);
+
+ container.addItem();
+
+ EasyMock.verify(addListener);
+ }
+
+ public void testItemAddedEvent_AddedItem() {
+ GeneratedPropertyContainer container = createContainer();
+ ItemSetChangeListener addListener = createListenerMockFor(container);
+ Capture<ItemAddEvent> capturedEvent = captureAddEvent(addListener);
+ EasyMock.replay(addListener);
+
+ Object itemId = container.addItem();
+
+ assertEquals(itemId, capturedEvent.getValue().getFirstItemId());
+ }
+
+ public void testItemAddedEvent_IndexOfAddedItem() {
+ GeneratedPropertyContainer container = createContainer();
+ ItemSetChangeListener addListener = createListenerMockFor(container);
+ container.addItem();
+ Capture<ItemAddEvent> capturedEvent = captureAddEvent(addListener);
+ EasyMock.replay(addListener);
+
+ Object itemId = container.addItemAt(1);
+
+ assertEquals(1, capturedEvent.getValue().getFirstIndex());
+ }
+
+ public void testItemRemovedEvent() {
+ GeneratedPropertyContainer container = createContainer();
+ Object itemId = container.addItem();
+ ItemSetChangeListener removeListener = createListenerMockFor(container);
+ removeListener.containerItemSetChange(EasyMock
+ .isA(ItemRemoveEvent.class));
+ EasyMock.replay(removeListener);
+
+ container.removeItem(itemId);
+
+ EasyMock.verify(removeListener);
+ }
+
+ public void testItemRemovedEvent_RemovedItem() {
+ GeneratedPropertyContainer container = createContainer();
+ Object itemId = container.addItem();
+ ItemSetChangeListener removeListener = createListenerMockFor(container);
+ Capture<ItemRemoveEvent> capturedEvent = captureRemoveEvent(removeListener);
+ EasyMock.replay(removeListener);
+
+ container.removeItem(itemId);
+
+ assertEquals(itemId, capturedEvent.getValue().getFirstItemId());
+ }
+
+ public void testItemRemovedEvent_indexOfRemovedItem() {
+ GeneratedPropertyContainer container = createContainer();
+ container.addItem();
+ Object secondItemId = container.addItem();
+ ItemSetChangeListener removeListener = createListenerMockFor(container);
+ Capture<ItemRemoveEvent> capturedEvent = captureRemoveEvent(removeListener);
+ EasyMock.replay(removeListener);
+
+ container.removeItem(secondItemId);
+
+ assertEquals(1, capturedEvent.getValue().getFirstIndex());
+ }
+
+ public void testItemRemovedEvent_amountOfRemovedItems() {
+ GeneratedPropertyContainer container = createContainer();
+ container.addItem();
+ container.addItem();
+ ItemSetChangeListener removeListener = createListenerMockFor(container);
+ Capture<ItemRemoveEvent> capturedEvent = captureRemoveEvent(removeListener);
+ EasyMock.replay(removeListener);
+
+ container.removeAllItems();
+
+ assertEquals(2, capturedEvent.getValue().getRemovedItemsCount());
+ }
+
+ private Capture<ItemAddEvent> captureAddEvent(
+ ItemSetChangeListener addListener) {
+ Capture<ItemAddEvent> capturedEvent = new Capture<ItemAddEvent>();
+ addListener.containerItemSetChange(EasyMock.capture(capturedEvent));
+ return capturedEvent;
+ }
+
+ private Capture<ItemRemoveEvent> captureRemoveEvent(
+ ItemSetChangeListener removeListener) {
+ Capture<ItemRemoveEvent> capturedEvent = new Capture<ItemRemoveEvent>();
+ removeListener.containerItemSetChange(EasyMock.capture(capturedEvent));
+ return capturedEvent;
+ }
+
+ private ItemSetChangeListener createListenerMockFor(
+ ItemSetChangeNotifier container) {
+ ItemSetChangeListener listener = EasyMock
+ .createNiceMock(ItemSetChangeListener.class);
+ container.addItemSetChangeListener(listener);
+ return listener;
+ }
+
+ // Ticket 8028
+ public void testGetItemIdsRangeIndexOutOfBounds() {
+ GeneratedPropertyContainer ic = createContainer();
+ try {
+ ic.getItemIds(-1, 10);
+ fail("Container returned items starting from index -1, something very wrong here!");
+ } catch (IndexOutOfBoundsException e) {
+ // This is expected...
+ } catch (Exception e) {
+ // Should not happen!
+ fail("Container threw unspecified exception when fetching a range of items and the range started from -1");
+ }
+
+ }
+
+ // Ticket 8028
+ public void testGetItemIdsRangeIndexOutOfBounds2() {
+ GeneratedPropertyContainer ic = createContainer();
+ ic.addItem(new Object());
+ try {
+ ic.getItemIds(2, 1);
+ fail("Container returned items starting from index -1, something very wrong here!");
+ } catch (IndexOutOfBoundsException e) {
+ // This is expected...
+ } catch (Exception e) {
+ // Should not happen!
+ fail("Container threw unspecified exception when fetching a out of bounds range of items");
+ }
+
+ }
+
+ // Ticket 8028
+ public void testGetItemIdsRangeZeroRange() {
+ GeneratedPropertyContainer ic = createContainer();
+ ic.addItem(new Object());
+ try {
+ List<Object> itemIds = (List<Object>) ic.getItemIds(1, 0);
+
+ assertTrue(
+ "Container returned actual values when asking for 0 items...",
+ itemIds.isEmpty());
+ } catch (Exception e) {
+ // Should not happen!
+ fail("Container threw unspecified exception when fetching 0 items...");
+ }
+
+ }
+
+ // Ticket 8028
+ public void testGetItemIdsRangeNegativeRange() {
+ GeneratedPropertyContainer ic = createContainer();
+ ic.addItem(new Object());
+ try {
+ List<Object> itemIds = (List<Object>) ic.getItemIds(1, -1);
+
+ assertTrue(
+ "Container returned actual values when asking for -1 items...",
+ itemIds.isEmpty());
+ } catch (IllegalArgumentException e) {
+ // this is expected
+
+ } catch (Exception e) {
+ // Should not happen!
+ fail("Container threw unspecified exception when fetching -1 items...");
+ }
+
+ }
+
+ // Ticket 8028
+ public void testGetItemIdsRangeIndexOutOfBoundsDueToSizeChange() {
+ GeneratedPropertyContainer ic = createContainer();
+ ic.addItem(new Object());
+ Assert.assertEquals(
+ "Container returned too many items when the range was >> container size",
+ 1, ic.getItemIds(0, 10).size());
+ }
+
+ // Ticket 8028
+ public void testGetItemIdsRangeBaseCase() {
+ GeneratedPropertyContainer ic = createContainer();
+ String object1 = new String("Obj1");
+ String object2 = new String("Obj2");
+ String object3 = new String("Obj3");
+ String object4 = new String("Obj4");
+ String object5 = new String("Obj5");
+
+ ic.addItem(object1);
+ ic.addItem(object2);
+ ic.addItem(object3);
+ ic.addItem(object4);
+ ic.addItem(object5);
+
+ try {
+ List<Object> itemIds = (List<Object>) ic.getItemIds(1, 2);
+
+ assertTrue(itemIds.contains(object2));
+ assertTrue(itemIds.contains(object3));
+ assertEquals(2, itemIds.size());
+
+ } catch (Exception e) {
+ // Should not happen!
+ fail("Container threw exception when fetching a range of items ");
+ }
+ }
+
+ // test getting non-existing property (#10445)
+ public void testNonExistingProperty() {
+ Container ic = createContainer();
+ String object1 = new String("Obj1");
+ ic.addItem(object1);
+ assertNull(ic.getContainerProperty(object1, "xyz"));
+ }
+
+ // test getting null property id (#10445)
+ public void testNullPropertyId() {
+ Container ic = createContainer();
+ String object1 = new String("Obj1");
+ ic.addItem(object1);
+ assertNull(ic.getContainerProperty(object1, null));
+ }
+
+ @Override
+ protected void initializeContainer(Container container) {
+ if (container instanceof GeneratedPropertyContainer) {
+ super.initializeContainer(((GeneratedPropertyContainer) container)
+ .getWrappedContainer());
+ } else {
+ super.initializeContainer(container);
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/data/util/GeneratedPropertyContainerTest.java b/server/src/test/java/com/vaadin/data/util/GeneratedPropertyContainerTest.java
new file mode 100644
index 0000000000..bfa77eab52
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/GeneratedPropertyContainerTest.java
@@ -0,0 +1,306 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.data.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.Container.Filter;
+import com.vaadin.data.Container.Indexed;
+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.Item;
+import com.vaadin.data.sort.SortOrder;
+import com.vaadin.data.util.filter.Compare;
+import com.vaadin.data.util.filter.UnsupportedFilterException;
+
+public class GeneratedPropertyContainerTest {
+
+ GeneratedPropertyContainer container;
+ Indexed wrappedContainer;
+ private static double MILES_CONVERSION = 0.6214d;
+
+ private class GeneratedPropertyListener implements
+ PropertySetChangeListener {
+
+ private int callCount = 0;
+
+ public int getCallCount() {
+ return callCount;
+ }
+
+ @Override
+ public void containerPropertySetChange(PropertySetChangeEvent event) {
+ ++callCount;
+ assertEquals(
+ "Container for event was not GeneratedPropertyContainer",
+ event.getContainer(), container);
+ }
+ }
+
+ private class GeneratedItemSetListener implements ItemSetChangeListener {
+
+ private int callCount = 0;
+
+ public int getCallCount() {
+ return callCount;
+ }
+
+ @Override
+ public void containerItemSetChange(ItemSetChangeEvent event) {
+ ++callCount;
+ assertEquals(
+ "Container for event was not GeneratedPropertyContainer",
+ event.getContainer(), container);
+ }
+ }
+
+ @Before
+ public void setUp() {
+ container = new GeneratedPropertyContainer(createContainer());
+ }
+
+ @Test
+ public void testSimpleGeneratedProperty() {
+ container.addGeneratedProperty("hello",
+ new PropertyValueGenerator<String>() {
+
+ @Override
+ public String getValue(Item item, Object itemId,
+ Object propertyId) {
+ return "Hello World!";
+ }
+
+ @Override
+ public Class<String> getType() {
+ return String.class;
+ }
+ });
+
+ Object itemId = container.addItem();
+ assertEquals("Expected value not in item.", container.getItem(itemId)
+ .getItemProperty("hello").getValue(), "Hello World!");
+ }
+
+ @Test
+ public void testSortableProperties() {
+ container.addGeneratedProperty("baz",
+ new PropertyValueGenerator<String>() {
+
+ @Override
+ public String getValue(Item item, Object itemId,
+ Object propertyId) {
+ return item.getItemProperty("foo").getValue() + " "
+ + item.getItemProperty("bar").getValue();
+ }
+
+ @Override
+ public Class<String> getType() {
+ return String.class;
+ }
+
+ @Override
+ public SortOrder[] getSortProperties(SortOrder order) {
+ SortOrder[] sortOrder = new SortOrder[1];
+ sortOrder[0] = new SortOrder("bar", order
+ .getDirection());
+ return sortOrder;
+ }
+ });
+
+ container.sort(new Object[] { "baz" }, new boolean[] { true });
+ assertEquals("foo 0", container.getItem(container.getIdByIndex(0))
+ .getItemProperty("baz").getValue());
+
+ container.sort(new Object[] { "baz" }, new boolean[] { false });
+ assertEquals("foo 10", container.getItem(container.getIdByIndex(0))
+ .getItemProperty("baz").getValue());
+ }
+
+ @Test
+ public void testOverrideSortableProperties() {
+
+ assertTrue(container.getSortableContainerPropertyIds().contains("bar"));
+
+ container.addGeneratedProperty("bar",
+ new PropertyValueGenerator<String>() {
+
+ @Override
+ public String getValue(Item item, Object itemId,
+ Object propertyId) {
+ return item.getItemProperty("foo").getValue() + " "
+ + item.getItemProperty("bar").getValue();
+ }
+
+ @Override
+ public Class<String> getType() {
+ return String.class;
+ }
+ });
+
+ assertFalse(container.getSortableContainerPropertyIds().contains("bar"));
+ }
+
+ @Test
+ public void testFilterByMiles() {
+ container.addGeneratedProperty("miles",
+ new PropertyValueGenerator<Double>() {
+
+ @Override
+ public Double getValue(Item item, Object itemId,
+ Object propertyId) {
+ return (Double) item.getItemProperty("km").getValue()
+ * MILES_CONVERSION;
+ }
+
+ @Override
+ public Class<Double> getType() {
+ return Double.class;
+ }
+
+ @Override
+ public Filter modifyFilter(Filter filter)
+ throws UnsupportedFilterException {
+ if (filter instanceof Compare.LessOrEqual) {
+ Double value = (Double) ((Compare.LessOrEqual) filter)
+ .getValue();
+ value = value / MILES_CONVERSION;
+ return new Compare.LessOrEqual("km", value);
+ }
+ return super.modifyFilter(filter);
+ }
+ });
+
+ for (Object itemId : container.getItemIds()) {
+ Item item = container.getItem(itemId);
+ Double km = (Double) item.getItemProperty("km").getValue();
+ Double miles = (Double) item.getItemProperty("miles").getValue();
+ assertTrue(miles.equals(km * MILES_CONVERSION));
+ }
+
+ Filter filter = new Compare.LessOrEqual("miles", MILES_CONVERSION);
+ container.addContainerFilter(filter);
+ for (Object itemId : container.getItemIds()) {
+ Item item = container.getItem(itemId);
+ assertTrue("Item did not pass original filter.",
+ filter.passesFilter(itemId, item));
+ }
+
+ assertTrue(container.getContainerFilters().contains(filter));
+ container.removeContainerFilter(filter);
+ assertFalse(container.getContainerFilters().contains(filter));
+
+ boolean allPass = true;
+ for (Object itemId : container.getItemIds()) {
+ Item item = container.getItem(itemId);
+ if (!filter.passesFilter(itemId, item)) {
+ allPass = false;
+ }
+ }
+
+ if (allPass) {
+ fail("Removing filter did not introduce any previous filtered items");
+ }
+ }
+
+ @Test
+ public void testPropertySetChangeNotifier() {
+ GeneratedPropertyListener listener = new GeneratedPropertyListener();
+ GeneratedPropertyListener removedListener = new GeneratedPropertyListener();
+ container.addPropertySetChangeListener(listener);
+ container.addPropertySetChangeListener(removedListener);
+
+ container.addGeneratedProperty("foo",
+ new PropertyValueGenerator<String>() {
+
+ @Override
+ public String getValue(Item item, Object itemId,
+ Object propertyId) {
+ return "";
+ }
+
+ @Override
+ public Class<String> getType() {
+ return String.class;
+ }
+ });
+
+ // Adding property to wrapped container should cause an event
+ wrappedContainer.addContainerProperty("baz", String.class, "");
+ container.removePropertySetChangeListener(removedListener);
+ container.removeGeneratedProperty("foo");
+
+ assertEquals("Listener was not called correctly.", 3,
+ listener.getCallCount());
+ assertEquals("Removed listener was not called correctly.", 2,
+ removedListener.getCallCount());
+ }
+
+ @Test
+ public void testItemSetChangeNotifier() {
+ GeneratedItemSetListener listener = new GeneratedItemSetListener();
+ container.addItemSetChangeListener(listener);
+
+ container.sort(new Object[] { "foo" }, new boolean[] { true });
+ container.sort(new Object[] { "foo" }, new boolean[] { false });
+
+ assertEquals("Listener was not called correctly.", 2,
+ listener.getCallCount());
+
+ }
+
+ @Test
+ public void testRemoveProperty() {
+ container.removeContainerProperty("foo");
+ assertFalse("Container contained removed property", container
+ .getContainerPropertyIds().contains("foo"));
+ assertTrue("Wrapped container did not contain removed property",
+ wrappedContainer.getContainerPropertyIds().contains("foo"));
+
+ assertFalse(container.getItem(container.firstItemId())
+ .getItemPropertyIds().contains("foo"));
+
+ container.addContainerProperty("foo", null, null);
+ assertTrue("Container did not contain returned property", container
+ .getContainerPropertyIds().contains("foo"));
+ }
+
+ private Indexed createContainer() {
+ wrappedContainer = new IndexedContainer();
+ wrappedContainer.addContainerProperty("foo", String.class, "foo");
+ wrappedContainer.addContainerProperty("bar", Integer.class, 0);
+ // km contains double values from 0.0 to 2.0
+ wrappedContainer.addContainerProperty("km", Double.class, 0);
+
+ for (int i = 0; i <= 10; ++i) {
+ Object itemId = wrappedContainer.addItem();
+ Item item = wrappedContainer.getItem(itemId);
+ item.getItemProperty("foo").setValue("foo");
+ item.getItemProperty("bar").setValue(i);
+ item.getItemProperty("km").setValue(i / 5.0d);
+ }
+
+ return wrappedContainer;
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/data/util/HierarchicalContainerOrderedWrapperTest.java b/server/src/test/java/com/vaadin/data/util/HierarchicalContainerOrderedWrapperTest.java
new file mode 100644
index 0000000000..7ecf59c309
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/HierarchicalContainerOrderedWrapperTest.java
@@ -0,0 +1,27 @@
+package com.vaadin.data.util;
+
+public class HierarchicalContainerOrderedWrapperTest extends
+ AbstractHierarchicalContainerTestBase {
+
+ private HierarchicalContainerOrderedWrapper createContainer() {
+ return new HierarchicalContainerOrderedWrapper(
+ new ContainerHierarchicalWrapper(new IndexedContainer()));
+ }
+
+ public void testBasicOperations() {
+ testBasicContainerOperations(createContainer());
+ }
+
+ public void testHierarchicalContainer() {
+ testHierarchicalContainer(createContainer());
+ }
+
+ public void testContainerOrdered() {
+ testContainerOrdered(createContainer());
+ }
+
+ public void testRemoveSubtree() {
+ testRemoveHierarchicalWrapperSubtree(createContainer());
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/data/util/HierarchicalContainerTest.java b/server/src/test/java/com/vaadin/data/util/HierarchicalContainerTest.java
new file mode 100644
index 0000000000..0b71b3dff9
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/HierarchicalContainerTest.java
@@ -0,0 +1,270 @@
+package com.vaadin.data.util;
+
+import com.vaadin.data.Container.Filter;
+import com.vaadin.data.Item;
+
+public class HierarchicalContainerTest extends
+ AbstractHierarchicalContainerTestBase {
+
+ 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.terminal.gwt.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.terminal.gwt.client.ui.VPopupCalendar");
+ assertNull(p1);
+ container.removeAllContainerFilters();
+ p1 = container
+ .getParent("com.vaadin.terminal.gwt.client.ui.VPopupCalendar");
+ assertEquals("com.vaadin.terminal.gwt.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.terminal.gwt.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.terminal.gwt.client.WidgetSet",
+ "com.vaadin.terminal.gwt.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.terminal.gwt.client.ui.VUriFragmentUtility",
+ "com.vaadin.terminal.gwt.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.terminal.gwt.client.Focusable
+ // com.vaadin.terminal.gwt.client.Paintable
+ // com.vaadin.terminal.gwt.client.ui.Table
+ // com.vaadin.terminal.gwt.client.ui.VLabel
+ // com.vaadin.terminal.gwt.client.ui.VScrollTable
+ // com.vaadin.terminal.gwt.client.ui.VTablePaging
+ // com.vaadin.terminal.gwt.client.ui.VTabsheet
+ // com.vaadin.terminal.gwt.client.ui.VTabsheetBase
+ // com.vaadin.terminal.gwt.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.terminal.gwt.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.terminal.gwt.client.ui +
+ // com.vaadin.terminal.gwt.client.*
+
+ // Sorting is case insensitive
+ validateHierarchicalContainer(container,
+ "com.vaadin.terminal.gwt.client.ApplicationConfiguration",
+ "com.vaadin.terminal.gwt.client.WidgetSet",
+ "com.vaadin.terminal.gwt.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.terminal.gwt.client.Paintable",
+ "com.vaadin.terminal.gwt.client.ui.VTabsheetPanel",
+ "com.vaadin.terminal.gwt.client.ui.VPopupCalendar", "blah",
+ true, expectedSize, expectedRoots, false);
+
+ }
+}
diff --git a/server/src/test/java/com/vaadin/data/util/IndexedContainerTest.java b/server/src/test/java/com/vaadin/data/util/IndexedContainerTest.java
new file mode 100644
index 0000000000..5828ac88cc
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/IndexedContainerTest.java
@@ -0,0 +1,539 @@
+package com.vaadin.data.util;
+
+import java.util.List;
+
+import org.easymock.Capture;
+import org.easymock.EasyMock;
+import org.junit.Assert;
+
+import com.vaadin.data.Container.Indexed.ItemAddEvent;
+import com.vaadin.data.Container.Indexed.ItemRemoveEvent;
+import com.vaadin.data.Container.ItemSetChangeListener;
+import com.vaadin.data.Item;
+
+public class IndexedContainerTest extends AbstractInMemoryContainerTestBase {
+
+ 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();
+ }
+
+ public void testItemAdd_idSequence() {
+ IndexedContainer container = new IndexedContainer();
+ Object itemId;
+
+ itemId = container.addItem();
+ assertEquals(Integer.valueOf(1), itemId);
+
+ itemId = container.addItem();
+ assertEquals(Integer.valueOf(2), itemId);
+
+ itemId = container.addItemAfter(null);
+ assertEquals(Integer.valueOf(3), itemId);
+
+ itemId = container.addItemAt(2);
+ assertEquals(Integer.valueOf(4), itemId);
+ }
+
+ public void testItemAddRemove_idSequence() {
+ IndexedContainer container = new IndexedContainer();
+ Object itemId;
+
+ itemId = container.addItem();
+ assertEquals(Integer.valueOf(1), itemId);
+
+ container.removeItem(itemId);
+
+ itemId = container.addItem();
+ assertEquals(
+ "Id sequence should continue from the previous value even if an item is removed",
+ Integer.valueOf(2), itemId);
+ }
+
+ public void testItemAddedEvent() {
+ IndexedContainer container = new IndexedContainer();
+ ItemSetChangeListener addListener = createListenerMockFor(container);
+ addListener.containerItemSetChange(EasyMock.isA(ItemAddEvent.class));
+ EasyMock.replay(addListener);
+
+ container.addItem();
+
+ EasyMock.verify(addListener);
+ }
+
+ public void testItemAddedEvent_AddedItem() {
+ IndexedContainer container = new IndexedContainer();
+ ItemSetChangeListener addListener = createListenerMockFor(container);
+ Capture<ItemAddEvent> capturedEvent = captureAddEvent(addListener);
+ EasyMock.replay(addListener);
+
+ Object itemId = container.addItem();
+
+ assertEquals(itemId, capturedEvent.getValue().getFirstItemId());
+ }
+
+ public void testItemAddedEvent_IndexOfAddedItem() {
+ IndexedContainer container = new IndexedContainer();
+ ItemSetChangeListener addListener = createListenerMockFor(container);
+ container.addItem();
+ Capture<ItemAddEvent> capturedEvent = captureAddEvent(addListener);
+ EasyMock.replay(addListener);
+
+ Object itemId = container.addItemAt(1);
+
+ assertEquals(1, capturedEvent.getValue().getFirstIndex());
+ }
+
+ public void testItemRemovedEvent() {
+ IndexedContainer container = new IndexedContainer();
+ Object itemId = container.addItem();
+ ItemSetChangeListener removeListener = createListenerMockFor(container);
+ removeListener.containerItemSetChange(EasyMock
+ .isA(ItemRemoveEvent.class));
+ EasyMock.replay(removeListener);
+
+ container.removeItem(itemId);
+
+ EasyMock.verify(removeListener);
+ }
+
+ public void testItemRemovedEvent_RemovedItem() {
+ IndexedContainer container = new IndexedContainer();
+ Object itemId = container.addItem();
+ ItemSetChangeListener removeListener = createListenerMockFor(container);
+ Capture<ItemRemoveEvent> capturedEvent = captureRemoveEvent(removeListener);
+ EasyMock.replay(removeListener);
+
+ container.removeItem(itemId);
+
+ assertEquals(itemId, capturedEvent.getValue().getFirstItemId());
+ }
+
+ public void testItemRemovedEvent_indexOfRemovedItem() {
+ IndexedContainer container = new IndexedContainer();
+ container.addItem();
+ Object secondItemId = container.addItem();
+ ItemSetChangeListener removeListener = createListenerMockFor(container);
+ Capture<ItemRemoveEvent> capturedEvent = captureRemoveEvent(removeListener);
+ EasyMock.replay(removeListener);
+
+ container.removeItem(secondItemId);
+
+ assertEquals(1, capturedEvent.getValue().getFirstIndex());
+ }
+
+ public void testItemRemovedEvent_amountOfRemovedItems() {
+ IndexedContainer container = new IndexedContainer();
+ container.addItem();
+ container.addItem();
+ ItemSetChangeListener removeListener = createListenerMockFor(container);
+ Capture<ItemRemoveEvent> capturedEvent = captureRemoveEvent(removeListener);
+ EasyMock.replay(removeListener);
+
+ container.removeAllItems();
+
+ assertEquals(2, capturedEvent.getValue().getRemovedItemsCount());
+ }
+
+ private Capture<ItemAddEvent> captureAddEvent(
+ ItemSetChangeListener addListener) {
+ Capture<ItemAddEvent> capturedEvent = new Capture<ItemAddEvent>();
+ addListener.containerItemSetChange(EasyMock.capture(capturedEvent));
+ return capturedEvent;
+ }
+
+ private Capture<ItemRemoveEvent> captureRemoveEvent(
+ ItemSetChangeListener removeListener) {
+ Capture<ItemRemoveEvent> capturedEvent = new Capture<ItemRemoveEvent>();
+ removeListener.containerItemSetChange(EasyMock.capture(capturedEvent));
+ return capturedEvent;
+ }
+
+ private ItemSetChangeListener createListenerMockFor(
+ IndexedContainer container) {
+ ItemSetChangeListener listener = EasyMock
+ .createNiceMock(ItemSetChangeListener.class);
+ container.addItemSetChangeListener(listener);
+ return listener;
+ }
+
+ // Ticket 8028
+ public void testGetItemIdsRangeIndexOutOfBounds() {
+ IndexedContainer ic = new IndexedContainer();
+ try {
+ ic.getItemIds(-1, 10);
+ fail("Container returned items starting from index -1, something very wrong here!");
+ } catch (IndexOutOfBoundsException e) {
+ // This is expected...
+ } catch (Exception e) {
+ // Should not happen!
+ fail("Container threw unspecified exception when fetching a range of items and the range started from -1");
+ }
+
+ }
+
+ // Ticket 8028
+ public void testGetItemIdsRangeIndexOutOfBounds2() {
+ IndexedContainer ic = new IndexedContainer();
+ ic.addItem(new Object());
+ try {
+ ic.getItemIds(2, 1);
+ fail("Container returned items starting from index -1, something very wrong here!");
+ } catch (IndexOutOfBoundsException e) {
+ // This is expected...
+ } catch (Exception e) {
+ // Should not happen!
+ fail("Container threw unspecified exception when fetching a out of bounds range of items");
+ }
+
+ }
+
+ // Ticket 8028
+ public void testGetItemIdsRangeZeroRange() {
+ IndexedContainer ic = new IndexedContainer();
+ ic.addItem(new Object());
+ try {
+ List<Object> itemIds = ic.getItemIds(1, 0);
+
+ assertTrue(
+ "Container returned actual values when asking for 0 items...",
+ itemIds.isEmpty());
+ } catch (Exception e) {
+ // Should not happen!
+ fail("Container threw unspecified exception when fetching 0 items...");
+ }
+
+ }
+
+ // Ticket 8028
+ public void testGetItemIdsRangeNegativeRange() {
+ IndexedContainer ic = new IndexedContainer();
+ ic.addItem(new Object());
+ try {
+ List<Object> itemIds = ic.getItemIds(1, -1);
+
+ assertTrue(
+ "Container returned actual values when asking for -1 items...",
+ itemIds.isEmpty());
+ } catch (IllegalArgumentException e) {
+ // this is expected
+
+ } catch (Exception e) {
+ // Should not happen!
+ fail("Container threw unspecified exception when fetching -1 items...");
+ }
+
+ }
+
+ // Ticket 8028
+ public void testGetItemIdsRangeIndexOutOfBoundsDueToSizeChange() {
+ IndexedContainer ic = new IndexedContainer();
+ ic.addItem(new Object());
+ Assert.assertEquals(
+ "Container returned too many items when the range was >> container size",
+ 1, ic.getItemIds(0, 10).size());
+ }
+
+ // Ticket 8028
+ public void testGetItemIdsRangeBaseCase() {
+ IndexedContainer ic = new IndexedContainer();
+ String object1 = new String("Obj1");
+ String object2 = new String("Obj2");
+ String object3 = new String("Obj3");
+ String object4 = new String("Obj4");
+ String object5 = new String("Obj5");
+
+ ic.addItem(object1);
+ ic.addItem(object2);
+ ic.addItem(object3);
+ ic.addItem(object4);
+ ic.addItem(object5);
+
+ try {
+ List<Object> itemIds = ic.getItemIds(1, 2);
+
+ assertTrue(itemIds.contains(object2));
+ assertTrue(itemIds.contains(object3));
+ assertEquals(2, itemIds.size());
+
+ } catch (Exception e) {
+ // Should not happen!
+ fail("Container threw exception when fetching a range of items ");
+ }
+ }
+
+ // test getting non-existing property (#10445)
+ public void testNonExistingProperty() {
+ IndexedContainer ic = new IndexedContainer();
+ String object1 = new String("Obj1");
+ ic.addItem(object1);
+ assertNull(ic.getContainerProperty(object1, "xyz"));
+ }
+
+ // test getting null property id (#10445)
+ public void testNullPropertyId() {
+ IndexedContainer ic = new IndexedContainer();
+ String object1 = new String("Obj1");
+ ic.addItem(object1);
+ assertNull(ic.getContainerProperty(object1, null));
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/data/util/MethodPropertyMemoryConsumptionTest.java b/server/src/test/java/com/vaadin/data/util/MethodPropertyMemoryConsumptionTest.java
new file mode 100644
index 0000000000..b4621b823a
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/MethodPropertyMemoryConsumptionTest.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.data.util;
+
+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 java.lang.reflect.Field;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Test for MethodProperty: don't allocate unnecessary Object arrays.
+ *
+ * @since 7.2
+ * @author Vaadin Ltd
+ */
+public class MethodPropertyMemoryConsumptionTest {
+
+ @Test
+ public void testSetArguments() throws NoSuchFieldException,
+ SecurityException, IllegalArgumentException, IllegalAccessException {
+ TestBean bean = new TestBean();
+ TestMethodProperty<String> property = new TestMethodProperty<String>(
+ bean, "name");
+ Object[] getArgs = property.getGetArgs();
+ Object[] setArgs = property.getSetArgs();
+
+ Field getArgsField = TestMethodProperty.class
+ .getDeclaredField("getArgs");
+ getArgsField.setAccessible(true);
+
+ Field setArgsField = TestMethodProperty.class
+ .getDeclaredField("setArgs");
+ setArgsField.setAccessible(true);
+
+ Assert.assertSame("setArguments method sets non-default instance"
+ + " of empty Object array for getArgs",
+ getArgsField.get(property), getArgs);
+
+ Assert.assertSame("setArguments method sets non-default instance"
+ + " of empty Object array for setArgs",
+ setArgsField.get(property), setArgs);
+ }
+
+ @Test
+ public void testDefaultCtor() {
+ TestBean bean = new TestBean();
+ TestMethodProperty<String> property = new TestMethodProperty<String>(
+ bean, "name");
+
+ Object[] getArgs = property.getGetArgs();
+ Object[] setArgs = property.getSetArgs();
+
+ TestBean otherBean = new TestBean();
+ TestMethodProperty<String> otherProperty = new TestMethodProperty<String>(
+ otherBean, "name");
+ Assert.assertSame("setArguments method uses different instance"
+ + " of empty Object array for getArgs", getArgs,
+ otherProperty.getGetArgs());
+ Assert.assertSame("setArguments method uses different instance"
+ + " of empty Object array for setArgs", setArgs,
+ otherProperty.getSetArgs());
+ }
+
+ @Test
+ public void testDefaultArgsSerialization() throws IOException,
+ ClassNotFoundException {
+ TestBean bean = new TestBean();
+ TestMethodProperty<String> property = new TestMethodProperty<String>(
+ bean, "name");
+
+ ByteArrayOutputStream sourceOutStream = new ByteArrayOutputStream();
+ ObjectOutputStream outStream = new ObjectOutputStream(sourceOutStream);
+ outStream.writeObject(property);
+
+ ObjectInputStream inputStream = new ObjectInputStream(
+ new ByteArrayInputStream(sourceOutStream.toByteArray()));
+ Object red = inputStream.readObject();
+ TestMethodProperty<?> deserialized = (TestMethodProperty<?>) red;
+
+ Assert.assertNotNull("Deseriliation doesn't call setArguments method",
+ deserialized.getGetArgs());
+ Assert.assertNotNull("Deseriliation doesn't call setArguments method",
+ deserialized.getSetArgs());
+
+ }
+
+ public static class TestMethodProperty<T> extends MethodProperty<T> {
+
+ public TestMethodProperty(Object instance, String beanPropertyName) {
+ super(instance, beanPropertyName);
+ }
+
+ @Override
+ public void setArguments(Object[] getArgs, Object[] setArgs,
+ int setArgumentIndex) {
+ super.setArguments(getArgs, setArgs, setArgumentIndex);
+ this.getArgs = getArgs;
+ this.setArgs = setArgs;
+ }
+
+ Object[] getGetArgs() {
+ return getArgs;
+ }
+
+ Object[] getSetArgs() {
+ return setArgs;
+ }
+
+ private transient Object[] getArgs;
+ private transient Object[] setArgs;
+ }
+
+ public static class TestBean implements Serializable {
+
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ }
+}
diff --git a/server/src/test/java/com/vaadin/data/util/NestedMethodPropertyTest.java b/server/src/test/java/com/vaadin/data/util/NestedMethodPropertyTest.java
new file mode 100644
index 0000000000..6535ba1870
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/NestedMethodPropertyTest.java
@@ -0,0 +1,344 @@
+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.TestCase;
+
+import org.junit.Assert;
+
+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;
+ private int age;
+
+ public Person(String name, Address address) {
+ this.name = name;
+ this.address = address;
+ }
+
+ public Person(String name, Address address, int age) {
+ this.name = name;
+ this.address = address;
+ this.age = age;
+ }
+
+ 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 int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+ }
+
+ 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);
+ assertNull(streetProperty.getValue());
+
+ vaadin.setManager(null);
+ assertNull(managerNameProperty.getValue());
+ assertNull(streetProperty.getValue());
+
+ vaadin.setManager(joonas);
+ Assert.assertEquals("Joonas", managerNameProperty.getValue());
+ Assert.assertNull(streetProperty.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 testSerializationWithIntermediateNull() throws IOException,
+ ClassNotFoundException {
+ vaadin.setManager(null);
+ 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.assertNull(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/src/test/java/com/vaadin/data/util/ObjectPropertyTest.java b/server/src/test/java/com/vaadin/data/util/ObjectPropertyTest.java
new file mode 100644
index 0000000000..99ca58ba42
--- /dev/null
+++ b/server/src/test/java/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/src/test/java/com/vaadin/data/util/PerformanceTestIndexedContainerTest.java b/server/src/test/java/com/vaadin/data/util/PerformanceTestIndexedContainerTest.java
new file mode 100644
index 0000000000..042f260be8
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/PerformanceTestIndexedContainerTest.java
@@ -0,0 +1,116 @@
+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.TestCase;
+
+import org.junit.Assert;
+
+public class PerformanceTestIndexedContainerTest 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/src/test/java/com/vaadin/data/util/PropertyDescriptorTest.java b/server/src/test/java/com/vaadin/data/util/PropertyDescriptorTest.java
new file mode 100644
index 0000000000..9d662b2599
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/PropertyDescriptorTest.java
@@ -0,0 +1,80 @@
+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.TestCase;
+
+import org.junit.Assert;
+
+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 testSimpleNestedPropertyDescriptorSerialization()
+ 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());
+ }
+
+ public void testNestedPropertyDescriptorSerialization() throws Exception {
+ NestedPropertyDescriptor<Person> pd = new NestedPropertyDescriptor<Person>(
+ "address.street", 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.assertNull(property.getValue());
+ }
+
+ public void testMethodPropertyDescriptorWithPrimitivePropertyType()
+ throws Exception {
+ MethodPropertyDescriptor<Person> pd = new MethodPropertyDescriptor<Person>(
+ "age", int.class, Person.class.getMethod("getAge"),
+ Person.class.getMethod("setAge", int.class));
+
+ Assert.assertEquals(Integer.class, pd.getPropertyType());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/data/util/PropertySetItemTest.java b/server/src/test/java/com/vaadin/data/util/PropertySetItemTest.java
new file mode 100644
index 0000000000..ff83db4437
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/PropertySetItemTest.java
@@ -0,0 +1,405 @@
+package com.vaadin.data.util;
+
+import java.util.Iterator;
+
+import junit.framework.TestCase;
+
+import org.easymock.EasyMock;
+import org.junit.Assert;
+
+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/src/test/java/com/vaadin/data/util/ReflectToolsGetSuperFieldTest.java b/server/src/test/java/com/vaadin/data/util/ReflectToolsGetSuperFieldTest.java
new file mode 100644
index 0000000000..5f31150210
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/ReflectToolsGetSuperFieldTest.java
@@ -0,0 +1,35 @@
+package com.vaadin.data.util;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import com.vaadin.data.fieldgroup.FieldGroup;
+import com.vaadin.data.fieldgroup.PropertyId;
+import com.vaadin.ui.TextField;
+
+public class ReflectToolsGetSuperFieldTest {
+
+ @Test
+ public void getFieldFromSuperClass() {
+ class MyClass {
+ @PropertyId("testProperty")
+ TextField test = new TextField("This is a test");
+ }
+ class MySubClass extends MyClass {
+ // no fields here
+ }
+
+ PropertysetItem item = new PropertysetItem();
+ item.addItemProperty("testProperty", new ObjectProperty<String>(
+ "Value of testProperty"));
+
+ MySubClass form = new MySubClass();
+
+ FieldGroup binder = new FieldGroup(item);
+ binder.bindMemberFields(form);
+
+ assertTrue("Value of testProperty".equals(form.test.getValue()));
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/data/util/TransactionalPropertyWrapperTest.java b/server/src/test/java/com/vaadin/data/util/TransactionalPropertyWrapperTest.java
new file mode 100644
index 0000000000..5297cd807c
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/TransactionalPropertyWrapperTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.data.util;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.vaadin.data.fieldgroup.FieldGroup;
+import com.vaadin.ui.TextField;
+
+/**
+ * Test verifying that TransactionalPropertyWrapper removes it's listener from
+ * wrapped Property
+ *
+ * @since 7.1.15
+ * @author Vaadin Ltd
+ */
+public class TransactionalPropertyWrapperTest {
+
+ @SuppressWarnings("serial")
+ public class TestingProperty<T extends Object> extends
+ ObjectProperty<Object> {
+
+ private List<ValueChangeListener> listeners = new ArrayList<ValueChangeListener>();
+
+ public TestingProperty(Object value) {
+ super(value);
+ }
+
+ @Override
+ public void addValueChangeListener(ValueChangeListener listener) {
+ super.addValueChangeListener(listener);
+ listeners.add(listener);
+ }
+
+ @Override
+ public void removeValueChangeListener(ValueChangeListener listener) {
+ super.removeValueChangeListener(listener);
+ if (listeners.contains(listener)) {
+ listeners.remove(listener);
+ }
+ }
+
+ public boolean hasListeners() {
+ return !listeners.isEmpty();
+ }
+ }
+
+ private final TextField nameField = new TextField("Name");
+ private final TextField ageField = new TextField("Age");
+ private final TextField unboundField = new TextField("No FieldGroup");
+ private final TestingProperty<String> unboundProp = new TestingProperty<String>(
+ "Hello World");
+ private final PropertysetItem item = new PropertysetItem();
+
+ @Test
+ public void fieldGroupBindAndUnbind() {
+ item.addItemProperty("name", new TestingProperty<String>(
+ "Just some text"));
+ item.addItemProperty("age", new TestingProperty<String>("42"));
+
+ final FieldGroup binder = new FieldGroup(item);
+ binder.setBuffered(false);
+
+ for (int i = 0; i < 2; ++i) {
+ binder.bind(nameField, "name");
+ binder.bind(ageField, "age");
+ unboundField.setPropertyDataSource(unboundProp);
+
+ assertTrue("No listeners in Properties", fieldsHaveListeners(true));
+
+ binder.unbind(nameField);
+ binder.unbind(ageField);
+ unboundField.setPropertyDataSource(null);
+
+ assertTrue("Listeners in Properties after unbinding",
+ fieldsHaveListeners(false));
+ }
+ }
+
+ /**
+ * Check that all listeners have same hasListeners() response
+ *
+ * @param expected
+ * expected response
+ * @return true if all are the same as expected. false if not
+ */
+ private boolean fieldsHaveListeners(boolean expected) {
+ for (Object id : item.getItemPropertyIds()) {
+ TestingProperty<?> itemProperty = (TestingProperty<?>) item
+ .getItemProperty(id);
+
+ if (itemProperty.hasListeners() != expected) {
+ return false;
+ }
+ }
+ return unboundProp.hasListeners() == expected;
+ }
+}
diff --git a/server/src/test/java/com/vaadin/data/util/filter/AbstractFilterTestBase.java b/server/src/test/java/com/vaadin/data/util/filter/AbstractFilterTestBase.java
new file mode 100644
index 0000000000..ebd843fb53
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/filter/AbstractFilterTestBase.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 AbstractFilterTestBase<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(String 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/src/test/java/com/vaadin/data/util/filter/AndOrFilterTest.java b/server/src/test/java/com/vaadin/data/util/filter/AndOrFilterTest.java
new file mode 100644
index 0000000000..1f42f4e935
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/filter/AndOrFilterTest.java
@@ -0,0 +1,233 @@
+package com.vaadin.data.util.filter;
+
+import org.junit.Assert;
+
+import com.vaadin.data.Container.Filter;
+import com.vaadin.data.Item;
+import com.vaadin.data.util.BeanItem;
+
+public class AndOrFilterTest extends
+ AbstractFilterTestBase<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/src/test/java/com/vaadin/data/util/filter/CompareFilterTest.java b/server/src/test/java/com/vaadin/data/util/filter/CompareFilterTest.java
new file mode 100644
index 0000000000..fc5ffb9b56
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/filter/CompareFilterTest.java
@@ -0,0 +1,314 @@
+package com.vaadin.data.util.filter;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+import org.junit.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 AbstractFilterTestBase<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 testCompareBigDecimal() {
+ BigDecimal negative = new BigDecimal(-1);
+ BigDecimal zero = new BigDecimal(0);
+ BigDecimal positive = new BigDecimal(1);
+ positive.setScale(1);
+ BigDecimal positiveScaleTwo = new BigDecimal(1).setScale(2);
+
+ Item itemNegative = new PropertysetItem();
+ itemNegative.addItemProperty(PROPERTY1, new ObjectProperty<BigDecimal>(
+ negative, BigDecimal.class));
+ Item itemZero = new PropertysetItem();
+ itemZero.addItemProperty(PROPERTY1, new ObjectProperty<BigDecimal>(
+ zero, BigDecimal.class));
+ Item itemPositive = new PropertysetItem();
+ itemPositive.addItemProperty(PROPERTY1, new ObjectProperty<BigDecimal>(
+ positive, BigDecimal.class));
+ Item itemPositiveScaleTwo = new PropertysetItem();
+ itemPositiveScaleTwo.addItemProperty(PROPERTY1,
+ new ObjectProperty<BigDecimal>(positiveScaleTwo,
+ BigDecimal.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));
+
+ Filter isPositiveScaleTwo = new Equal(PROPERTY1, positiveScaleTwo);
+ Assert.assertTrue(isPositiveScaleTwo.passesFilter(null,
+ itemPositiveScaleTwo));
+ Assert.assertTrue(isPositiveScaleTwo.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/src/test/java/com/vaadin/data/util/filter/IsNullFilterTest.java b/server/src/test/java/com/vaadin/data/util/filter/IsNullFilterTest.java
new file mode 100644
index 0000000000..953bf3cd65
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/filter/IsNullFilterTest.java
@@ -0,0 +1,57 @@
+package com.vaadin.data.util.filter;
+
+import org.junit.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 AbstractFilterTestBase<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/src/test/java/com/vaadin/data/util/filter/LikeFilterTest.java b/server/src/test/java/com/vaadin/data/util/filter/LikeFilterTest.java
new file mode 100644
index 0000000000..9ba5168ac9
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/filter/LikeFilterTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.vaadin.data.util.filter;
+
+import org.junit.Assert;
+
+import com.vaadin.data.Item;
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.data.util.PropertysetItem;
+
+public class LikeFilterTest extends AbstractFilterTestBase<Like> {
+
+ protected Item item1 = new PropertysetItem();
+ protected Item item2 = new PropertysetItem();
+ protected Item item3 = new PropertysetItem();
+
+ public void testLikeWithNulls() {
+
+ Like filter = new Like("value", "a");
+
+ item1.addItemProperty("value", new ObjectProperty<String>("a"));
+ item2.addItemProperty("value", new ObjectProperty<String>("b"));
+ item3.addItemProperty("value", new ObjectProperty<String>(null,
+ String.class));
+
+ Assert.assertTrue(filter.passesFilter(null, item1));
+ Assert.assertFalse(filter.passesFilter(null, item2));
+ Assert.assertFalse(filter.passesFilter(null, item3));
+
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/data/util/filter/NotFilterTest.java b/server/src/test/java/com/vaadin/data/util/filter/NotFilterTest.java
new file mode 100644
index 0000000000..310b749ce2
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/filter/NotFilterTest.java
@@ -0,0 +1,50 @@
+package com.vaadin.data.util.filter;
+
+import org.junit.Assert;
+
+import com.vaadin.data.Container.Filter;
+import com.vaadin.data.Item;
+import com.vaadin.data.util.BeanItem;
+
+public class NotFilterTest extends AbstractFilterTestBase<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/src/test/java/com/vaadin/data/util/filter/SimpleStringFilterTest.java b/server/src/test/java/com/vaadin/data/util/filter/SimpleStringFilterTest.java
new file mode 100644
index 0000000000..fcaff6f2c3
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/filter/SimpleStringFilterTest.java
@@ -0,0 +1,130 @@
+package com.vaadin.data.util.filter;
+
+import org.junit.Assert;
+
+public class SimpleStringFilterTest extends
+ AbstractFilterTestBase<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/src/test/java/com/vaadin/data/util/sqlcontainer/AllTests.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/AllTests.java
new file mode 100644
index 0000000000..d2c7ad85ed
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/sqlcontainer/AllTests.java
@@ -0,0 +1,24 @@
+package com.vaadin.data.util.sqlcontainer;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+import com.vaadin.data.util.sqlcontainer.connection.J2EEConnectionPoolTest;
+import com.vaadin.data.util.sqlcontainer.connection.SimpleJDBCConnectionPoolTest;
+import com.vaadin.data.util.sqlcontainer.filters.BetweenTest;
+import com.vaadin.data.util.sqlcontainer.filters.LikeTest;
+import com.vaadin.data.util.sqlcontainer.generator.SQLGeneratorsTest;
+import com.vaadin.data.util.sqlcontainer.query.FreeformQueryTest;
+import com.vaadin.data.util.sqlcontainer.query.QueryBuilderTest;
+import com.vaadin.data.util.sqlcontainer.query.TableQueryTest;
+
+@RunWith(Suite.class)
+@SuiteClasses({ SimpleJDBCConnectionPoolTest.class,
+ J2EEConnectionPoolTest.class, LikeTest.class, QueryBuilderTest.class,
+ FreeformQueryTest.class, RowIdTest.class, SQLContainerTest.class,
+ SQLContainerTableQueryTest.class, ColumnPropertyTest.class,
+ TableQueryTest.class, SQLGeneratorsTest.class, UtilTest.class,
+ TicketTests.class, BetweenTest.class, ReadOnlyRowIdTest.class })
+public class AllTests {
+}
diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/ColumnPropertyTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/ColumnPropertyTest.java
new file mode 100644
index 0000000000..7cad310d37
--- /dev/null
+++ b/server/src/test/java/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/src/test/java/com/vaadin/data/util/sqlcontainer/DataGenerator.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/DataGenerator.java
new file mode 100644
index 0000000000..f6619a33b6
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/sqlcontainer/DataGenerator.java
@@ -0,0 +1,133 @@
+package com.vaadin.data.util.sqlcontainer;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.util.sqlcontainer.SQLTestsConstants.DB;
+import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool;
+
+public class DataGenerator {
+
+ public static void addPeopleToDatabase(JDBCConnectionPool connectionPool)
+ throws SQLException {
+ Connection conn = connectionPool.reserveConnection();
+ Statement statement = conn.createStatement();
+ try {
+ statement.execute("drop table PEOPLE");
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ statement.execute("drop sequence people_seq");
+ }
+ } catch (SQLException e) {
+ // Will fail if table doesn't exist, which is OK.
+ conn.rollback();
+ }
+ statement.execute(SQLTestsConstants.peopleFirst);
+ if (SQLTestsConstants.peopleSecond != null) {
+ statement.execute(SQLTestsConstants.peopleSecond);
+ }
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ statement.execute(SQLTestsConstants.peopleThird);
+ }
+ if (SQLTestsConstants.db == DB.MSSQL) {
+ statement.executeUpdate("insert into people values('Ville', '23')");
+ statement.executeUpdate("insert into people values('Kalle', '7')");
+ statement.executeUpdate("insert into people values('Pelle', '18')");
+ statement.executeUpdate("insert into people values('Börje', '64')");
+ } else {
+ statement
+ .executeUpdate("insert into people values(default, 'Ville', '23')");
+ statement
+ .executeUpdate("insert into people values(default, 'Kalle', '7')");
+ statement
+ .executeUpdate("insert into people values(default, 'Pelle', '18')");
+ statement
+ .executeUpdate("insert into people values(default, 'Börje', '64')");
+ }
+ statement.close();
+ statement = conn.createStatement();
+ ResultSet rs = statement.executeQuery("select * from PEOPLE");
+ Assert.assertTrue(rs.next());
+ statement.close();
+ conn.commit();
+ connectionPool.releaseConnection(conn);
+ }
+
+ public static void addFiveThousandPeople(JDBCConnectionPool connectionPool)
+ throws SQLException {
+ Connection conn = connectionPool.reserveConnection();
+ Statement statement = conn.createStatement();
+ for (int i = 4; i < 5000; i++) {
+ if (SQLTestsConstants.db == DB.MSSQL) {
+ statement.executeUpdate("insert into people values('Person "
+ + i + "', '" + i % 99 + "')");
+ } else {
+ statement
+ .executeUpdate("insert into people values(default, 'Person "
+ + i + "', '" + i % 99 + "')");
+ }
+ }
+ statement.close();
+ conn.commit();
+ connectionPool.releaseConnection(conn);
+ }
+
+ public static void addVersionedData(JDBCConnectionPool connectionPool)
+ throws SQLException {
+ Connection conn = connectionPool.reserveConnection();
+ Statement statement = conn.createStatement();
+ try {
+ statement.execute("DROP TABLE VERSIONED");
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ statement.execute("drop sequence versioned_seq");
+ statement.execute("drop sequence versioned_version");
+ }
+ } catch (SQLException e) {
+ // Will fail if table doesn't exist, which is OK.
+ conn.rollback();
+ }
+ for (String stmtString : SQLTestsConstants.versionStatements) {
+ statement.execute(stmtString);
+ }
+ if (SQLTestsConstants.db == DB.MSSQL) {
+ statement
+ .executeUpdate("insert into VERSIONED values('Junk', default)");
+ } else {
+ statement
+ .executeUpdate("insert into VERSIONED values(default, 'Junk', default)");
+ }
+ statement.close();
+ statement = conn.createStatement();
+ ResultSet rs = statement.executeQuery("select * from VERSIONED");
+ Assert.assertTrue(rs.next());
+ statement.close();
+ conn.commit();
+ connectionPool.releaseConnection(conn);
+ }
+
+ public static void createGarbage(JDBCConnectionPool connectionPool)
+ throws SQLException {
+ Connection conn = connectionPool.reserveConnection();
+ Statement statement = conn.createStatement();
+ try {
+ statement.execute("drop table GARBAGE");
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ statement.execute("drop sequence garbage_seq");
+ }
+ } catch (SQLException e) {
+ // Will fail if table doesn't exist, which is OK.
+ conn.rollback();
+ }
+ statement.execute(SQLTestsConstants.createGarbage);
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ statement.execute(SQLTestsConstants.createGarbageSecond);
+ statement.execute(SQLTestsConstants.createGarbageThird);
+ }
+ conn.commit();
+ connectionPool.releaseConnection(conn);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/FreeformQueryUtil.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/FreeformQueryUtil.java
new file mode 100644
index 0000000000..288cb65fae
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/sqlcontainer/FreeformQueryUtil.java
@@ -0,0 +1,65 @@
+package com.vaadin.data.util.sqlcontainer;
+
+import java.util.List;
+
+import org.junit.Test;
+
+import com.vaadin.data.Container.Filter;
+import com.vaadin.data.util.sqlcontainer.SQLTestsConstants.DB;
+import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
+import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder;
+
+public class FreeformQueryUtil {
+
+ public static StatementHelper getQueryWithFilters(List<Filter> filters,
+ int offset, int limit) {
+ StatementHelper sh = new StatementHelper();
+ if (SQLTestsConstants.db == DB.MSSQL) {
+ if (limit > 1) {
+ offset++;
+ limit--;
+ }
+ StringBuilder query = new StringBuilder();
+ query.append("SELECT * FROM (SELECT row_number() OVER (");
+ query.append("ORDER BY \"ID\" ASC");
+ query.append(") AS rownum, * FROM \"PEOPLE\"");
+
+ if (!filters.isEmpty()) {
+ query.append(QueryBuilder.getWhereStringForFilters(filters, sh));
+ }
+ query.append(") AS a WHERE a.rownum BETWEEN ").append(offset)
+ .append(" AND ").append(Integer.toString(offset + limit));
+ sh.setQueryString(query.toString());
+ return sh;
+ } else if (SQLTestsConstants.db == DB.ORACLE) {
+ if (limit > 1) {
+ offset++;
+ limit--;
+ }
+ StringBuilder query = new StringBuilder();
+ query.append("SELECT * FROM (SELECT x.*, ROWNUM AS "
+ + "\"rownum\" FROM (SELECT * FROM \"PEOPLE\"");
+ if (!filters.isEmpty()) {
+ query.append(QueryBuilder.getWhereStringForFilters(filters, sh));
+ }
+ query.append(") x) WHERE \"rownum\" BETWEEN ? AND ?");
+ sh.addParameterValue(offset);
+ sh.addParameterValue(offset + limit);
+ sh.setQueryString(query.toString());
+ return sh;
+ } else {
+ StringBuilder query = new StringBuilder("SELECT * FROM people");
+ if (!filters.isEmpty()) {
+ query.append(QueryBuilder.getWhereStringForFilters(filters, sh));
+ }
+ if (limit != 0 || offset != 0) {
+ query.append(" LIMIT ? OFFSET ?");
+ sh.addParameterValue(limit);
+ sh.addParameterValue(offset);
+ }
+ sh.setQueryString(query.toString());
+ return sh;
+ }
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/ReadOnlyRowIdTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/ReadOnlyRowIdTest.java
new file mode 100644
index 0000000000..29968ecf94
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/sqlcontainer/ReadOnlyRowIdTest.java
@@ -0,0 +1,55 @@
+package com.vaadin.data.util.sqlcontainer;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ReadOnlyRowIdTest {
+
+ @Test
+ public void getRowNum_shouldReturnRowNumGivenInConstructor() {
+ int rowNum = 1337;
+ ReadOnlyRowId rid = new ReadOnlyRowId(rowNum);
+ Assert.assertEquals(rowNum, rid.getRowNum());
+ }
+
+ @Test
+ public void hashCode_shouldBeEqualToHashCodeOfRowNum() {
+ int rowNum = 1337;
+ ReadOnlyRowId rid = new ReadOnlyRowId(rowNum);
+ Assert.assertEquals(Integer.valueOf(rowNum).hashCode(), rid.hashCode());
+ }
+
+ @Test
+ public void equals_compareWithNull_shouldBeFalse() {
+ ReadOnlyRowId rid = new ReadOnlyRowId(1337);
+ Assert.assertFalse(rid.equals(null));
+ }
+
+ @Test
+ public void equals_compareWithSameInstance_shouldBeTrue() {
+ ReadOnlyRowId rid = new ReadOnlyRowId(1337);
+ ReadOnlyRowId rid2 = rid;
+ Assert.assertTrue(rid.equals(rid2));
+ }
+
+ @Test
+ public void equals_compareWithOtherType_shouldBeFalse() {
+ ReadOnlyRowId rid = new ReadOnlyRowId(1337);
+ Assert.assertFalse(rid.equals(new Object()));
+ }
+
+ @Test
+ public void equals_compareWithOtherRowId_shouldBeFalse() {
+ ReadOnlyRowId rid = new ReadOnlyRowId(1337);
+ ReadOnlyRowId rid2 = new ReadOnlyRowId(42);
+ Assert.assertFalse(rid.equals(rid2));
+ }
+
+ @Test
+ public void toString_rowNumberIsReturned() {
+ int i = 1;
+ ReadOnlyRowId rowId = new ReadOnlyRowId(i);
+ Assert.assertEquals("Unexpected toString value", String.valueOf(i),
+ rowId.toString());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/RowIdTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/RowIdTest.java
new file mode 100644
index 0000000000..73f7be9fb2
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/sqlcontainer/RowIdTest.java
@@ -0,0 +1,60 @@
+package com.vaadin.data.util.sqlcontainer;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class RowIdTest {
+
+ @Test
+ public void constructor_withArrayOfPrimaryKeyColumns_shouldSucceed() {
+ RowId id = new RowId(new Object[] { "id", "name" });
+ Assert.assertArrayEquals(new Object[] { "id", "name" }, id.getId());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor_withNullParameter_shouldFail() {
+ new RowId(null);
+ }
+
+ @Test
+ public void hashCode_samePrimaryKeys_sameResult() {
+ RowId id = new RowId(new Object[] { "id", "name" });
+ RowId id2 = new RowId(new Object[] { "id", "name" });
+ Assert.assertEquals(id.hashCode(), id2.hashCode());
+ }
+
+ @Test
+ public void hashCode_differentPrimaryKeys_differentResult() {
+ RowId id = new RowId(new Object[] { "id", "name" });
+ RowId id2 = new RowId(new Object[] { "id" });
+ Assert.assertFalse(id.hashCode() == id2.hashCode());
+ }
+
+ @Test
+ public void equals_samePrimaryKeys_returnsTrue() {
+ RowId id = new RowId(new Object[] { "id", "name" });
+ RowId id2 = new RowId(new Object[] { "id", "name" });
+ Assert.assertEquals(id, id2);
+ }
+
+ @Test
+ public void equals_differentPrimaryKeys_returnsFalse() {
+ RowId id = new RowId(new Object[] { "id", "name" });
+ RowId id2 = new RowId(new Object[] { "id" });
+ Assert.assertFalse(id.equals(id2.hashCode()));
+ }
+
+ @Test
+ public void equals_differentDataType_returnsFalse() {
+ RowId id = new RowId(new Object[] { "id", "name" });
+ Assert.assertFalse(id.equals("Tudiluu"));
+ Assert.assertFalse(id.equals(new Integer(1337)));
+ }
+
+ @Test
+ public void toString_defaultCtor_noException() {
+ RowId rowId = new RowId();
+ Assert.assertTrue("Unexpected to string for empty Row Id", rowId
+ .toString().isEmpty());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java
new file mode 100644
index 0000000000..b2cc9a5d0c
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java
@@ -0,0 +1,1363 @@
+package com.vaadin.data.util.sqlcontainer;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.hasItems;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNull.nullValue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.math.BigDecimal;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.Container.ItemSetChangeEvent;
+import com.vaadin.data.Container.ItemSetChangeListener;
+import com.vaadin.data.Item;
+import com.vaadin.data.util.filter.Like;
+import com.vaadin.data.util.sqlcontainer.SQLTestsConstants.DB;
+import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool;
+import com.vaadin.data.util.sqlcontainer.query.OrderBy;
+import com.vaadin.data.util.sqlcontainer.query.TableQuery;
+import com.vaadin.data.util.sqlcontainer.query.ValidatingSimpleJDBCConnectionPool;
+
+public class SQLContainerTableQueryTest {
+
+ private static final int offset = SQLTestsConstants.offset;
+ private final int numberOfRowsInContainer = 4;
+ private final int numberOfPropertiesInContainer = 3;
+ private final String NAME = "NAME";
+ private final String ID = "ID";
+ private final String AGE = "AGE";
+ private JDBCConnectionPool connectionPool;
+ private TableQuery query;
+ private SQLContainer container;
+ private final RowId existingItemId = getRowId(1);
+ private final RowId nonExistingItemId = getRowId(1337);
+
+ @Before
+ public void setUp() throws SQLException {
+
+ try {
+ connectionPool = new ValidatingSimpleJDBCConnectionPool(
+ SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL,
+ SQLTestsConstants.dbUser, SQLTestsConstants.dbPwd, 2, 2);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ Assert.fail(e.getMessage());
+ }
+
+ DataGenerator.addPeopleToDatabase(connectionPool);
+
+ query = getTableQuery("people");
+ container = new SQLContainer(query);
+ }
+
+ private TableQuery getTableQuery(String tableName) {
+ return new TableQuery(tableName, connectionPool,
+ SQLTestsConstants.sqlGen);
+ }
+
+ private SQLContainer getGarbageContainer() throws SQLException {
+ DataGenerator.createGarbage(connectionPool);
+
+ return new SQLContainer(getTableQuery("garbage"));
+ }
+
+ private Item getItem(Object id) {
+ return container.getItem(id);
+ }
+
+ private RowId getRowId(int id) {
+ return new RowId(new Object[] { id + offset });
+ }
+
+ @After
+ public void tearDown() {
+ if (connectionPool != null) {
+ connectionPool.destroy();
+ }
+ }
+
+ @Test
+ public void itemWithExistingVersionColumnIsRemoved() throws SQLException {
+ container.setAutoCommit(true);
+ query.setVersionColumn(ID);
+
+ assertTrue(container.removeItem(container.lastItemId()));
+ }
+
+ @Test(expected = SQLException.class)
+ public void itemWithNonExistingVersionColumnCannotBeRemoved()
+ throws SQLException {
+ query.setVersionColumn("version");
+
+ container.removeItem(container.lastItemId());
+
+ container.commit();
+ }
+
+ @Test
+ public void containerContainsId() {
+ assertTrue(container.containsId(existingItemId));
+ }
+
+ @Test
+ public void containerDoesNotContainId() {
+ assertFalse(container.containsId(nonExistingItemId));
+ }
+
+ @Test
+ public void idPropertyHasCorrectType() {
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ assertEquals(container.getType(ID), BigDecimal.class);
+ } else {
+ assertEquals(container.getType(ID), Integer.class);
+ }
+ }
+
+ @Test
+ public void namePropertyHasCorrectType() {
+ assertEquals(container.getType(NAME), String.class);
+ }
+
+ @Test
+ public void nonExistingPropertyDoesNotHaveType() {
+ assertThat(container.getType("adsf"), is(nullValue()));
+ }
+
+ @Test
+ public void sizeIsReturnedCorrectly() {
+ assertEquals(numberOfRowsInContainer, container.size());
+ }
+
+ @Test
+ public void propertyIsFetchedForExistingItem() {
+ assertThat(container.getContainerProperty(existingItemId, NAME)
+ .getValue().toString(), is("Kalle"));
+ }
+
+ @Test
+ public void containerDoesNotContainPropertyForExistingItem() {
+ assertThat(container.getContainerProperty(existingItemId, "asdf"),
+ is(nullValue()));
+ }
+
+ @Test
+ public void containerDoesNotContainExistingPropertyForNonExistingItem() {
+ assertThat(container.getContainerProperty(nonExistingItemId, NAME),
+ is(nullValue()));
+ }
+
+ @Test
+ public void propertyIdsAreFetched() {
+ ArrayList<String> propertyIds = new ArrayList<String>(
+ (Collection<? extends String>) container
+ .getContainerPropertyIds());
+
+ assertThat(propertyIds.size(), is(numberOfPropertiesInContainer));
+ assertThat(propertyIds, hasItems(ID, NAME, AGE));
+ }
+
+ @Test
+ public void existingItemIsFetched() {
+ Item item = container.getItem(existingItemId);
+
+ assertThat(item.getItemProperty(NAME).getValue().toString(),
+ is("Kalle"));
+ }
+
+ @Test
+ public void newItemIsAdded() throws SQLException {
+ Object id = container.addItem();
+ getItem(id).getItemProperty(NAME).setValue("foo");
+
+ container.commit();
+
+ Item item = getItem(container.lastItemId());
+ assertThat(item.getItemProperty(NAME).getValue().toString(), is("foo"));
+ }
+
+ @Test
+ public void itemPropertyIsNotRevertedOnRefresh() {
+ getItem(existingItemId).getItemProperty(NAME).setValue("foo");
+
+ container.refresh();
+
+ assertThat(getItem(existingItemId).getItemProperty(NAME).toString(),
+ is("foo"));
+ }
+
+ @Test
+ public void correctItemIsFetchedFromMultipleRows() throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+
+ Item item = container.getItem(getRowId(1337));
+
+ assertThat((Integer) item.getItemProperty(ID).getValue(),
+ is(equalTo(1337 + offset)));
+ assertThat(item.getItemProperty(NAME).getValue().toString(),
+ is("Person 1337"));
+ }
+
+ @Test
+ public void getItemIds_table_returnsItemIdsWithKeys0through3()
+ throws SQLException {
+ Collection<?> itemIds = container.getItemIds();
+ assertEquals(4, itemIds.size());
+ RowId zero = new RowId(new Object[] { 0 + offset });
+ RowId one = new RowId(new Object[] { 1 + offset });
+ RowId two = new RowId(new Object[] { 2 + offset });
+ RowId three = new RowId(new Object[] { 3 + offset });
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ String[] correct = new String[] { "1", "2", "3", "4" };
+ List<String> oracle = new ArrayList<String>();
+ for (Object o : itemIds) {
+ oracle.add(o.toString());
+ }
+ Assert.assertArrayEquals(correct, oracle.toArray());
+ } else {
+ Assert.assertArrayEquals(new Object[] { zero, one, two, three },
+ itemIds.toArray());
+ }
+ }
+
+ @Test
+ public void size_tableOneAddedItem_returnsFive() throws SQLException {
+ Connection conn = connectionPool.reserveConnection();
+ Statement statement = conn.createStatement();
+ if (SQLTestsConstants.db == DB.MSSQL) {
+ statement.executeUpdate("insert into people values('Bengt', 30)");
+ } else {
+ statement
+ .executeUpdate("insert into people values(default, 'Bengt', 30)");
+ }
+ statement.close();
+ conn.commit();
+ connectionPool.releaseConnection(conn);
+
+ assertEquals(5, container.size());
+ }
+
+ @Test
+ public void indexOfId_tableWithParameterThree_returnsThree()
+ throws SQLException {
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ assertEquals(3, container.indexOfId(new RowId(
+ new Object[] { new BigDecimal(3 + offset) })));
+ } else {
+ assertEquals(3,
+ container.indexOfId(new RowId(new Object[] { 3 + offset })));
+ }
+ }
+
+ @Test
+ public void indexOfId_table5000RowsWithParameter1337_returns1337()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ container.getItem(new RowId(new Object[] { new BigDecimal(
+ 1337 + offset) }));
+ assertEquals(1337, container.indexOfId(new RowId(
+ new Object[] { new BigDecimal(1337 + offset) })));
+ } else {
+ container.getItem(new RowId(new Object[] { 1337 + offset }));
+ assertEquals(1337, container.indexOfId(new RowId(
+ new Object[] { 1337 + offset })));
+ }
+ }
+
+ @Test
+ public void getIdByIndex_table5000rowsIndex1337_returnsRowId1337()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ Object itemId = container.getIdByIndex(1337);
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ assertEquals(new RowId(new Object[] { 1337 + offset }).toString(),
+ itemId.toString());
+ } else {
+ assertEquals(new RowId(new Object[] { 1337 + offset }), itemId);
+ }
+ }
+
+ @Test
+ public void getIdByIndex_tableWithPaging5000rowsIndex1337_returnsRowId1337()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+
+ Object itemId = container.getIdByIndex(1337);
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ assertEquals(new RowId(new Object[] { 1337 + offset }).toString(),
+ itemId.toString());
+ } else {
+ assertEquals(new RowId(new Object[] { 1337 + offset }), itemId);
+ }
+ }
+
+ @Test
+ public void nextItemId_tableCurrentItem1337_returnsItem1338()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, SQLTestsConstants.sqlGen));
+ Object itemId = container.getIdByIndex(1337);
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ assertEquals(new RowId(new Object[] { 1338 + offset }).toString(),
+ container.nextItemId(itemId).toString());
+ } else {
+ assertEquals(new RowId(new Object[] { 1338 + offset }),
+ container.nextItemId(itemId));
+ }
+ }
+
+ @Test
+ public void prevItemId_tableCurrentItem1337_returns1336()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ Object itemId = container.getIdByIndex(1337);
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ assertEquals(new RowId(new Object[] { 1336 + offset }).toString(),
+ container.prevItemId(itemId).toString());
+ } else {
+ assertEquals(new RowId(new Object[] { 1336 + offset }),
+ container.prevItemId(itemId));
+ }
+ }
+
+ @Test
+ public void firstItemId_table_returnsItemId0() throws SQLException {
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ assertEquals(new RowId(new Object[] { 0 + offset }).toString(),
+ container.firstItemId().toString());
+ } else {
+ assertEquals(new RowId(new Object[] { 0 + offset }),
+ container.firstItemId());
+ }
+ }
+
+ @Test
+ public void lastItemId_table5000Rows_returnsItemId4999()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ assertEquals(new RowId(new Object[] { 4999 + offset }).toString(),
+ container.lastItemId().toString());
+ } else {
+ assertEquals(new RowId(new Object[] { 4999 + offset }),
+ container.lastItemId());
+ }
+ }
+
+ @Test
+ public void isFirstId_tableActualFirstId_returnsTrue() throws SQLException {
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ assertTrue(container.isFirstId(new RowId(
+ new Object[] { new BigDecimal(0 + offset) })));
+ } else {
+ assertTrue(container.isFirstId(new RowId(
+ new Object[] { 0 + offset })));
+ }
+ }
+
+ @Test
+ public void isFirstId_tableSecondId_returnsFalse() throws SQLException {
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ Assert.assertFalse(container.isFirstId(new RowId(
+ new Object[] { new BigDecimal(1 + offset) })));
+ } else {
+ Assert.assertFalse(container.isFirstId(new RowId(
+ new Object[] { 1 + offset })));
+ }
+ }
+
+ @Test
+ public void isLastId_tableSecondId_returnsFalse() throws SQLException {
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ Assert.assertFalse(container.isLastId(new RowId(
+ new Object[] { new BigDecimal(1 + offset) })));
+ } else {
+ Assert.assertFalse(container.isLastId(new RowId(
+ new Object[] { 1 + offset })));
+ }
+ }
+
+ @Test
+ public void isLastId_tableLastId_returnsTrue() throws SQLException {
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ assertTrue(container.isLastId(new RowId(
+ new Object[] { new BigDecimal(3 + offset) })));
+ } else {
+ assertTrue(container
+ .isLastId(new RowId(new Object[] { 3 + offset })));
+ }
+ }
+
+ @Test
+ public void isLastId_table5000RowsLastId_returnsTrue() throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ assertTrue(container.isLastId(new RowId(
+ new Object[] { new BigDecimal(4999 + offset) })));
+ } else {
+ assertTrue(container.isLastId(new RowId(
+ new Object[] { 4999 + offset })));
+ }
+ }
+
+ @Test
+ public void allIdsFound_table5000RowsLastId_shouldSucceed()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+
+ for (int i = 0; i < 5000; i++) {
+ assertTrue(container.containsId(container.getIdByIndex(i)));
+ }
+ }
+
+ @Test
+ public void allIdsFound_table5000RowsLastId_autoCommit_shouldSucceed()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+
+ container.setAutoCommit(true);
+ for (int i = 0; i < 5000; i++) {
+ assertTrue(container.containsId(container.getIdByIndex(i)));
+ }
+ }
+
+ @Test
+ public void refresh_table_sizeShouldUpdate() throws SQLException {
+ assertEquals(4, container.size());
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ container.refresh();
+ assertEquals(5000, container.size());
+ }
+
+ @Test
+ public void refresh_tableWithoutCallingRefresh_sizeShouldNotUpdate()
+ throws SQLException {
+ // Yeah, this is a weird one. We're testing that the size doesn't update
+ // after adding lots of items unless we call refresh inbetween. This to
+ // make sure that the refresh method actually refreshes stuff and isn't
+ // a NOP.
+ assertEquals(4, container.size());
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ assertEquals(4, container.size());
+ }
+
+ @Test
+ public void setAutoCommit_table_shouldSucceed() throws SQLException {
+ container.setAutoCommit(true);
+ assertTrue(container.isAutoCommit());
+ container.setAutoCommit(false);
+ Assert.assertFalse(container.isAutoCommit());
+ }
+
+ @Test
+ public void getPageLength_table_returnsDefault100() throws SQLException {
+ assertEquals(100, container.getPageLength());
+ }
+
+ @Test
+ public void setPageLength_table_shouldSucceed() throws SQLException {
+ container.setPageLength(20);
+ assertEquals(20, container.getPageLength());
+ container.setPageLength(200);
+ assertEquals(200, container.getPageLength());
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void addContainerProperty_normal_isUnsupported() throws SQLException {
+ container.addContainerProperty("asdf", String.class, "");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void removeContainerProperty_normal_isUnsupported()
+ throws SQLException {
+ container.removeContainerProperty("asdf");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void addItemObject_normal_isUnsupported() throws SQLException {
+ container.addItem("asdf");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void addItemAfterObjectObject_normal_isUnsupported()
+ throws SQLException {
+ container.addItemAfter("asdf", "foo");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void addItemAtIntObject_normal_isUnsupported() throws SQLException {
+ container.addItemAt(2, "asdf");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void addItemAtInt_normal_isUnsupported() throws SQLException {
+ container.addItemAt(2);
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void addItemAfterObject_normal_isUnsupported() throws SQLException {
+ container.addItemAfter("asdf");
+ }
+
+ @Test
+ public void addItem_tableAddOneNewItem_returnsItemId() throws SQLException {
+ Object itemId = container.addItem();
+ Assert.assertNotNull(itemId);
+ }
+
+ @Test
+ public void addItem_tableAddOneNewItem_autoCommit_returnsFinalItemId()
+ throws SQLException {
+ container.setAutoCommit(true);
+ Object itemId = container.addItem();
+ Assert.assertNotNull(itemId);
+ assertTrue(itemId instanceof RowId);
+ Assert.assertFalse(itemId instanceof TemporaryRowId);
+ }
+
+ @Test
+ public void addItem_tableAddOneNewItem_autoCommit_sizeIsIncreased()
+ throws SQLException {
+ container.setAutoCommit(true);
+ int originalSize = container.size();
+ container.addItem();
+ assertEquals(originalSize + 1, container.size());
+ }
+
+ @Test
+ public void addItem_tableAddOneNewItem_shouldChangeSize()
+ throws SQLException {
+ int size = container.size();
+ container.addItem();
+ assertEquals(size + 1, container.size());
+ }
+
+ @Test
+ public void addItem_tableAddTwoNewItems_shouldChangeSize()
+ throws SQLException {
+ int size = container.size();
+ Object id1 = container.addItem();
+ Object id2 = container.addItem();
+ assertEquals(size + 2, container.size());
+ Assert.assertNotSame(id1, id2);
+ Assert.assertFalse(id1.equals(id2));
+ }
+
+ @Test
+ public void nextItemId_tableNewlyAddedItem_returnsNewlyAdded()
+ throws SQLException {
+ Object lastId = container.lastItemId();
+ Object id = container.addItem();
+ assertEquals(id, container.nextItemId(lastId));
+ }
+
+ @Test
+ public void lastItemId_tableNewlyAddedItem_returnsNewlyAdded()
+ throws SQLException {
+ Object lastId = container.lastItemId();
+ Object id = container.addItem();
+ assertEquals(id, container.lastItemId());
+ Assert.assertNotSame(lastId, container.lastItemId());
+ }
+
+ @Test
+ public void indexOfId_tableNewlyAddedItem_returnsFour() throws SQLException {
+ Object id = container.addItem();
+ assertEquals(4, container.indexOfId(id));
+ }
+
+ @Test
+ public void getItem_tableNewlyAddedItem_returnsNewlyAdded()
+ throws SQLException {
+ Object id = container.addItem();
+ Assert.assertNotNull(container.getItem(id));
+ }
+
+ @Test
+ public void getItemIds_tableNewlyAddedItem_containsNewlyAdded()
+ throws SQLException {
+ Object id = container.addItem();
+ assertTrue(container.getItemIds().contains(id));
+ }
+
+ @Test
+ public void getContainerProperty_tableNewlyAddedItem_returnsPropertyOfNewlyAddedItem()
+ throws SQLException {
+ Object id = container.addItem();
+ Item item = container.getItem(id);
+ item.getItemProperty(NAME).setValue("asdf");
+ assertEquals("asdf", container.getContainerProperty(id, NAME)
+ .getValue());
+ }
+
+ @Test
+ public void containsId_tableNewlyAddedItem_returnsTrue()
+ throws SQLException {
+ Object id = container.addItem();
+
+ assertTrue(container.containsId(id));
+ }
+
+ @Test
+ public void prevItemId_tableTwoNewlyAddedItems_returnsFirstAddedItem()
+ throws SQLException {
+ Object id1 = container.addItem();
+ Object id2 = container.addItem();
+
+ assertEquals(id1, container.prevItemId(id2));
+ }
+
+ @Test
+ public void firstItemId_tableEmptyResultSet_returnsFirstAddedItem()
+ throws SQLException {
+ SQLContainer garbageContainer = getGarbageContainer();
+
+ Object id = garbageContainer.addItem();
+
+ Assert.assertSame(id, garbageContainer.firstItemId());
+ }
+
+ @Test
+ public void isFirstId_tableEmptyResultSet_returnsFirstAddedItem()
+ throws SQLException {
+ SQLContainer garbageContainer = getGarbageContainer();
+
+ Object id = garbageContainer.addItem();
+
+ assertTrue(garbageContainer.isFirstId(id));
+ }
+
+ @Test
+ public void isLastId_tableOneItemAdded_returnsTrueForAddedItem()
+ throws SQLException {
+ Object id = container.addItem();
+
+ assertTrue(container.isLastId(id));
+ }
+
+ @Test
+ public void isLastId_tableTwoItemsAdded_returnsTrueForLastAddedItem()
+ throws SQLException {
+ container.addItem();
+
+ Object id2 = container.addItem();
+
+ assertTrue(container.isLastId(id2));
+ }
+
+ @Test
+ public void getIdByIndex_tableOneItemAddedLastIndexInContainer_returnsAddedItem()
+ throws SQLException {
+ Object id = container.addItem();
+
+ assertEquals(id, container.getIdByIndex(container.size() - 1));
+ }
+
+ @Test
+ public void removeItem_tableNoAddedItems_removesItemFromContainer()
+ throws SQLException {
+ int originalSize = container.size();
+ Object id = container.firstItemId();
+
+ assertTrue(container.removeItem(id));
+
+ Assert.assertNotSame(id, container.firstItemId());
+ assertEquals(originalSize - 1, container.size());
+ }
+
+ @Test
+ public void containsId_tableRemovedItem_returnsFalse() throws SQLException {
+ Object id = container.firstItemId();
+ assertTrue(container.removeItem(id));
+ Assert.assertFalse(container.containsId(id));
+ }
+
+ @Test
+ public void removeItem_tableOneAddedItem_removesTheAddedItem()
+ throws SQLException {
+ Object id = container.addItem();
+ int size = container.size();
+
+ assertTrue(container.removeItem(id));
+ Assert.assertFalse(container.containsId(id));
+ assertEquals(size - 1, container.size());
+ }
+
+ @Test
+ public void getItem_tableItemRemoved_returnsNull() throws SQLException {
+ Object id = container.firstItemId();
+
+ assertTrue(container.removeItem(id));
+ Assert.assertNull(container.getItem(id));
+ }
+
+ @Test
+ public void getItem_tableAddedItemRemoved_returnsNull() throws SQLException {
+ Object id = container.addItem();
+
+ Assert.assertNotNull(container.getItem(id));
+ assertTrue(container.removeItem(id));
+ Assert.assertNull(container.getItem(id));
+ }
+
+ @Test
+ public void getItemIds_tableItemRemoved_shouldNotContainRemovedItem()
+ throws SQLException {
+ Object id = container.firstItemId();
+
+ assertTrue(container.getItemIds().contains(id));
+ assertTrue(container.removeItem(id));
+ Assert.assertFalse(container.getItemIds().contains(id));
+ }
+
+ @Test
+ public void getItemIds_tableAddedItemRemoved_shouldNotContainRemovedItem()
+ throws SQLException {
+ Object id = container.addItem();
+
+ assertTrue(container.getItemIds().contains(id));
+ assertTrue(container.removeItem(id));
+ Assert.assertFalse(container.getItemIds().contains(id));
+ }
+
+ @Test
+ public void containsId_tableItemRemoved_returnsFalse() throws SQLException {
+ Object id = container.firstItemId();
+
+ assertTrue(container.containsId(id));
+ assertTrue(container.removeItem(id));
+ Assert.assertFalse(container.containsId(id));
+ }
+
+ @Test
+ public void containsId_tableAddedItemRemoved_returnsFalse()
+ throws SQLException {
+ Object id = container.addItem();
+
+ assertTrue(container.containsId(id));
+ assertTrue(container.removeItem(id));
+ Assert.assertFalse(container.containsId(id));
+ }
+
+ @Test
+ public void nextItemId_tableItemRemoved_skipsRemovedItem()
+ throws SQLException {
+ Object first = container.getIdByIndex(0);
+ Object second = container.getIdByIndex(1);
+ Object third = container.getIdByIndex(2);
+
+ assertTrue(container.removeItem(second));
+ assertEquals(third, container.nextItemId(first));
+ }
+
+ @Test
+ public void nextItemId_tableAddedItemRemoved_skipsRemovedItem()
+ throws SQLException {
+ Object first = container.lastItemId();
+ Object second = container.addItem();
+ Object third = container.addItem();
+
+ assertTrue(container.removeItem(second));
+ assertEquals(third, container.nextItemId(first));
+ }
+
+ @Test
+ public void prevItemId_tableItemRemoved_skipsRemovedItem()
+ throws SQLException {
+ Object first = container.getIdByIndex(0);
+ Object second = container.getIdByIndex(1);
+ Object third = container.getIdByIndex(2);
+
+ assertTrue(container.removeItem(second));
+ assertEquals(first, container.prevItemId(third));
+ }
+
+ @Test
+ public void prevItemId_tableAddedItemRemoved_skipsRemovedItem()
+ throws SQLException {
+ Object first = container.lastItemId();
+ Object second = container.addItem();
+ Object third = container.addItem();
+
+ assertTrue(container.removeItem(second));
+ assertEquals(first, container.prevItemId(third));
+ }
+
+ @Test
+ public void firstItemId_tableFirstItemRemoved_resultChanges()
+ throws SQLException {
+ Object first = container.firstItemId();
+
+ assertTrue(container.removeItem(first));
+ Assert.assertNotSame(first, container.firstItemId());
+ }
+
+ @Test
+ public void firstItemId_tableNewlyAddedFirstItemRemoved_resultChanges()
+ throws SQLException {
+ SQLContainer garbageContainer = getGarbageContainer();
+
+ Object first = garbageContainer.addItem();
+ Object second = garbageContainer.addItem();
+
+ Assert.assertSame(first, garbageContainer.firstItemId());
+ assertTrue(garbageContainer.removeItem(first));
+ Assert.assertSame(second, garbageContainer.firstItemId());
+ }
+
+ @Test
+ public void lastItemId_tableLastItemRemoved_resultChanges()
+ throws SQLException {
+ Object last = container.lastItemId();
+
+ assertTrue(container.removeItem(last));
+ Assert.assertNotSame(last, container.lastItemId());
+ }
+
+ @Test
+ public void lastItemId_tableAddedLastItemRemoved_resultChanges()
+ throws SQLException {
+ Object last = container.addItem();
+
+ Assert.assertSame(last, container.lastItemId());
+ assertTrue(container.removeItem(last));
+ Assert.assertNotSame(last, container.lastItemId());
+ }
+
+ @Test
+ public void isFirstId_tableFirstItemRemoved_returnsFalse()
+ throws SQLException {
+ Object first = container.firstItemId();
+
+ assertTrue(container.removeItem(first));
+ Assert.assertFalse(container.isFirstId(first));
+ }
+
+ @Test
+ public void isFirstId_tableAddedFirstItemRemoved_returnsFalse()
+ throws SQLException {
+ SQLContainer garbageContainer = getGarbageContainer();
+
+ Object first = garbageContainer.addItem();
+ garbageContainer.addItem();
+
+ Assert.assertSame(first, garbageContainer.firstItemId());
+ assertTrue(garbageContainer.removeItem(first));
+ Assert.assertFalse(garbageContainer.isFirstId(first));
+ }
+
+ @Test
+ public void isLastId_tableLastItemRemoved_returnsFalse()
+ throws SQLException {
+ Object last = container.lastItemId();
+
+ assertTrue(container.removeItem(last));
+ Assert.assertFalse(container.isLastId(last));
+ }
+
+ @Test
+ public void isLastId_tableAddedLastItemRemoved_returnsFalse()
+ throws SQLException {
+ Object last = container.addItem();
+
+ Assert.assertSame(last, container.lastItemId());
+ assertTrue(container.removeItem(last));
+ Assert.assertFalse(container.isLastId(last));
+ }
+
+ @Test
+ public void indexOfId_tableItemRemoved_returnsNegOne() throws SQLException {
+ Object id = container.getIdByIndex(2);
+
+ assertTrue(container.removeItem(id));
+ assertEquals(-1, container.indexOfId(id));
+ }
+
+ @Test
+ public void indexOfId_tableAddedItemRemoved_returnsNegOne()
+ throws SQLException {
+ Object id = container.addItem();
+
+ assertTrue(container.indexOfId(id) != -1);
+ assertTrue(container.removeItem(id));
+ assertEquals(-1, container.indexOfId(id));
+ }
+
+ @Test
+ public void getIdByIndex_tableItemRemoved_resultChanges()
+ throws SQLException {
+ Object id = container.getIdByIndex(2);
+
+ assertTrue(container.removeItem(id));
+ Assert.assertNotSame(id, container.getIdByIndex(2));
+ }
+
+ @Test
+ public void getIdByIndex_tableAddedItemRemoved_resultChanges()
+ throws SQLException {
+ Object id = container.addItem();
+ container.addItem();
+ int index = container.indexOfId(id);
+
+ assertTrue(container.removeItem(id));
+ Assert.assertNotSame(id, container.getIdByIndex(index));
+ }
+
+ @Test
+ public void removeAllItems_table_shouldSucceed() throws SQLException {
+ assertTrue(container.removeAllItems());
+ assertEquals(0, container.size());
+ }
+
+ @Test
+ public void removeAllItems_tableAddedItems_shouldSucceed()
+ throws SQLException {
+ container.addItem();
+ container.addItem();
+
+ assertTrue(container.removeAllItems());
+ assertEquals(0, container.size());
+ }
+
+ // Set timeout to ensure there is no infinite looping (#12882)
+ @Test(timeout = 1000)
+ public void removeAllItems_manyItems_commit_shouldSucceed()
+ throws SQLException {
+ final int itemNumber = (SQLContainer.CACHE_RATIO + 1)
+ * SQLContainer.DEFAULT_PAGE_LENGTH + 1;
+
+ container.removeAllItems();
+
+ assertEquals(container.size(), 0);
+ for (int i = 0; i < itemNumber; ++i) {
+ container.addItem();
+ }
+ container.commit();
+ assertEquals(container.size(), itemNumber);
+ assertTrue(container.removeAllItems());
+ container.commit();
+ assertEquals(container.size(), 0);
+ }
+
+ @Test
+ public void commit_tableAddedItem_shouldBeWrittenToDB() throws SQLException {
+ Object id = container.addItem();
+ container.getContainerProperty(id, NAME).setValue("New Name");
+
+ assertTrue(id instanceof TemporaryRowId);
+ Assert.assertSame(id, container.lastItemId());
+ container.commit();
+ Assert.assertFalse(container.lastItemId() instanceof TemporaryRowId);
+ assertEquals("New Name",
+ container.getContainerProperty(container.lastItemId(), NAME)
+ .getValue());
+ }
+
+ @Test
+ public void commit_tableTwoAddedItems_shouldBeWrittenToDB()
+ throws SQLException {
+ Object id = container.addItem();
+ Object id2 = container.addItem();
+ container.getContainerProperty(id, NAME).setValue("Herbert");
+ container.getContainerProperty(id2, NAME).setValue("Larry");
+ assertTrue(id2 instanceof TemporaryRowId);
+ Assert.assertSame(id2, container.lastItemId());
+ container.commit();
+ Object nextToLast = container.getIdByIndex(container.size() - 2);
+
+ Assert.assertFalse(nextToLast instanceof TemporaryRowId);
+ assertEquals("Herbert", container
+ .getContainerProperty(nextToLast, NAME).getValue());
+ Assert.assertFalse(container.lastItemId() instanceof TemporaryRowId);
+ assertEquals("Larry",
+ container.getContainerProperty(container.lastItemId(), NAME)
+ .getValue());
+ }
+
+ @Test
+ public void commit_tableRemovedItem_shouldBeRemovedFromDB()
+ throws SQLException {
+ Object last = container.lastItemId();
+ container.removeItem(last);
+ container.commit();
+
+ Assert.assertFalse(last.equals(container.lastItemId()));
+ }
+
+ @Test
+ public void commit_tableLastItemUpdated_shouldUpdateRowInDB()
+ throws SQLException {
+ Object last = container.lastItemId();
+ container.getContainerProperty(last, NAME).setValue("Donald");
+ container.commit();
+
+ assertEquals("Donald",
+ container.getContainerProperty(container.lastItemId(), NAME)
+ .getValue());
+ }
+
+ @Test
+ public void commit_removeModifiedItem_shouldSucceed() throws SQLException {
+ int size = container.size();
+ Object key = container.firstItemId();
+ Item row = container.getItem(key);
+ row.getItemProperty(NAME).setValue("Pekka");
+
+ assertTrue(container.removeItem(key));
+ container.commit();
+ assertEquals(size - 1, container.size());
+ }
+
+ @Test
+ public void rollback_tableItemAdded_discardsAddedItem() throws SQLException {
+ int size = container.size();
+ Object id = container.addItem();
+ container.getContainerProperty(id, NAME).setValue("foo");
+ assertEquals(size + 1, container.size());
+ container.rollback();
+ assertEquals(size, container.size());
+ Assert.assertFalse("foo".equals(container.getContainerProperty(
+ container.lastItemId(), NAME).getValue()));
+ }
+
+ @Test
+ public void rollback_tableItemRemoved_restoresRemovedItem()
+ throws SQLException {
+ int size = container.size();
+ Object last = container.lastItemId();
+ container.removeItem(last);
+ assertEquals(size - 1, container.size());
+ container.rollback();
+ assertEquals(size, container.size());
+ assertEquals(last, container.lastItemId());
+ }
+
+ @Test
+ public void rollback_tableItemChanged_discardsChanges() throws SQLException {
+ Object last = container.lastItemId();
+ container.getContainerProperty(last, NAME).setValue("foo");
+ container.rollback();
+ Assert.assertFalse("foo".equals(container.getContainerProperty(
+ container.lastItemId(), NAME).getValue()));
+ }
+
+ @Test
+ public void itemChangeNotification_table_isModifiedReturnsTrue()
+ throws SQLException {
+ Assert.assertFalse(container.isModified());
+ RowItem last = (RowItem) container.getItem(container.lastItemId());
+ container.itemChangeNotification(last);
+ assertTrue(container.isModified());
+ }
+
+ @Test
+ public void itemSetChangeListeners_table_shouldFire() throws SQLException {
+ ItemSetChangeListener listener = EasyMock
+ .createMock(ItemSetChangeListener.class);
+ listener.containerItemSetChange(EasyMock.isA(ItemSetChangeEvent.class));
+ EasyMock.replay(listener);
+
+ container.addListener(listener);
+ container.addItem();
+
+ EasyMock.verify(listener);
+ }
+
+ @Test
+ public void itemSetChangeListeners_tableItemRemoved_shouldFire()
+ throws SQLException {
+ ItemSetChangeListener listener = EasyMock
+ .createMock(ItemSetChangeListener.class);
+ listener.containerItemSetChange(EasyMock.isA(ItemSetChangeEvent.class));
+ EasyMock.expectLastCall().anyTimes();
+ EasyMock.replay(listener);
+
+ container.addListener(listener);
+ container.removeItem(container.lastItemId());
+
+ EasyMock.verify(listener);
+ }
+
+ @Test
+ public void removeListener_table_shouldNotFire() throws SQLException {
+ ItemSetChangeListener listener = EasyMock
+ .createMock(ItemSetChangeListener.class);
+ EasyMock.replay(listener);
+
+ container.addListener(listener);
+ container.removeListener(listener);
+ container.addItem();
+
+ EasyMock.verify(listener);
+ }
+
+ @Test
+ public void isModified_tableRemovedItem_returnsTrue() throws SQLException {
+ Assert.assertFalse(container.isModified());
+ container.removeItem(container.lastItemId());
+ assertTrue(container.isModified());
+ }
+
+ @Test
+ public void isModified_tableAddedItem_returnsTrue() throws SQLException {
+ Assert.assertFalse(container.isModified());
+ container.addItem();
+ assertTrue(container.isModified());
+ }
+
+ @Test
+ public void isModified_tableChangedItem_returnsTrue() throws SQLException {
+ Assert.assertFalse(container.isModified());
+ container.getContainerProperty(container.lastItemId(), NAME).setValue(
+ "foo");
+ assertTrue(container.isModified());
+ }
+
+ @Test
+ public void getSortableContainerPropertyIds_table_returnsAllPropertyIds()
+ throws SQLException {
+ Collection<?> sortableIds = container.getSortableContainerPropertyIds();
+ assertTrue(sortableIds.contains(ID));
+ assertTrue(sortableIds.contains(NAME));
+ assertTrue(sortableIds.contains("AGE"));
+ assertEquals(3, sortableIds.size());
+ if (SQLTestsConstants.db == DB.MSSQL
+ || SQLTestsConstants.db == DB.ORACLE) {
+ Assert.assertFalse(sortableIds.contains("rownum"));
+ }
+ }
+
+ @Test
+ public void addOrderBy_table_shouldReorderResults() throws SQLException {
+ // Ville, Kalle, Pelle, Börje
+ assertEquals("Ville",
+ container.getContainerProperty(container.firstItemId(), NAME)
+ .getValue());
+ assertEquals("Börje",
+ container.getContainerProperty(container.lastItemId(), NAME)
+ .getValue());
+
+ container.addOrderBy(new OrderBy(NAME, true));
+ // Börje, Kalle, Pelle, Ville
+ assertEquals("Börje",
+ container.getContainerProperty(container.firstItemId(), NAME)
+ .getValue());
+ assertEquals("Ville",
+ container.getContainerProperty(container.lastItemId(), NAME)
+ .getValue());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void addOrderBy_tableIllegalColumn_shouldFail() throws SQLException {
+ container.addOrderBy(new OrderBy("asdf", true));
+ }
+
+ @Test
+ public void sort_table_sortsByName() throws SQLException {
+ // Ville, Kalle, Pelle, Börje
+ assertEquals("Ville",
+ container.getContainerProperty(container.firstItemId(), NAME)
+ .getValue());
+ assertEquals("Börje",
+ container.getContainerProperty(container.lastItemId(), NAME)
+ .getValue());
+
+ container.sort(new Object[] { NAME }, new boolean[] { true });
+
+ // Börje, Kalle, Pelle, Ville
+ assertEquals("Börje",
+ container.getContainerProperty(container.firstItemId(), NAME)
+ .getValue());
+ assertEquals("Ville",
+ container.getContainerProperty(container.lastItemId(), NAME)
+ .getValue());
+ }
+
+ @Test
+ public void addFilter_table_filtersResults() throws SQLException {
+ // Ville, Kalle, Pelle, Börje
+ assertEquals(4, container.size());
+ assertEquals("Börje",
+ container.getContainerProperty(container.lastItemId(), NAME)
+ .getValue());
+
+ container.addContainerFilter(new Like(NAME, "%lle"));
+ // Ville, Kalle, Pelle
+ assertEquals(3, container.size());
+ assertEquals("Pelle",
+ container.getContainerProperty(container.lastItemId(), NAME)
+ .getValue());
+ }
+
+ @Test
+ public void addContainerFilter_filtersResults() throws SQLException {
+ // Ville, Kalle, Pelle, Börje
+ assertEquals(4, container.size());
+
+ container.addContainerFilter(NAME, "Vi", false, false);
+
+ // Ville
+ assertEquals(1, container.size());
+ assertEquals("Ville",
+ container.getContainerProperty(container.lastItemId(), NAME)
+ .getValue());
+ }
+
+ @Test
+ public void addContainerFilter_ignoreCase_filtersResults()
+ throws SQLException {
+ // Ville, Kalle, Pelle, Börje
+ assertEquals(4, container.size());
+
+ container.addContainerFilter(NAME, "vi", true, false);
+
+ // Ville
+ assertEquals(1, container.size());
+ assertEquals("Ville",
+ container.getContainerProperty(container.lastItemId(), NAME)
+ .getValue());
+ }
+
+ @Test
+ public void removeAllContainerFilters_table_noFiltering()
+ throws SQLException {
+ // Ville, Kalle, Pelle, Börje
+ assertEquals(4, container.size());
+
+ container.addContainerFilter(NAME, "Vi", false, false);
+
+ // Ville
+ assertEquals(1, container.size());
+ assertEquals("Ville",
+ container.getContainerProperty(container.lastItemId(), NAME)
+ .getValue());
+
+ container.removeAllContainerFilters();
+
+ assertEquals(4, container.size());
+ assertEquals("Börje",
+ container.getContainerProperty(container.lastItemId(), NAME)
+ .getValue());
+ }
+
+ @Test
+ public void removeContainerFilters_table_noFiltering() throws SQLException {
+ // Ville, Kalle, Pelle, Börje
+ assertEquals(4, container.size());
+
+ container.addContainerFilter(NAME, "Vi", false, false);
+
+ // Ville
+ assertEquals(1, container.size());
+ assertEquals("Ville",
+ container.getContainerProperty(container.lastItemId(), NAME)
+ .getValue());
+
+ container.removeContainerFilters(NAME);
+
+ assertEquals(4, container.size());
+ assertEquals("Börje",
+ container.getContainerProperty(container.lastItemId(), NAME)
+ .getValue());
+ }
+
+ @Test
+ public void addFilter_tableBufferedItems_alsoFiltersBufferedItems()
+ throws SQLException {
+ // Ville, Kalle, Pelle, Börje
+ assertEquals(4, container.size());
+ assertEquals("Börje",
+ container.getContainerProperty(container.lastItemId(), NAME)
+ .getValue());
+
+ Object id1 = container.addItem();
+ container.getContainerProperty(id1, NAME).setValue("Palle");
+ Object id2 = container.addItem();
+ container.getContainerProperty(id2, NAME).setValue("Bengt");
+
+ container.addContainerFilter(new Like(NAME, "%lle"));
+
+ // Ville, Kalle, Pelle, Palle
+ assertEquals(4, container.size());
+ assertEquals("Ville",
+ container.getContainerProperty(container.getIdByIndex(0), NAME)
+ .getValue());
+ assertEquals("Kalle",
+ container.getContainerProperty(container.getIdByIndex(1), NAME)
+ .getValue());
+ assertEquals("Pelle",
+ container.getContainerProperty(container.getIdByIndex(2), NAME)
+ .getValue());
+ assertEquals("Palle",
+ container.getContainerProperty(container.getIdByIndex(3), NAME)
+ .getValue());
+
+ try {
+ container.getIdByIndex(4);
+ Assert.fail("SQLContainer.getIdByIndex() returned a value for an index beyond the end of the container");
+ } catch (IndexOutOfBoundsException e) {
+ // should throw exception - item is filtered out
+ }
+ Assert.assertNull(container.nextItemId(container.getIdByIndex(3)));
+
+ Assert.assertFalse(container.containsId(id2));
+ Assert.assertFalse(container.getItemIds().contains(id2));
+
+ Assert.assertNull(container.getItem(id2));
+ assertEquals(-1, container.indexOfId(id2));
+
+ Assert.assertNotSame(id2, container.lastItemId());
+ Assert.assertSame(id1, container.lastItemId());
+ }
+
+ @Test
+ public void sort_tableBufferedItems_sortsBufferedItemsLastInOrderAdded()
+ throws SQLException {
+ // Ville, Kalle, Pelle, Börje
+ assertEquals("Ville",
+ container.getContainerProperty(container.firstItemId(), NAME)
+ .getValue());
+ assertEquals("Börje",
+ container.getContainerProperty(container.lastItemId(), NAME)
+ .getValue());
+
+ Object id1 = container.addItem();
+ container.getContainerProperty(id1, NAME).setValue("Wilbert");
+ Object id2 = container.addItem();
+ container.getContainerProperty(id2, NAME).setValue("Albert");
+
+ container.sort(new Object[] { NAME }, new boolean[] { true });
+
+ // Börje, Kalle, Pelle, Ville, Wilbert, Albert
+ assertEquals("Börje",
+ container.getContainerProperty(container.firstItemId(), NAME)
+ .getValue());
+ assertEquals(
+ "Wilbert",
+ container.getContainerProperty(
+ container.getIdByIndex(container.size() - 2), NAME)
+ .getValue());
+ assertEquals("Albert",
+ container.getContainerProperty(container.lastItemId(), NAME)
+ .getValue());
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLContainerTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLContainerTest.java
new file mode 100644
index 0000000000..a332d9d9ee
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLContainerTest.java
@@ -0,0 +1,2477 @@
+package com.vaadin.data.util.sqlcontainer;
+
+import java.math.BigDecimal;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.logging.Handler;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.Container.Filter;
+import com.vaadin.data.Container.ItemSetChangeEvent;
+import com.vaadin.data.Container.ItemSetChangeListener;
+import com.vaadin.data.Item;
+import com.vaadin.data.util.filter.Compare.Equal;
+import com.vaadin.data.util.filter.Like;
+import com.vaadin.data.util.sqlcontainer.SQLTestsConstants.DB;
+import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool;
+import com.vaadin.data.util.sqlcontainer.query.FreeformQuery;
+import com.vaadin.data.util.sqlcontainer.query.FreeformQueryDelegate;
+import com.vaadin.data.util.sqlcontainer.query.FreeformStatementDelegate;
+import com.vaadin.data.util.sqlcontainer.query.OrderBy;
+import com.vaadin.data.util.sqlcontainer.query.ValidatingSimpleJDBCConnectionPool;
+import com.vaadin.data.util.sqlcontainer.query.generator.MSSQLGenerator;
+import com.vaadin.data.util.sqlcontainer.query.generator.OracleGenerator;
+import com.vaadin.data.util.sqlcontainer.query.generator.SQLGenerator;
+import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
+import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder;
+
+public class SQLContainerTest {
+ private static final int offset = SQLTestsConstants.offset;
+ private JDBCConnectionPool connectionPool;
+
+ @Before
+ public void setUp() throws SQLException {
+
+ try {
+ connectionPool = new ValidatingSimpleJDBCConnectionPool(
+ SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL,
+ SQLTestsConstants.dbUser, SQLTestsConstants.dbPwd, 2, 2);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ Assert.fail(e.getMessage());
+ }
+
+ DataGenerator.addPeopleToDatabase(connectionPool);
+ }
+
+ @After
+ public void tearDown() {
+ if (connectionPool != null) {
+ connectionPool.destroy();
+ }
+ }
+
+ @Test
+ public void constructor_withFreeformQuery_shouldSucceed()
+ throws SQLException {
+ new SQLContainer(new FreeformQuery("SELECT * FROM people",
+ connectionPool, "ID"));
+ }
+
+ @Test(expected = SQLException.class)
+ public void constructor_withIllegalFreeformQuery_shouldFail()
+ throws SQLException {
+ SQLContainer c = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM asdf", connectionPool, "ID"));
+ c.getItem(c.firstItemId());
+ }
+
+ @Test
+ public void containsId_withFreeformQueryAndExistingId_returnsTrue()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Assert.assertTrue(container.containsId(new RowId(new Object[] { 1 })));
+ }
+
+ @Test
+ public void containsId_withFreeformQueryAndNonexistingId_returnsFalse()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Assert.assertFalse(container
+ .containsId(new RowId(new Object[] { 1337 })));
+ }
+
+ @Test
+ public void getContainerProperty_freeformExistingItemIdAndPropertyId_returnsProperty()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ Assert.assertEquals(
+ "Ville",
+ container
+ .getContainerProperty(
+ new RowId(new Object[] { new BigDecimal(
+ 0 + offset) }), "NAME").getValue());
+ } else {
+ Assert.assertEquals(
+ "Ville",
+ container.getContainerProperty(
+ new RowId(new Object[] { 0 + offset }), "NAME")
+ .getValue());
+ }
+ }
+
+ @Test
+ public void getContainerProperty_freeformExistingItemIdAndNonexistingPropertyId_returnsNull()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Assert.assertNull(container.getContainerProperty(new RowId(
+ new Object[] { 1 + offset }), "asdf"));
+ }
+
+ @Test
+ public void getContainerProperty_freeformNonexistingItemId_returnsNull()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Assert.assertNull(container.getContainerProperty(new RowId(
+ new Object[] { 1337 + offset }), "NAME"));
+ }
+
+ @Test
+ public void getContainerPropertyIds_freeform_returnsIDAndNAME()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Collection<?> propertyIds = container.getContainerPropertyIds();
+ Assert.assertEquals(3, propertyIds.size());
+ Assert.assertArrayEquals(new String[] { "ID", "NAME", "AGE" },
+ propertyIds.toArray());
+ }
+
+ @Test
+ public void getItem_freeformExistingItemId_returnsItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Item item;
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ item = container.getItem(new RowId(new Object[] { new BigDecimal(
+ 0 + offset) }));
+ } else {
+ item = container.getItem(new RowId(new Object[] { 0 + offset }));
+ }
+ Assert.assertNotNull(item);
+ Assert.assertEquals("Ville", item.getItemProperty("NAME").getValue());
+ }
+
+ @Test
+ public void nextItemNullAtEnd_freeformExistingItem() throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object lastItemId = container.lastItemId();
+ Object afterLast = container.nextItemId(lastItemId);
+ Assert.assertNull(afterLast);
+ }
+
+ @Test
+ public void prevItemNullAtStart_freeformExistingItem() throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object firstItemId = container.firstItemId();
+ Object beforeFirst = container.prevItemId(firstItemId);
+ Assert.assertNull(beforeFirst);
+ }
+
+ @Test
+ public void getItem_freeform5000RowsWithParameter1337_returnsItemWithId1337()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Item item;
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ item = container.getItem(new RowId(new Object[] { new BigDecimal(
+ 1337 + offset) }));
+ Assert.assertNotNull(item);
+ Assert.assertEquals(new BigDecimal(1337 + offset), item
+ .getItemProperty("ID").getValue());
+ } else {
+ item = container.getItem(new RowId(new Object[] { 1337 + offset }));
+ Assert.assertNotNull(item);
+ Assert.assertEquals(1337 + offset, item.getItemProperty("ID")
+ .getValue());
+ }
+ Assert.assertEquals("Person 1337", item.getItemProperty("NAME")
+ .getValue());
+ }
+
+ @Test
+ public void getItemIds_freeform_returnsItemIdsWithKeys0through3()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Collection<?> itemIds = container.getItemIds();
+ Assert.assertEquals(4, itemIds.size());
+ RowId zero = new RowId(new Object[] { 0 + offset });
+ RowId one = new RowId(new Object[] { 1 + offset });
+ RowId two = new RowId(new Object[] { 2 + offset });
+ RowId three = new RowId(new Object[] { 3 + offset });
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ String[] correct = new String[] { "1", "2", "3", "4" };
+ List<String> oracle = new ArrayList<String>();
+ for (Object o : itemIds) {
+ oracle.add(o.toString());
+ }
+ Assert.assertArrayEquals(correct, oracle.toArray());
+ } else {
+ Assert.assertArrayEquals(new Object[] { zero, one, two, three },
+ itemIds.toArray());
+ }
+ }
+
+ @Test
+ public void getType_freeformNAMEPropertyId_returnsString()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Assert.assertEquals(String.class, container.getType("NAME"));
+ }
+
+ @Test
+ public void getType_freeformIDPropertyId_returnsInteger()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ Assert.assertEquals(BigDecimal.class, container.getType("ID"));
+ } else {
+ Assert.assertEquals(Integer.class, container.getType("ID"));
+ }
+ }
+
+ @Test
+ public void getType_freeformNonexistingPropertyId_returnsNull()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Assert.assertNull(container.getType("asdf"));
+ }
+
+ @Test
+ public void size_freeform_returnsFour() throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Assert.assertEquals(4, container.size());
+ }
+
+ @Test
+ public void size_freeformOneAddedItem_returnsFive() throws SQLException {
+ Connection conn = connectionPool.reserveConnection();
+ Statement statement = conn.createStatement();
+ if (SQLTestsConstants.db == DB.MSSQL) {
+ statement.executeUpdate("insert into people values('Bengt', '42')");
+ } else {
+ statement
+ .executeUpdate("insert into people values(default, 'Bengt', '42')");
+ }
+ statement.close();
+ conn.commit();
+ connectionPool.releaseConnection(conn);
+
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Assert.assertEquals(5, container.size());
+ }
+
+ @Test
+ public void indexOfId_freeformWithParameterThree_returnsThree()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ Assert.assertEquals(3, container.indexOfId(new RowId(
+ new Object[] { new BigDecimal(3 + offset) })));
+ } else {
+ Assert.assertEquals(3,
+ container.indexOfId(new RowId(new Object[] { 3 + offset })));
+ }
+ }
+
+ @Test
+ public void indexOfId_freeform5000RowsWithParameter1337_returns1337()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people ORDER BY \"ID\" ASC", connectionPool,
+ "ID"));
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ container.getItem(new RowId(new Object[] { new BigDecimal(
+ 1337 + offset) }));
+ Assert.assertEquals(1337, container.indexOfId(new RowId(
+ new Object[] { new BigDecimal(1337 + offset) })));
+ } else {
+ container.getItem(new RowId(new Object[] { 1337 + offset }));
+ Assert.assertEquals(1337, container.indexOfId(new RowId(
+ new Object[] { 1337 + offset })));
+ }
+ }
+
+ @Test
+ public void getIdByIndex_freeform5000rowsIndex1337_returnsRowId1337()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people ORDER BY \"ID\" ASC", connectionPool,
+ "ID"));
+ Object itemId = container.getIdByIndex(1337);
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ Assert.assertEquals(new RowId(new Object[] { new BigDecimal(
+ 1337 + offset) }), itemId);
+ } else {
+ Assert.assertEquals(new RowId(new Object[] { 1337 + offset }),
+ itemId);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void getIdByIndex_freeformWithPaging5000rowsIndex1337_returnsRowId1337()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ connectionPool, "ID");
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ EasyMock.expect(
+ delegate.getQueryString(EasyMock.anyInt(), EasyMock.anyInt()))
+ .andAnswer(new IAnswer<String>() {
+ @Override
+ public String answer() throws Throwable {
+ Object[] args = EasyMock.getCurrentArguments();
+ int offset = (Integer) (args[0]);
+ int limit = (Integer) (args[1]);
+ if (SQLTestsConstants.db == DB.MSSQL) {
+ int start = offset + 1;
+ int end = offset + limit + 1;
+ String q = "SELECT * FROM (SELECT row_number() OVER"
+ + " ( ORDER BY \"ID\" ASC) AS rownum, * FROM people)"
+ + " AS a WHERE a.rownum BETWEEN "
+ + start
+ + " AND " + end;
+ return q;
+ } else if (SQLTestsConstants.db == DB.ORACLE) {
+ int start = offset + 1;
+ int end = offset + limit + 1;
+ String q = "SELECT * FROM (SELECT x.*, ROWNUM AS r FROM"
+ + " (SELECT * FROM people ORDER BY \"ID\" ASC) x) "
+ + " WHERE r BETWEEN "
+ + start
+ + " AND "
+ + end;
+ return q;
+ } else {
+ return "SELECT * FROM people LIMIT " + limit
+ + " OFFSET " + offset;
+ }
+ }
+ }).anyTimes();
+ delegate.setFilters(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setFilters(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().anyTimes();
+ EasyMock.expect(delegate.getCountQuery())
+ .andThrow(new UnsupportedOperationException()).anyTimes();
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+ SQLContainer container = new SQLContainer(query);
+ Object itemId = container.getIdByIndex(1337);
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ Assert.assertEquals(
+ new RowId(new Object[] { 1337 + offset }).toString(),
+ itemId.toString());
+ } else {
+ Assert.assertEquals(new RowId(new Object[] { 1337 + offset }),
+ itemId);
+ }
+ }
+
+ @Test
+ public void nextItemId_freeformCurrentItem1337_returnsItem1338()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people ORDER BY \"ID\" ASC", connectionPool,
+ "ID"));
+ Object itemId = container.getIdByIndex(1337);
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ Assert.assertEquals(
+ new RowId(new Object[] { 1338 + offset }).toString(),
+ container.nextItemId(itemId).toString());
+ } else {
+ Assert.assertEquals(new RowId(new Object[] { 1338 + offset }),
+ container.nextItemId(itemId));
+ }
+ }
+
+ @Test
+ public void prevItemId_freeformCurrentItem1337_returns1336()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people ORDER BY \"ID\" ASC", connectionPool,
+ "ID"));
+ Object itemId = container.getIdByIndex(1337);
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ Assert.assertEquals(
+ new RowId(new Object[] { 1336 + offset }).toString(),
+ container.prevItemId(itemId).toString());
+ } else {
+ Assert.assertEquals(new RowId(new Object[] { 1336 + offset }),
+ container.prevItemId(itemId));
+ }
+ }
+
+ @Test
+ public void firstItemId_freeform_returnsItemId0() throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ Assert.assertEquals(
+ new RowId(new Object[] { 0 + offset }).toString(),
+ container.firstItemId().toString());
+ } else {
+ Assert.assertEquals(new RowId(new Object[] { 0 + offset }),
+ container.firstItemId());
+ }
+ }
+
+ @Test
+ public void lastItemId_freeform5000Rows_returnsItemId4999()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people ORDER BY \"ID\" ASC", connectionPool,
+ "ID"));
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ Assert.assertEquals(
+ new RowId(new Object[] { 4999 + offset }).toString(),
+ container.lastItemId().toString());
+ } else {
+ Assert.assertEquals(new RowId(new Object[] { 4999 + offset }),
+ container.lastItemId());
+ }
+ }
+
+ @Test
+ public void isFirstId_freeformActualFirstId_returnsTrue()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ Assert.assertTrue(container.isFirstId(new RowId(
+ new Object[] { new BigDecimal(0 + offset) })));
+ } else {
+ Assert.assertTrue(container.isFirstId(new RowId(
+ new Object[] { 0 + offset })));
+ }
+ }
+
+ @Test
+ public void isFirstId_freeformSecondId_returnsFalse() throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ Assert.assertFalse(container.isFirstId(new RowId(
+ new Object[] { new BigDecimal(1 + offset) })));
+ } else {
+ Assert.assertFalse(container.isFirstId(new RowId(
+ new Object[] { 1 + offset })));
+ }
+ }
+
+ @Test
+ public void isLastId_freeformSecondId_returnsFalse() throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ Assert.assertFalse(container.isLastId(new RowId(
+ new Object[] { new BigDecimal(1 + offset) })));
+ } else {
+ Assert.assertFalse(container.isLastId(new RowId(
+ new Object[] { 1 + offset })));
+ }
+ }
+
+ @Test
+ public void isLastId_freeformLastId_returnsTrue() throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ Assert.assertTrue(container.isLastId(new RowId(
+ new Object[] { new BigDecimal(3 + offset) })));
+ } else {
+ Assert.assertTrue(container.isLastId(new RowId(
+ new Object[] { 3 + offset })));
+ }
+ }
+
+ @Test
+ public void isLastId_freeform5000RowsLastId_returnsTrue()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people ORDER BY \"ID\" ASC", connectionPool,
+ "ID"));
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ Assert.assertTrue(container.isLastId(new RowId(
+ new Object[] { new BigDecimal(4999 + offset) })));
+ } else {
+ Assert.assertTrue(container.isLastId(new RowId(
+ new Object[] { 4999 + offset })));
+ }
+ }
+
+ @Test
+ public void refresh_freeform_sizeShouldUpdate() throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Assert.assertEquals(4, container.size());
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ container.refresh();
+ Assert.assertEquals(5000, container.size());
+ }
+
+ @Test
+ public void refresh_freeformWithoutCallingRefresh_sizeShouldNotUpdate()
+ throws SQLException {
+ // Yeah, this is a weird one. We're testing that the size doesn't update
+ // after adding lots of items unless we call refresh inbetween. This to
+ // make sure that the refresh method actually refreshes stuff and isn't
+ // a NOP.
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Assert.assertEquals(4, container.size());
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ Assert.assertEquals(4, container.size());
+ }
+
+ @Test
+ public void setAutoCommit_freeform_shouldSucceed() throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ container.setAutoCommit(true);
+ Assert.assertTrue(container.isAutoCommit());
+ container.setAutoCommit(false);
+ Assert.assertFalse(container.isAutoCommit());
+ }
+
+ @Test
+ public void getPageLength_freeform_returnsDefault100() throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Assert.assertEquals(100, container.getPageLength());
+ }
+
+ @Test
+ public void setPageLength_freeform_shouldSucceed() throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ container.setPageLength(20);
+ Assert.assertEquals(20, container.getPageLength());
+ container.setPageLength(200);
+ Assert.assertEquals(200, container.getPageLength());
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void addContainerProperty_normal_isUnsupported() throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ container.addContainerProperty("asdf", String.class, "");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void removeContainerProperty_normal_isUnsupported()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ container.removeContainerProperty("asdf");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void addItemObject_normal_isUnsupported() throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ container.addItem("asdf");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void addItemAfterObjectObject_normal_isUnsupported()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ container.addItemAfter("asdf", "foo");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void addItemAtIntObject_normal_isUnsupported() throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ container.addItemAt(2, "asdf");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void addItemAtInt_normal_isUnsupported() throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ container.addItemAt(2);
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void addItemAfterObject_normal_isUnsupported() throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ container.addItemAfter("asdf");
+ }
+
+ @Test
+ public void addItem_freeformAddOneNewItem_returnsItemId()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object itemId = container.addItem();
+ Assert.assertNotNull(itemId);
+ }
+
+ @Test
+ public void addItem_freeformAddOneNewItem_shouldChangeSize()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ int size = container.size();
+ container.addItem();
+ Assert.assertEquals(size + 1, container.size());
+ }
+
+ @Test
+ public void addItem_freeformAddTwoNewItems_shouldChangeSize()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ int size = container.size();
+ Object id1 = container.addItem();
+ Object id2 = container.addItem();
+ Assert.assertEquals(size + 2, container.size());
+ Assert.assertNotSame(id1, id2);
+ Assert.assertFalse(id1.equals(id2));
+ }
+
+ @Test
+ public void nextItemId_freeformNewlyAddedItem_returnsNewlyAdded()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object lastId = container.lastItemId();
+ Object id = container.addItem();
+ Assert.assertEquals(id, container.nextItemId(lastId));
+ }
+
+ @Test
+ public void lastItemId_freeformNewlyAddedItem_returnsNewlyAdded()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object lastId = container.lastItemId();
+ Object id = container.addItem();
+ Assert.assertEquals(id, container.lastItemId());
+ Assert.assertNotSame(lastId, container.lastItemId());
+ }
+
+ @Test
+ public void indexOfId_freeformNewlyAddedItem_returnsFour()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object id = container.addItem();
+ Assert.assertEquals(4, container.indexOfId(id));
+ }
+
+ @Test
+ public void getItem_freeformNewlyAddedItem_returnsNewlyAdded()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object id = container.addItem();
+ Assert.assertNotNull(container.getItem(id));
+ }
+
+ @Test
+ public void getItem_freeformNewlyAddedItemAndFiltered_returnsNull()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ container.addContainerFilter(new Equal("NAME", "asdf"));
+ Object id = container.addItem();
+ Assert.assertNull(container.getItem(id));
+ }
+
+ @Test
+ public void getItemUnfiltered_freeformNewlyAddedItemAndFiltered_returnsNewlyAdded()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ container.addContainerFilter(new Equal("NAME", "asdf"));
+ Object id = container.addItem();
+ Assert.assertNotNull(container.getItemUnfiltered(id));
+ }
+
+ @Test
+ public void getItemIds_freeformNewlyAddedItem_containsNewlyAdded()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object id = container.addItem();
+ Assert.assertTrue(container.getItemIds().contains(id));
+ }
+
+ @Test
+ public void getContainerProperty_freeformNewlyAddedItem_returnsPropertyOfNewlyAddedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object id = container.addItem();
+ Item item = container.getItem(id);
+ item.getItemProperty("NAME").setValue("asdf");
+ Assert.assertEquals("asdf", container.getContainerProperty(id, "NAME")
+ .getValue());
+ }
+
+ @Test
+ public void containsId_freeformNewlyAddedItem_returnsTrue()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object id = container.addItem();
+ Assert.assertTrue(container.containsId(id));
+ }
+
+ @Test
+ public void prevItemId_freeformTwoNewlyAddedItems_returnsFirstAddedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object id1 = container.addItem();
+ Object id2 = container.addItem();
+ Assert.assertEquals(id1, container.prevItemId(id2));
+ }
+
+ @Test
+ public void firstItemId_freeformEmptyResultSet_returnsFirstAddedItem()
+ throws SQLException {
+ DataGenerator.createGarbage(connectionPool);
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM GARBAGE", connectionPool, "ID"));
+ Object id = container.addItem();
+ Assert.assertSame(id, container.firstItemId());
+ }
+
+ @Test
+ public void isFirstId_freeformEmptyResultSet_returnsFirstAddedItem()
+ throws SQLException {
+ DataGenerator.createGarbage(connectionPool);
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM GARBAGE", connectionPool, "ID"));
+ Object id = container.addItem();
+ Assert.assertTrue(container.isFirstId(id));
+ }
+
+ @Test
+ public void isLastId_freeformOneItemAdded_returnsTrueForAddedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object id = container.addItem();
+ Assert.assertTrue(container.isLastId(id));
+ }
+
+ @Test
+ public void isLastId_freeformTwoItemsAdded_returnsTrueForLastAddedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ container.addItem();
+ Object id2 = container.addItem();
+ Assert.assertTrue(container.isLastId(id2));
+ }
+
+ @Test
+ public void getIdByIndex_freeformOneItemAddedLastIndexInContainer_returnsAddedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object id = container.addItem();
+ Assert.assertEquals(id, container.getIdByIndex(container.size() - 1));
+ }
+
+ @Test
+ public void removeItem_freeformNoAddedItems_removesItemFromContainer()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ int size = container.size();
+ Object id = container.firstItemId();
+ Assert.assertTrue(container.removeItem(id));
+ Assert.assertNotSame(id, container.firstItemId());
+ Assert.assertEquals(size - 1, container.size());
+ }
+
+ @Test
+ public void containsId_freeformRemovedItem_returnsFalse()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object id = container.firstItemId();
+ Assert.assertTrue(container.removeItem(id));
+ Assert.assertFalse(container.containsId(id));
+ }
+
+ @Test
+ public void containsId_unknownObject() throws SQLException {
+
+ Handler ensureNoLogging = new Handler() {
+
+ @Override
+ public void publish(LogRecord record) {
+ Assert.fail("No messages should be logged");
+
+ }
+
+ @Override
+ public void flush() {
+ }
+
+ @Override
+ public void close() throws SecurityException {
+ }
+ };
+
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Logger logger = Logger.getLogger(SQLContainer.class.getName());
+
+ logger.addHandler(ensureNoLogging);
+ try {
+ Assert.assertFalse(container.containsId(new Object()));
+ } finally {
+ logger.removeHandler(ensureNoLogging);
+ }
+ }
+
+ @Test
+ public void removeItem_freeformOneAddedItem_removesTheAddedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object id = container.addItem();
+ int size = container.size();
+ Assert.assertTrue(container.removeItem(id));
+ Assert.assertFalse(container.containsId(id));
+ Assert.assertEquals(size - 1, container.size());
+ }
+
+ @Test
+ public void getItem_freeformItemRemoved_returnsNull() throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object id = container.firstItemId();
+ Assert.assertTrue(container.removeItem(id));
+ Assert.assertNull(container.getItem(id));
+ }
+
+ @Test
+ public void getItem_freeformAddedItemRemoved_returnsNull()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object id = container.addItem();
+ Assert.assertNotNull(container.getItem(id));
+ Assert.assertTrue(container.removeItem(id));
+ Assert.assertNull(container.getItem(id));
+ }
+
+ @Test
+ public void getItemIds_freeformItemRemoved_shouldNotContainRemovedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object id = container.firstItemId();
+ Assert.assertTrue(container.getItemIds().contains(id));
+ Assert.assertTrue(container.removeItem(id));
+ Assert.assertFalse(container.getItemIds().contains(id));
+ }
+
+ @Test
+ public void getItemIds_freeformAddedItemRemoved_shouldNotContainRemovedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object id = container.addItem();
+ Assert.assertTrue(container.getItemIds().contains(id));
+ Assert.assertTrue(container.removeItem(id));
+ Assert.assertFalse(container.getItemIds().contains(id));
+ }
+
+ @Test
+ public void containsId_freeformItemRemoved_returnsFalse()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object id = container.firstItemId();
+ Assert.assertTrue(container.containsId(id));
+ Assert.assertTrue(container.removeItem(id));
+ Assert.assertFalse(container.containsId(id));
+ }
+
+ @Test
+ public void containsId_freeformAddedItemRemoved_returnsFalse()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object id = container.addItem();
+ Assert.assertTrue(container.containsId(id));
+ Assert.assertTrue(container.removeItem(id));
+ Assert.assertFalse(container.containsId(id));
+ }
+
+ @Test
+ public void nextItemId_freeformItemRemoved_skipsRemovedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object first = container.getIdByIndex(0);
+ Object second = container.getIdByIndex(1);
+ Object third = container.getIdByIndex(2);
+ Assert.assertTrue(container.removeItem(second));
+ Assert.assertEquals(third, container.nextItemId(first));
+ }
+
+ @Test
+ public void nextItemId_freeformAddedItemRemoved_skipsRemovedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object first = container.lastItemId();
+ Object second = container.addItem();
+ Object third = container.addItem();
+ Assert.assertTrue(container.removeItem(second));
+ Assert.assertEquals(third, container.nextItemId(first));
+ }
+
+ @Test
+ public void prevItemId_freeformItemRemoved_skipsRemovedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object first = container.getIdByIndex(0);
+ Object second = container.getIdByIndex(1);
+ Object third = container.getIdByIndex(2);
+ Assert.assertTrue(container.removeItem(second));
+ Assert.assertEquals(first, container.prevItemId(third));
+ }
+
+ @Test
+ public void prevItemId_freeformAddedItemRemoved_skipsRemovedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object first = container.lastItemId();
+ Object second = container.addItem();
+ Object third = container.addItem();
+ Assert.assertTrue(container.removeItem(second));
+ Assert.assertEquals(first, container.prevItemId(third));
+ }
+
+ @Test
+ public void firstItemId_freeformFirstItemRemoved_resultChanges()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object first = container.firstItemId();
+ Assert.assertTrue(container.removeItem(first));
+ Assert.assertNotSame(first, container.firstItemId());
+ }
+
+ @Test
+ public void firstItemId_freeformNewlyAddedFirstItemRemoved_resultChanges()
+ throws SQLException {
+ DataGenerator.createGarbage(connectionPool);
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM GARBAGE", connectionPool, "ID"));
+ Object first = container.addItem();
+ Object second = container.addItem();
+ Assert.assertSame(first, container.firstItemId());
+ Assert.assertTrue(container.removeItem(first));
+ Assert.assertSame(second, container.firstItemId());
+ }
+
+ @Test
+ public void lastItemId_freeformLastItemRemoved_resultChanges()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object last = container.lastItemId();
+ Assert.assertTrue(container.removeItem(last));
+ Assert.assertNotSame(last, container.lastItemId());
+ }
+
+ @Test
+ public void lastItemId_freeformAddedLastItemRemoved_resultChanges()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object last = container.addItem();
+ Assert.assertSame(last, container.lastItemId());
+ Assert.assertTrue(container.removeItem(last));
+ Assert.assertNotSame(last, container.lastItemId());
+ }
+
+ @Test
+ public void isFirstId_freeformFirstItemRemoved_returnsFalse()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object first = container.firstItemId();
+ Assert.assertTrue(container.removeItem(first));
+ Assert.assertFalse(container.isFirstId(first));
+ }
+
+ @Test
+ public void isFirstId_freeformAddedFirstItemRemoved_returnsFalse()
+ throws SQLException {
+ DataGenerator.createGarbage(connectionPool);
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM GARBAGE", connectionPool, "ID"));
+ Object first = container.addItem();
+ container.addItem();
+ Assert.assertSame(first, container.firstItemId());
+ Assert.assertTrue(container.removeItem(first));
+ Assert.assertFalse(container.isFirstId(first));
+ }
+
+ @Test
+ public void isLastId_freeformLastItemRemoved_returnsFalse()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object last = container.lastItemId();
+ Assert.assertTrue(container.removeItem(last));
+ Assert.assertFalse(container.isLastId(last));
+ }
+
+ @Test
+ public void isLastId_freeformAddedLastItemRemoved_returnsFalse()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object last = container.addItem();
+ Assert.assertSame(last, container.lastItemId());
+ Assert.assertTrue(container.removeItem(last));
+ Assert.assertFalse(container.isLastId(last));
+ }
+
+ @Test
+ public void indexOfId_freeformItemRemoved_returnsNegOne()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object id = container.getIdByIndex(2);
+ Assert.assertTrue(container.removeItem(id));
+ Assert.assertEquals(-1, container.indexOfId(id));
+ }
+
+ @Test
+ public void indexOfId_freeformAddedItemRemoved_returnsNegOne()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object id = container.addItem();
+ Assert.assertTrue(container.indexOfId(id) != -1);
+ Assert.assertTrue(container.removeItem(id));
+ Assert.assertEquals(-1, container.indexOfId(id));
+ }
+
+ @Test
+ public void getIdByIndex_freeformItemRemoved_resultChanges()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object id = container.getIdByIndex(2);
+ Assert.assertTrue(container.removeItem(id));
+ Assert.assertNotSame(id, container.getIdByIndex(2));
+ }
+
+ @Test
+ public void getIdByIndex_freeformAddedItemRemoved_resultChanges()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object id = container.addItem();
+ container.addItem();
+ int index = container.indexOfId(id);
+ Assert.assertTrue(container.removeItem(id));
+ Assert.assertNotSame(id, container.getIdByIndex(index));
+ }
+
+ @Test
+ public void removeAllItems_freeform_shouldSucceed() throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Assert.assertTrue(container.removeAllItems());
+ Assert.assertEquals(0, container.size());
+ }
+
+ @Test
+ public void removeAllItems_freeformAddedItems_shouldSucceed()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ container.addItem();
+ container.addItem();
+ Assert.assertTrue(container.removeAllItems());
+ Assert.assertEquals(0, container.size());
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void commit_freeformAddedItem_shouldBeWrittenToDB()
+ throws SQLException {
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ EasyMock.expect(
+ delegate.storeRow(EasyMock.isA(Connection.class),
+ EasyMock.isA(RowItem.class)))
+ .andAnswer(new IAnswer<Integer>() {
+ @Override
+ public Integer answer() throws Throwable {
+ Connection conn = (Connection) EasyMock
+ .getCurrentArguments()[0];
+ RowItem item = (RowItem) EasyMock.getCurrentArguments()[1];
+ Statement statement = conn.createStatement();
+ if (SQLTestsConstants.db == DB.MSSQL) {
+ statement
+ .executeUpdate("insert into people values('"
+ + item.getItemProperty("NAME")
+ .getValue()
+ + "', '"
+ + item.getItemProperty("AGE")
+ .getValue() + "')");
+ } else {
+ statement
+ .executeUpdate("insert into people values(default, '"
+ + item.getItemProperty("NAME")
+ .getValue()
+ + "', '"
+ + item.getItemProperty("AGE")
+ .getValue() + "')");
+ }
+ statement.close();
+ conn.commit();
+ connectionPool.releaseConnection(conn);
+ return 1;
+ }
+ }).anyTimes();
+ EasyMock.expect(
+ delegate.getQueryString(EasyMock.anyInt(), EasyMock.anyInt()))
+ .andAnswer(new IAnswer<String>() {
+ @Override
+ public String answer() throws Throwable {
+ Object[] args = EasyMock.getCurrentArguments();
+ int offset = (Integer) (args[0]);
+ int limit = (Integer) (args[1]);
+ if (SQLTestsConstants.db == DB.MSSQL) {
+ int start = offset + 1;
+ int end = offset + limit + 1;
+ String q = "SELECT * FROM (SELECT row_number() OVER"
+ + " ( ORDER BY \"ID\" ASC) AS rownum, * FROM people)"
+ + " AS a WHERE a.rownum BETWEEN "
+ + start
+ + " AND " + end;
+ return q;
+ } else if (SQLTestsConstants.db == DB.ORACLE) {
+ int start = offset + 1;
+ int end = offset + limit + 1;
+ String q = "SELECT * FROM (SELECT x.*, ROWNUM AS r FROM"
+ + " (SELECT * FROM people ORDER BY \"ID\" ASC) x) "
+ + " WHERE r BETWEEN "
+ + start
+ + " AND "
+ + end;
+ return q;
+ } else {
+ return "SELECT * FROM people LIMIT " + limit
+ + " OFFSET " + offset;
+ }
+ }
+ }).anyTimes();
+ delegate.setFilters(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setFilters(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().anyTimes();
+ EasyMock.expect(delegate.getCountQuery())
+ .andThrow(new UnsupportedOperationException()).anyTimes();
+
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ connectionPool, "ID");
+ query.setDelegate(delegate);
+ EasyMock.replay(delegate);
+ SQLContainer container = new SQLContainer(query);
+ Object id = container.addItem();
+ container.getContainerProperty(id, "NAME").setValue("New Name");
+ container.getContainerProperty(id, "AGE").setValue(30);
+ Assert.assertTrue(id instanceof TemporaryRowId);
+ Assert.assertSame(id, container.lastItemId());
+ container.commit();
+ Assert.assertFalse(container.lastItemId() instanceof TemporaryRowId);
+ Assert.assertEquals("New Name",
+ container.getContainerProperty(container.lastItemId(), "NAME")
+ .getValue());
+ EasyMock.verify(delegate);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void commit_freeformTwoAddedItems_shouldBeWrittenToDB()
+ throws SQLException {
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ EasyMock.expect(
+ delegate.storeRow(EasyMock.isA(Connection.class),
+ EasyMock.isA(RowItem.class)))
+ .andAnswer(new IAnswer<Integer>() {
+ @Override
+ public Integer answer() throws Throwable {
+ Connection conn = (Connection) EasyMock
+ .getCurrentArguments()[0];
+ RowItem item = (RowItem) EasyMock.getCurrentArguments()[1];
+ Statement statement = conn.createStatement();
+ if (SQLTestsConstants.db == DB.MSSQL) {
+ statement
+ .executeUpdate("insert into people values('"
+ + item.getItemProperty("NAME")
+ .getValue()
+ + "', '"
+ + item.getItemProperty("AGE")
+ .getValue() + "')");
+ } else {
+ statement
+ .executeUpdate("insert into people values(default, '"
+ + item.getItemProperty("NAME")
+ .getValue()
+ + "', '"
+ + item.getItemProperty("AGE")
+ .getValue() + "')");
+ }
+ statement.close();
+ conn.commit();
+ connectionPool.releaseConnection(conn);
+ return 1;
+ }
+ }).anyTimes();
+ EasyMock.expect(
+ delegate.getQueryString(EasyMock.anyInt(), EasyMock.anyInt()))
+ .andAnswer(new IAnswer<String>() {
+ @Override
+ public String answer() throws Throwable {
+ Object[] args = EasyMock.getCurrentArguments();
+ int offset = (Integer) (args[0]);
+ int limit = (Integer) (args[1]);
+ if (SQLTestsConstants.db == DB.MSSQL) {
+ int start = offset + 1;
+ int end = offset + limit + 1;
+ String q = "SELECT * FROM (SELECT row_number() OVER"
+ + " ( ORDER BY \"ID\" ASC) AS rownum, * FROM people)"
+ + " AS a WHERE a.rownum BETWEEN "
+ + start
+ + " AND " + end;
+ return q;
+ } else if (SQLTestsConstants.db == DB.ORACLE) {
+ int start = offset + 1;
+ int end = offset + limit + 1;
+ String q = "SELECT * FROM (SELECT x.*, ROWNUM AS r FROM"
+ + " (SELECT * FROM people ORDER BY \"ID\" ASC) x) "
+ + " WHERE r BETWEEN "
+ + start
+ + " AND "
+ + end;
+ return q;
+ } else {
+ return "SELECT * FROM people LIMIT " + limit
+ + " OFFSET " + offset;
+ }
+ }
+ }).anyTimes();
+ delegate.setFilters(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setFilters(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().anyTimes();
+ EasyMock.expect(delegate.getCountQuery())
+ .andThrow(new UnsupportedOperationException()).anyTimes();
+
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ connectionPool, "ID");
+ query.setDelegate(delegate);
+ EasyMock.replay(delegate);
+ SQLContainer container = new SQLContainer(query);
+ Object id = container.addItem();
+ Object id2 = container.addItem();
+ container.getContainerProperty(id, "NAME").setValue("Herbert");
+ container.getContainerProperty(id, "AGE").setValue(30);
+ container.getContainerProperty(id2, "NAME").setValue("Larry");
+ container.getContainerProperty(id2, "AGE").setValue(50);
+ Assert.assertTrue(id2 instanceof TemporaryRowId);
+ Assert.assertSame(id2, container.lastItemId());
+ container.commit();
+ Object nextToLast = container.getIdByIndex(container.size() - 2);
+ Assert.assertFalse(nextToLast instanceof TemporaryRowId);
+ Assert.assertEquals("Herbert",
+ container.getContainerProperty(nextToLast, "NAME").getValue());
+ Assert.assertFalse(container.lastItemId() instanceof TemporaryRowId);
+ Assert.assertEquals("Larry",
+ container.getContainerProperty(container.lastItemId(), "NAME")
+ .getValue());
+ EasyMock.verify(delegate);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void commit_freeformRemovedItem_shouldBeRemovedFromDB()
+ throws SQLException {
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ EasyMock.expect(
+ delegate.removeRow(EasyMock.isA(Connection.class),
+ EasyMock.isA(RowItem.class)))
+ .andAnswer(new IAnswer<Boolean>() {
+ @Override
+ public Boolean answer() throws Throwable {
+ Connection conn = (Connection) EasyMock
+ .getCurrentArguments()[0];
+ RowItem item = (RowItem) EasyMock.getCurrentArguments()[1];
+ Statement statement = conn.createStatement();
+ statement
+ .executeUpdate("DELETE FROM people WHERE \"ID\"="
+ + item.getItemProperty("ID").getValue());
+ statement.close();
+ return true;
+ }
+ }).anyTimes();
+ EasyMock.expect(
+ delegate.getQueryString(EasyMock.anyInt(), EasyMock.anyInt()))
+ .andAnswer(new IAnswer<String>() {
+ @Override
+ public String answer() throws Throwable {
+ Object[] args = EasyMock.getCurrentArguments();
+ int offset = (Integer) (args[0]);
+ int limit = (Integer) (args[1]);
+ if (SQLTestsConstants.db == DB.MSSQL) {
+ int start = offset + 1;
+ int end = offset + limit + 1;
+ String q = "SELECT * FROM (SELECT row_number() OVER"
+ + " ( ORDER BY \"ID\" ASC) AS rownum, * FROM people)"
+ + " AS a WHERE a.rownum BETWEEN "
+ + start
+ + " AND " + end;
+ return q;
+ } else if (SQLTestsConstants.db == DB.ORACLE) {
+ int start = offset + 1;
+ int end = offset + limit + 1;
+ String q = "SELECT * FROM (SELECT x.*, ROWNUM AS r FROM"
+ + " (SELECT * FROM people ORDER BY \"ID\" ASC) x) "
+ + " WHERE r BETWEEN "
+ + start
+ + " AND "
+ + end;
+ return q;
+ } else {
+ return "SELECT * FROM people LIMIT " + limit
+ + " OFFSET " + offset;
+ }
+ }
+ }).anyTimes();
+ delegate.setFilters(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setFilters(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().anyTimes();
+ EasyMock.expect(delegate.getCountQuery())
+ .andThrow(new UnsupportedOperationException()).anyTimes();
+
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ connectionPool, "ID");
+ query.setDelegate(delegate);
+ EasyMock.replay(delegate);
+ SQLContainer container = new SQLContainer(query);
+ Object last = container.lastItemId();
+ container.removeItem(last);
+ container.commit();
+ Assert.assertFalse(last.equals(container.lastItemId()));
+ EasyMock.verify(delegate);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void commit_freeformLastItemUpdated_shouldUpdateRowInDB()
+ throws SQLException {
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ EasyMock.expect(
+ delegate.storeRow(EasyMock.isA(Connection.class),
+ EasyMock.isA(RowItem.class)))
+ .andAnswer(new IAnswer<Integer>() {
+ @Override
+ public Integer answer() throws Throwable {
+ Connection conn = (Connection) EasyMock
+ .getCurrentArguments()[0];
+ RowItem item = (RowItem) EasyMock.getCurrentArguments()[1];
+ Statement statement = conn.createStatement();
+ statement.executeUpdate("UPDATE people SET \"NAME\"='"
+ + item.getItemProperty("NAME").getValue()
+ + "' WHERE \"ID\"="
+ + item.getItemProperty("ID").getValue());
+ statement.close();
+ conn.commit();
+ connectionPool.releaseConnection(conn);
+ return 1;
+ }
+ }).anyTimes();
+ EasyMock.expect(
+ delegate.getQueryString(EasyMock.anyInt(), EasyMock.anyInt()))
+ .andAnswer(new IAnswer<String>() {
+ @Override
+ public String answer() throws Throwable {
+ Object[] args = EasyMock.getCurrentArguments();
+ int offset = (Integer) (args[0]);
+ int limit = (Integer) (args[1]);
+ if (SQLTestsConstants.db == DB.MSSQL) {
+ int start = offset + 1;
+ int end = offset + limit + 1;
+ String q = "SELECT * FROM (SELECT row_number() OVER"
+ + " ( ORDER BY \"ID\" ASC) AS rownum, * FROM people)"
+ + " AS a WHERE a.rownum BETWEEN "
+ + start
+ + " AND " + end;
+ return q;
+ } else if (SQLTestsConstants.db == DB.ORACLE) {
+ int start = offset + 1;
+ int end = offset + limit + 1;
+ String q = "SELECT * FROM (SELECT x.*, ROWNUM AS r FROM"
+ + " (SELECT * FROM people ORDER BY \"ID\" ASC) x) "
+ + " WHERE r BETWEEN "
+ + start
+ + " AND "
+ + end;
+ return q;
+ } else {
+ return "SELECT * FROM people LIMIT " + limit
+ + " OFFSET " + offset;
+ }
+ }
+ }).anyTimes();
+ delegate.setFilters(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setFilters(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().anyTimes();
+ EasyMock.expect(delegate.getCountQuery())
+ .andThrow(new UnsupportedOperationException()).anyTimes();
+
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ connectionPool, "ID");
+ query.setDelegate(delegate);
+ EasyMock.replay(delegate);
+ SQLContainer container = new SQLContainer(query);
+ Object last = container.lastItemId();
+ container.getContainerProperty(last, "NAME").setValue("Donald");
+ container.commit();
+ Assert.assertEquals("Donald",
+ container.getContainerProperty(container.lastItemId(), "NAME")
+ .getValue());
+ EasyMock.verify(delegate);
+ }
+
+ @Test
+ public void rollback_freeformItemAdded_discardsAddedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ int size = container.size();
+ Object id = container.addItem();
+ container.getContainerProperty(id, "NAME").setValue("foo");
+ Assert.assertEquals(size + 1, container.size());
+ container.rollback();
+ Assert.assertEquals(size, container.size());
+ Assert.assertFalse("foo".equals(container.getContainerProperty(
+ container.lastItemId(), "NAME").getValue()));
+ }
+
+ @Test
+ public void rollback_freeformItemRemoved_restoresRemovedItem()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ int size = container.size();
+ Object last = container.lastItemId();
+ container.removeItem(last);
+ Assert.assertEquals(size - 1, container.size());
+ container.rollback();
+ Assert.assertEquals(size, container.size());
+ Assert.assertEquals(last, container.lastItemId());
+ }
+
+ @Test
+ public void rollback_freeformItemChanged_discardsChanges()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Object last = container.lastItemId();
+ container.getContainerProperty(last, "NAME").setValue("foo");
+ container.rollback();
+ Assert.assertFalse("foo".equals(container.getContainerProperty(
+ container.lastItemId(), "NAME").getValue()));
+ }
+
+ @Test
+ public void itemChangeNotification_freeform_isModifiedReturnsTrue()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Assert.assertFalse(container.isModified());
+ RowItem last = (RowItem) container.getItem(container.lastItemId());
+ container.itemChangeNotification(last);
+ Assert.assertTrue(container.isModified());
+ }
+
+ @Test
+ public void itemSetChangeListeners_freeform_shouldFire()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ ItemSetChangeListener listener = EasyMock
+ .createMock(ItemSetChangeListener.class);
+ listener.containerItemSetChange(EasyMock.isA(ItemSetChangeEvent.class));
+ EasyMock.replay(listener);
+
+ container.addListener(listener);
+ container.addItem();
+
+ EasyMock.verify(listener);
+ }
+
+ @Test
+ public void itemSetChangeListeners_freeformItemRemoved_shouldFire()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ ItemSetChangeListener listener = EasyMock
+ .createMock(ItemSetChangeListener.class);
+ listener.containerItemSetChange(EasyMock.isA(ItemSetChangeEvent.class));
+ EasyMock.expectLastCall().anyTimes();
+ EasyMock.replay(listener);
+
+ container.addListener(listener);
+ container.removeItem(container.lastItemId());
+
+ EasyMock.verify(listener);
+ }
+
+ @Test
+ public void removeListener_freeform_shouldNotFire() throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ ItemSetChangeListener listener = EasyMock
+ .createMock(ItemSetChangeListener.class);
+ EasyMock.replay(listener);
+
+ container.addListener(listener);
+ container.removeListener(listener);
+ container.addItem();
+
+ EasyMock.verify(listener);
+ }
+
+ @Test
+ public void isModified_freeformRemovedItem_returnsTrue()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Assert.assertFalse(container.isModified());
+ container.removeItem(container.lastItemId());
+ Assert.assertTrue(container.isModified());
+ }
+
+ @Test
+ public void isModified_freeformAddedItem_returnsTrue() throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Assert.assertFalse(container.isModified());
+ container.addItem();
+ Assert.assertTrue(container.isModified());
+ }
+
+ @Test
+ public void isModified_freeformChangedItem_returnsTrue()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Assert.assertFalse(container.isModified());
+ container.getContainerProperty(container.lastItemId(), "NAME")
+ .setValue("foo");
+ Assert.assertTrue(container.isModified());
+ }
+
+ @Test
+ public void getSortableContainerPropertyIds_freeform_returnsAllPropertyIds()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ Collection<?> sortableIds = container.getSortableContainerPropertyIds();
+ Assert.assertTrue(sortableIds.contains("ID"));
+ Assert.assertTrue(sortableIds.contains("NAME"));
+ Assert.assertTrue(sortableIds.contains("AGE"));
+ Assert.assertEquals(3, sortableIds.size());
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void addOrderBy_freeform_shouldReorderResults() throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ connectionPool, "ID");
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ final ArrayList<OrderBy> orderBys = new ArrayList<OrderBy>();
+ delegate.setFilters(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setFilters(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+ @Override
+ public Object answer() throws Throwable {
+ List<OrderBy> orders = (List<OrderBy>) EasyMock
+ .getCurrentArguments()[0];
+ orderBys.clear();
+ orderBys.addAll(orders);
+ return null;
+ }
+ }).anyTimes();
+ EasyMock.expect(
+ delegate.getQueryString(EasyMock.anyInt(), EasyMock.anyInt()))
+ .andAnswer(new IAnswer<String>() {
+ @Override
+ public String answer() throws Throwable {
+ Object[] args = EasyMock.getCurrentArguments();
+ int offset = (Integer) (args[0]);
+ int limit = (Integer) (args[1]);
+ if (SQLTestsConstants.db == DB.MSSQL) {
+ SQLGenerator gen = new MSSQLGenerator();
+ if (orderBys == null || orderBys.isEmpty()) {
+ List<OrderBy> ob = new ArrayList<OrderBy>();
+ ob.add(new OrderBy("ID", true));
+ return gen.generateSelectQuery("people", null,
+ ob, offset, limit, null)
+ .getQueryString();
+ } else {
+ return gen.generateSelectQuery("people", null,
+ orderBys, offset, limit, null)
+ .getQueryString();
+ }
+ } else if (SQLTestsConstants.db == DB.ORACLE) {
+ SQLGenerator gen = new OracleGenerator();
+ if (orderBys == null || orderBys.isEmpty()) {
+ List<OrderBy> ob = new ArrayList<OrderBy>();
+ ob.add(new OrderBy("ID", true));
+ return gen.generateSelectQuery("people", null,
+ ob, offset, limit, null)
+ .getQueryString();
+ } else {
+ return gen.generateSelectQuery("people", null,
+ orderBys, offset, limit, null)
+ .getQueryString();
+ }
+ } else {
+ StringBuffer query = new StringBuffer(
+ "SELECT * FROM people");
+ if (!orderBys.isEmpty()) {
+ query.append(" ORDER BY ");
+ for (OrderBy orderBy : orderBys) {
+ query.append("\"" + orderBy.getColumn()
+ + "\"");
+ if (orderBy.isAscending()) {
+ query.append(" ASC");
+ } else {
+ query.append(" DESC");
+ }
+ }
+ }
+ query.append(" LIMIT ").append(limit)
+ .append(" OFFSET ").append(offset);
+ return query.toString();
+ }
+ }
+ }).anyTimes();
+ EasyMock.expect(delegate.getCountQuery())
+ .andThrow(new UnsupportedOperationException()).anyTimes();
+
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+ SQLContainer container = new SQLContainer(query);
+ // Ville, Kalle, Pelle, Börje
+ Assert.assertEquals("Ville",
+ container.getContainerProperty(container.firstItemId(), "NAME")
+ .getValue());
+ Assert.assertEquals("Börje",
+ container.getContainerProperty(container.lastItemId(), "NAME")
+ .getValue());
+
+ container.addOrderBy(new OrderBy("NAME", true));
+ // Börje, Kalle, Pelle, Ville
+ Assert.assertEquals("Börje",
+ container.getContainerProperty(container.firstItemId(), "NAME")
+ .getValue());
+ Assert.assertEquals("Ville",
+ container.getContainerProperty(container.lastItemId(), "NAME")
+ .getValue());
+
+ EasyMock.verify(delegate);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void addOrderBy_freeformIllegalColumn_shouldFail()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", connectionPool, "ID"));
+ container.addOrderBy(new OrderBy("asdf", true));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void sort_freeform_sortsByName() throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ connectionPool, "ID");
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ final ArrayList<OrderBy> orderBys = new ArrayList<OrderBy>();
+ delegate.setFilters(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setFilters(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+ @Override
+ public Object answer() throws Throwable {
+ List<OrderBy> orders = (List<OrderBy>) EasyMock
+ .getCurrentArguments()[0];
+ orderBys.clear();
+ orderBys.addAll(orders);
+ return null;
+ }
+ }).anyTimes();
+ EasyMock.expect(
+ delegate.getQueryString(EasyMock.anyInt(), EasyMock.anyInt()))
+ .andAnswer(new IAnswer<String>() {
+ @Override
+ public String answer() throws Throwable {
+ Object[] args = EasyMock.getCurrentArguments();
+ int offset = (Integer) (args[0]);
+ int limit = (Integer) (args[1]);
+ if (SQLTestsConstants.db == DB.MSSQL) {
+ SQLGenerator gen = new MSSQLGenerator();
+ if (orderBys == null || orderBys.isEmpty()) {
+ List<OrderBy> ob = new ArrayList<OrderBy>();
+ ob.add(new OrderBy("ID", true));
+ return gen.generateSelectQuery("people", null,
+ ob, offset, limit, null)
+ .getQueryString();
+ } else {
+ return gen.generateSelectQuery("people", null,
+ orderBys, offset, limit, null)
+ .getQueryString();
+ }
+ } else if (SQLTestsConstants.db == DB.ORACLE) {
+ SQLGenerator gen = new OracleGenerator();
+ if (orderBys == null || orderBys.isEmpty()) {
+ List<OrderBy> ob = new ArrayList<OrderBy>();
+ ob.add(new OrderBy("ID", true));
+ return gen.generateSelectQuery("people", null,
+ ob, offset, limit, null)
+ .getQueryString();
+ } else {
+ return gen.generateSelectQuery("people", null,
+ orderBys, offset, limit, null)
+ .getQueryString();
+ }
+ } else {
+ StringBuffer query = new StringBuffer(
+ "SELECT * FROM people");
+ if (!orderBys.isEmpty()) {
+ query.append(" ORDER BY ");
+ for (OrderBy orderBy : orderBys) {
+ query.append("\"" + orderBy.getColumn()
+ + "\"");
+ if (orderBy.isAscending()) {
+ query.append(" ASC");
+ } else {
+ query.append(" DESC");
+ }
+ }
+ }
+ query.append(" LIMIT ").append(limit)
+ .append(" OFFSET ").append(offset);
+ return query.toString();
+ }
+ }
+ }).anyTimes();
+ EasyMock.expect(delegate.getCountQuery())
+ .andThrow(new UnsupportedOperationException()).anyTimes();
+ EasyMock.replay(delegate);
+
+ query.setDelegate(delegate);
+ SQLContainer container = new SQLContainer(query);
+ // Ville, Kalle, Pelle, Börje
+ Assert.assertEquals("Ville",
+ container.getContainerProperty(container.firstItemId(), "NAME")
+ .getValue());
+ Assert.assertEquals("Börje",
+ container.getContainerProperty(container.lastItemId(), "NAME")
+ .getValue());
+
+ container.sort(new Object[] { "NAME" }, new boolean[] { true });
+
+ // Börje, Kalle, Pelle, Ville
+ Assert.assertEquals("Börje",
+ container.getContainerProperty(container.firstItemId(), "NAME")
+ .getValue());
+ Assert.assertEquals("Ville",
+ container.getContainerProperty(container.lastItemId(), "NAME")
+ .getValue());
+
+ EasyMock.verify(delegate);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void addFilter_freeform_filtersResults() throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ connectionPool, "ID");
+ FreeformStatementDelegate delegate = EasyMock
+ .createMock(FreeformStatementDelegate.class);
+ final ArrayList<Filter> filters = new ArrayList<Filter>();
+ delegate.setFilters(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setFilters(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+ @Override
+ public Object answer() throws Throwable {
+ List<Filter> orders = (List<Filter>) EasyMock
+ .getCurrentArguments()[0];
+ filters.clear();
+ filters.addAll(orders);
+ return null;
+ }
+ }).anyTimes();
+ EasyMock.expect(
+ delegate.getQueryStatement(EasyMock.anyInt(), EasyMock.anyInt()))
+ .andAnswer(new IAnswer<StatementHelper>() {
+ @Override
+ public StatementHelper answer() throws Throwable {
+ Object[] args = EasyMock.getCurrentArguments();
+ int offset = (Integer) (args[0]);
+ int limit = (Integer) (args[1]);
+ return FreeformQueryUtil.getQueryWithFilters(filters,
+ offset, limit);
+ }
+ }).anyTimes();
+ EasyMock.expect(delegate.getCountStatement())
+ .andAnswer(new IAnswer<StatementHelper>() {
+ @Override
+ public StatementHelper answer() throws Throwable {
+ StatementHelper sh = new StatementHelper();
+ StringBuffer query = new StringBuffer(
+ "SELECT COUNT(*) FROM people");
+ if (!filters.isEmpty()) {
+ query.append(QueryBuilder.getWhereStringForFilters(
+ filters, sh));
+ }
+ sh.setQueryString(query.toString());
+ return sh;
+ }
+ }).anyTimes();
+
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+ SQLContainer container = new SQLContainer(query);
+ // Ville, Kalle, Pelle, Börje
+ Assert.assertEquals(4, container.size());
+ Assert.assertEquals("Börje",
+ container.getContainerProperty(container.lastItemId(), "NAME")
+ .getValue());
+
+ container.addContainerFilter(new Like("NAME", "%lle"));
+ // Ville, Kalle, Pelle
+ Assert.assertEquals(3, container.size());
+ Assert.assertEquals("Pelle",
+ container.getContainerProperty(container.lastItemId(), "NAME")
+ .getValue());
+
+ EasyMock.verify(delegate);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void addContainerFilter_filtersResults() throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ connectionPool, "ID");
+ FreeformStatementDelegate delegate = EasyMock
+ .createMock(FreeformStatementDelegate.class);
+ final ArrayList<Filter> filters = new ArrayList<Filter>();
+ delegate.setFilters(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setFilters(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+ @Override
+ public Object answer() throws Throwable {
+ List<Filter> orders = (List<Filter>) EasyMock
+ .getCurrentArguments()[0];
+ filters.clear();
+ filters.addAll(orders);
+ return null;
+ }
+ }).anyTimes();
+ EasyMock.expect(
+ delegate.getQueryStatement(EasyMock.anyInt(), EasyMock.anyInt()))
+ .andAnswer(new IAnswer<StatementHelper>() {
+ @Override
+ public StatementHelper answer() throws Throwable {
+ Object[] args = EasyMock.getCurrentArguments();
+ int offset = (Integer) (args[0]);
+ int limit = (Integer) (args[1]);
+ return FreeformQueryUtil.getQueryWithFilters(filters,
+ offset, limit);
+ }
+ }).anyTimes();
+ EasyMock.expect(delegate.getCountStatement())
+ .andAnswer(new IAnswer<StatementHelper>() {
+ @Override
+ public StatementHelper answer() throws Throwable {
+ StatementHelper sh = new StatementHelper();
+ StringBuffer query = new StringBuffer(
+ "SELECT COUNT(*) FROM people");
+ if (!filters.isEmpty()) {
+ query.append(QueryBuilder.getWhereStringForFilters(
+ filters, sh));
+ }
+ sh.setQueryString(query.toString());
+ return sh;
+ }
+ }).anyTimes();
+
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+ SQLContainer container = new SQLContainer(query);
+ // Ville, Kalle, Pelle, Börje
+ Assert.assertEquals(4, container.size());
+
+ container.addContainerFilter("NAME", "Vi", false, false);
+
+ // Ville
+ Assert.assertEquals(1, container.size());
+ Assert.assertEquals("Ville",
+ container.getContainerProperty(container.lastItemId(), "NAME")
+ .getValue());
+
+ EasyMock.verify(delegate);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void addContainerFilter_ignoreCase_filtersResults()
+ throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ connectionPool, "ID");
+ FreeformStatementDelegate delegate = EasyMock
+ .createMock(FreeformStatementDelegate.class);
+ final ArrayList<Filter> filters = new ArrayList<Filter>();
+ delegate.setFilters(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setFilters(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+ @Override
+ public Object answer() throws Throwable {
+ List<Filter> orders = (List<Filter>) EasyMock
+ .getCurrentArguments()[0];
+ filters.clear();
+ filters.addAll(orders);
+ return null;
+ }
+ }).anyTimes();
+ EasyMock.expect(
+ delegate.getQueryStatement(EasyMock.anyInt(), EasyMock.anyInt()))
+ .andAnswer(new IAnswer<StatementHelper>() {
+ @Override
+ public StatementHelper answer() throws Throwable {
+ Object[] args = EasyMock.getCurrentArguments();
+ int offset = (Integer) (args[0]);
+ int limit = (Integer) (args[1]);
+ return FreeformQueryUtil.getQueryWithFilters(filters,
+ offset, limit);
+ }
+ }).anyTimes();
+ EasyMock.expect(delegate.getCountStatement())
+ .andAnswer(new IAnswer<StatementHelper>() {
+ @Override
+ public StatementHelper answer() throws Throwable {
+ StatementHelper sh = new StatementHelper();
+ StringBuffer query = new StringBuffer(
+ "SELECT COUNT(*) FROM people");
+ if (!filters.isEmpty()) {
+ query.append(QueryBuilder.getWhereStringForFilters(
+ filters, sh));
+ }
+ sh.setQueryString(query.toString());
+ return sh;
+ }
+ }).anyTimes();
+
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+ SQLContainer container = new SQLContainer(query);
+ // Ville, Kalle, Pelle, Börje
+ Assert.assertEquals(4, container.size());
+
+ // FIXME LIKE %asdf% doesn't match a string that begins with asdf
+ container.addContainerFilter("NAME", "vi", true, true);
+
+ // Ville
+ Assert.assertEquals(1, container.size());
+ Assert.assertEquals("Ville",
+ container.getContainerProperty(container.lastItemId(), "NAME")
+ .getValue());
+
+ EasyMock.verify(delegate);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void removeAllContainerFilters_freeform_noFiltering()
+ throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ connectionPool, "ID");
+ FreeformStatementDelegate delegate = EasyMock
+ .createMock(FreeformStatementDelegate.class);
+ final ArrayList<Filter> filters = new ArrayList<Filter>();
+ delegate.setFilters(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setFilters(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+ @Override
+ public Object answer() throws Throwable {
+ List<Filter> orders = (List<Filter>) EasyMock
+ .getCurrentArguments()[0];
+ filters.clear();
+ filters.addAll(orders);
+ return null;
+ }
+ }).anyTimes();
+ EasyMock.expect(
+ delegate.getQueryStatement(EasyMock.anyInt(), EasyMock.anyInt()))
+ .andAnswer(new IAnswer<StatementHelper>() {
+ @Override
+ public StatementHelper answer() throws Throwable {
+ Object[] args = EasyMock.getCurrentArguments();
+ int offset = (Integer) (args[0]);
+ int limit = (Integer) (args[1]);
+ return FreeformQueryUtil.getQueryWithFilters(filters,
+ offset, limit);
+ }
+ }).anyTimes();
+ EasyMock.expect(delegate.getCountStatement())
+ .andAnswer(new IAnswer<StatementHelper>() {
+ @Override
+ public StatementHelper answer() throws Throwable {
+ StatementHelper sh = new StatementHelper();
+ StringBuffer query = new StringBuffer(
+ "SELECT COUNT(*) FROM people");
+ if (!filters.isEmpty()) {
+ query.append(QueryBuilder.getWhereStringForFilters(
+ filters, sh));
+ }
+ sh.setQueryString(query.toString());
+ return sh;
+ }
+ }).anyTimes();
+
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+ SQLContainer container = new SQLContainer(query);
+ // Ville, Kalle, Pelle, Börje
+ Assert.assertEquals(4, container.size());
+
+ container.addContainerFilter("NAME", "Vi", false, false);
+
+ // Ville
+ Assert.assertEquals(1, container.size());
+ Assert.assertEquals("Ville",
+ container.getContainerProperty(container.lastItemId(), "NAME")
+ .getValue());
+
+ container.removeAllContainerFilters();
+
+ Assert.assertEquals(4, container.size());
+ Assert.assertEquals("Börje",
+ container.getContainerProperty(container.lastItemId(), "NAME")
+ .getValue());
+
+ EasyMock.verify(delegate);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void removeContainerFilters_freeform_noFiltering()
+ throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ connectionPool, "ID");
+ FreeformStatementDelegate delegate = EasyMock
+ .createMock(FreeformStatementDelegate.class);
+ final ArrayList<Filter> filters = new ArrayList<Filter>();
+ delegate.setFilters(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setFilters(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+ @Override
+ public Object answer() throws Throwable {
+ List<Filter> orders = (List<Filter>) EasyMock
+ .getCurrentArguments()[0];
+ filters.clear();
+ filters.addAll(orders);
+ return null;
+ }
+ }).anyTimes();
+ EasyMock.expect(
+ delegate.getQueryStatement(EasyMock.anyInt(), EasyMock.anyInt()))
+ .andAnswer(new IAnswer<StatementHelper>() {
+ @Override
+ public StatementHelper answer() throws Throwable {
+ Object[] args = EasyMock.getCurrentArguments();
+ int offset = (Integer) (args[0]);
+ int limit = (Integer) (args[1]);
+ return FreeformQueryUtil.getQueryWithFilters(filters,
+ offset, limit);
+ }
+ }).anyTimes();
+ EasyMock.expect(delegate.getCountStatement())
+ .andAnswer(new IAnswer<StatementHelper>() {
+ @Override
+ public StatementHelper answer() throws Throwable {
+ StatementHelper sh = new StatementHelper();
+ StringBuffer query = new StringBuffer(
+ "SELECT COUNT(*) FROM people");
+ if (!filters.isEmpty()) {
+ query.append(QueryBuilder.getWhereStringForFilters(
+ filters, sh));
+ }
+ sh.setQueryString(query.toString());
+ return sh;
+ }
+ }).anyTimes();
+
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+ SQLContainer container = new SQLContainer(query);
+ // Ville, Kalle, Pelle, Börje
+ Assert.assertEquals(4, container.size());
+
+ container.addContainerFilter("NAME", "Vi", false, true);
+
+ // Ville
+ Assert.assertEquals(1, container.size());
+ Assert.assertEquals("Ville",
+ container.getContainerProperty(container.lastItemId(), "NAME")
+ .getValue());
+
+ container.removeContainerFilters("NAME");
+
+ Assert.assertEquals(4, container.size());
+ Assert.assertEquals("Börje",
+ container.getContainerProperty(container.lastItemId(), "NAME")
+ .getValue());
+
+ EasyMock.verify(delegate);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void addFilter_freeformBufferedItems_alsoFiltersBufferedItems()
+ throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ connectionPool, "ID");
+ FreeformStatementDelegate delegate = EasyMock
+ .createMock(FreeformStatementDelegate.class);
+ final ArrayList<Filter> filters = new ArrayList<Filter>();
+ delegate.setFilters(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setFilters(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+ @Override
+ public Object answer() throws Throwable {
+ List<Filter> orders = (List<Filter>) EasyMock
+ .getCurrentArguments()[0];
+ filters.clear();
+ filters.addAll(orders);
+ return null;
+ }
+ }).anyTimes();
+ EasyMock.expect(
+ delegate.getQueryStatement(EasyMock.anyInt(), EasyMock.anyInt()))
+ .andAnswer(new IAnswer<StatementHelper>() {
+ @Override
+ public StatementHelper answer() throws Throwable {
+ Object[] args = EasyMock.getCurrentArguments();
+ int offset = (Integer) (args[0]);
+ int limit = (Integer) (args[1]);
+ return FreeformQueryUtil.getQueryWithFilters(filters,
+ offset, limit);
+ }
+ }).anyTimes();
+ EasyMock.expect(delegate.getCountStatement())
+ .andAnswer(new IAnswer<StatementHelper>() {
+ @Override
+ public StatementHelper answer() throws Throwable {
+ StatementHelper sh = new StatementHelper();
+ StringBuffer query = new StringBuffer(
+ "SELECT COUNT(*) FROM people");
+ if (!filters.isEmpty()) {
+ query.append(QueryBuilder.getWhereStringForFilters(
+ filters, sh));
+ }
+ sh.setQueryString(query.toString());
+ return sh;
+ }
+ }).anyTimes();
+
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+ SQLContainer container = new SQLContainer(query);
+ // Ville, Kalle, Pelle, Börje
+ Assert.assertEquals(4, container.size());
+ Assert.assertEquals("Börje",
+ container.getContainerProperty(container.lastItemId(), "NAME")
+ .getValue());
+
+ Object id1 = container.addItem();
+ container.getContainerProperty(id1, "NAME").setValue("Palle");
+ Object id2 = container.addItem();
+ container.getContainerProperty(id2, "NAME").setValue("Bengt");
+
+ container.addContainerFilter(new Like("NAME", "%lle"));
+
+ // Ville, Kalle, Pelle, Palle
+ Assert.assertEquals(4, container.size());
+ Assert.assertEquals(
+ "Ville",
+ container.getContainerProperty(container.getIdByIndex(0),
+ "NAME").getValue());
+ Assert.assertEquals(
+ "Kalle",
+ container.getContainerProperty(container.getIdByIndex(1),
+ "NAME").getValue());
+ Assert.assertEquals(
+ "Pelle",
+ container.getContainerProperty(container.getIdByIndex(2),
+ "NAME").getValue());
+ Assert.assertEquals(
+ "Palle",
+ container.getContainerProperty(container.getIdByIndex(3),
+ "NAME").getValue());
+
+ try {
+ container.getIdByIndex(4);
+ Assert.fail("SQLContainer.getIdByIndex() returned a value for an index beyond the end of the container");
+ } catch (IndexOutOfBoundsException e) {
+ // should throw exception - item is filtered out
+ }
+ container.nextItemId(container.getIdByIndex(3));
+
+ Assert.assertFalse(container.containsId(id2));
+ Assert.assertFalse(container.getItemIds().contains(id2));
+
+ Assert.assertNull(container.getItem(id2));
+ Assert.assertEquals(-1, container.indexOfId(id2));
+
+ Assert.assertNotSame(id2, container.lastItemId());
+ Assert.assertSame(id1, container.lastItemId());
+
+ EasyMock.verify(delegate);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void sort_freeformBufferedItems_sortsBufferedItemsLastInOrderAdded()
+ throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ connectionPool, "ID");
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ final ArrayList<OrderBy> orderBys = new ArrayList<OrderBy>();
+ delegate.setFilters(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setFilters(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+ @Override
+ public Object answer() throws Throwable {
+ List<OrderBy> orders = (List<OrderBy>) EasyMock
+ .getCurrentArguments()[0];
+ orderBys.clear();
+ orderBys.addAll(orders);
+ return null;
+ }
+ }).anyTimes();
+ EasyMock.expect(
+ delegate.getQueryString(EasyMock.anyInt(), EasyMock.anyInt()))
+ .andAnswer(new IAnswer<String>() {
+ @Override
+ public String answer() throws Throwable {
+ Object[] args = EasyMock.getCurrentArguments();
+ int offset = (Integer) (args[0]);
+ int limit = (Integer) (args[1]);
+ if (SQLTestsConstants.db == DB.MSSQL) {
+ SQLGenerator gen = new MSSQLGenerator();
+ if (orderBys == null || orderBys.isEmpty()) {
+ List<OrderBy> ob = new ArrayList<OrderBy>();
+ ob.add(new OrderBy("ID", true));
+ return gen.generateSelectQuery("people", null,
+ ob, offset, limit, null)
+ .getQueryString();
+ } else {
+ return gen.generateSelectQuery("people", null,
+ orderBys, offset, limit, null)
+ .getQueryString();
+ }
+ } else if (SQLTestsConstants.db == DB.ORACLE) {
+ SQLGenerator gen = new OracleGenerator();
+ if (orderBys == null || orderBys.isEmpty()) {
+ List<OrderBy> ob = new ArrayList<OrderBy>();
+ ob.add(new OrderBy("ID", true));
+ return gen.generateSelectQuery("people", null,
+ ob, offset, limit, null)
+ .getQueryString();
+ } else {
+ return gen.generateSelectQuery("people", null,
+ orderBys, offset, limit, null)
+ .getQueryString();
+ }
+ } else {
+ StringBuffer query = new StringBuffer(
+ "SELECT * FROM people");
+ if (!orderBys.isEmpty()) {
+ query.append(" ORDER BY ");
+ for (OrderBy orderBy : orderBys) {
+ query.append("\"" + orderBy.getColumn()
+ + "\"");
+ if (orderBy.isAscending()) {
+ query.append(" ASC");
+ } else {
+ query.append(" DESC");
+ }
+ }
+ }
+ query.append(" LIMIT ").append(limit)
+ .append(" OFFSET ").append(offset);
+ return query.toString();
+ }
+ }
+ }).anyTimes();
+ EasyMock.expect(delegate.getCountQuery())
+ .andThrow(new UnsupportedOperationException()).anyTimes();
+ EasyMock.replay(delegate);
+
+ query.setDelegate(delegate);
+ SQLContainer container = new SQLContainer(query);
+ // Ville, Kalle, Pelle, Börje
+ Assert.assertEquals("Ville",
+ container.getContainerProperty(container.firstItemId(), "NAME")
+ .getValue());
+ Assert.assertEquals("Börje",
+ container.getContainerProperty(container.lastItemId(), "NAME")
+ .getValue());
+
+ Object id1 = container.addItem();
+ container.getContainerProperty(id1, "NAME").setValue("Wilbert");
+ Object id2 = container.addItem();
+ container.getContainerProperty(id2, "NAME").setValue("Albert");
+
+ container.sort(new Object[] { "NAME" }, new boolean[] { true });
+
+ // Börje, Kalle, Pelle, Ville, Wilbert, Albert
+ Assert.assertEquals("Börje",
+ container.getContainerProperty(container.firstItemId(), "NAME")
+ .getValue());
+ Assert.assertEquals(
+ "Wilbert",
+ container.getContainerProperty(
+ container.getIdByIndex(container.size() - 2), "NAME")
+ .getValue());
+ Assert.assertEquals("Albert",
+ container.getContainerProperty(container.lastItemId(), "NAME")
+ .getValue());
+
+ EasyMock.verify(delegate);
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLTestsConstants.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLTestsConstants.java
new file mode 100755
index 0000000000..e03e970048
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLTestsConstants.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.data.util.sqlcontainer;
+
+import com.vaadin.data.util.sqlcontainer.query.generator.DefaultSQLGenerator;
+import com.vaadin.data.util.sqlcontainer.query.generator.MSSQLGenerator;
+import com.vaadin.data.util.sqlcontainer.query.generator.OracleGenerator;
+import com.vaadin.data.util.sqlcontainer.query.generator.SQLGenerator;
+
+public class SQLTestsConstants {
+
+ /* Set the DB used for testing here! */
+ public enum DB {
+ HSQLDB, MYSQL, POSTGRESQL, MSSQL, ORACLE;
+ }
+
+ /* 0 = HSQLDB, 1 = MYSQL, 2 = POSTGRESQL, 3 = MSSQL, 4 = ORACLE */
+ public static final DB db = DB.HSQLDB;
+
+ /* Auto-increment column offset (HSQLDB = 0, MYSQL = 1, POSTGRES = 1) */
+ public static int offset;
+ /* Garbage table creation query (=three queries for oracle) */
+ public static String createGarbage;
+ public static String createGarbageSecond;
+ public static String createGarbageThird;
+ /* DB Drivers, urls, usernames and passwords */
+ public static String dbDriver;
+ public static String dbURL;
+ public static String dbUser;
+ public static String dbPwd;
+ /* People -test table creation statement(s) */
+ public static String peopleFirst;
+ public static String peopleSecond;
+ public static String peopleThird;
+ /* Schema test creation statement(s) */
+ public static String createSchema;
+ public static String createProductTable;
+ public static String dropSchema;
+ /* Versioned -test table createion statement(s) */
+ public static String[] versionStatements;
+ /* SQL Generator used during the testing */
+ public static SQLGenerator sqlGen;
+
+ /* Set DB-specific settings based on selected DB */
+ static {
+ sqlGen = new DefaultSQLGenerator();
+ switch (db) {
+ case HSQLDB:
+ offset = 0;
+ createGarbage = "create table garbage (id integer generated always as identity, type varchar(32), PRIMARY KEY(id))";
+ dbDriver = "org.hsqldb.jdbc.JDBCDriver";
+ dbURL = "jdbc:hsqldb:mem:sqlcontainer";
+ dbUser = "SA";
+ dbPwd = "";
+ peopleFirst = "create table people (id integer generated always as identity, name varchar(32), AGE INTEGER)";
+ peopleSecond = "alter table people add primary key (id)";
+ versionStatements = new String[] {
+ "create table versioned (id integer generated always as identity, text varchar(255), version tinyint default 0)",
+ "alter table versioned add primary key (id)" };
+ // TODO these should ideally exist for all databases
+ createSchema = "create schema oaas authorization DBA";
+ createProductTable = "create table oaas.product (\"ID\" integer generated always as identity primary key, \"NAME\" VARCHAR(32))";
+ dropSchema = "drop schema if exists oaas cascade";
+ break;
+ case MYSQL:
+ offset = 1;
+ createGarbage = "create table GARBAGE (ID integer auto_increment, type varchar(32), PRIMARY KEY(ID))";
+ dbDriver = "com.mysql.jdbc.Driver";
+ dbURL = "jdbc:mysql:///sqlcontainer";
+ dbUser = "sqlcontainer";
+ dbPwd = "sqlcontainer";
+ peopleFirst = "create table PEOPLE (ID integer auto_increment not null, NAME varchar(32), AGE INTEGER, primary key(ID))";
+ peopleSecond = null;
+ versionStatements = new String[] {
+ "create table VERSIONED (ID integer auto_increment not null, TEXT varchar(255), VERSION tinyint default 0, primary key(ID))",
+ "CREATE TRIGGER upd_version BEFORE UPDATE ON VERSIONED"
+ + " FOR EACH ROW SET NEW.VERSION = OLD.VERSION+1" };
+ break;
+ case POSTGRESQL:
+ offset = 1;
+ createGarbage = "create table GARBAGE (\"ID\" serial PRIMARY KEY, \"TYPE\" varchar(32))";
+ dbDriver = "org.postgresql.Driver";
+ dbURL = "jdbc:postgresql://localhost:5432/test";
+ dbUser = "postgres";
+ dbPwd = "postgres";
+ peopleFirst = "create table PEOPLE (\"ID\" serial primary key, \"NAME\" VARCHAR(32), \"AGE\" INTEGER)";
+ peopleSecond = null;
+ versionStatements = new String[] {
+ "create table VERSIONED (\"ID\" serial primary key, \"TEXT\" VARCHAR(255), \"VERSION\" INTEGER DEFAULT 0)",
+ "CREATE OR REPLACE FUNCTION zz_row_version() RETURNS TRIGGER AS $$"
+ + "BEGIN"
+ + " IF TG_OP = 'UPDATE'"
+ + " AND NEW.\"VERSION\" = old.\"VERSION\""
+ + " AND ROW(NEW.*) IS DISTINCT FROM ROW (old.*)"
+ + " THEN"
+ + " NEW.\"VERSION\" := NEW.\"VERSION\" + 1;"
+ + " END IF;" + " RETURN NEW;" + "END;"
+ + "$$ LANGUAGE plpgsql;",
+ "CREATE TRIGGER \"mytable_modify_dt_tr\" BEFORE UPDATE"
+ + " ON VERSIONED FOR EACH ROW"
+ + " EXECUTE PROCEDURE \"public\".\"zz_row_version\"();" };
+ createSchema = "create schema oaas";
+ createProductTable = "create table oaas.product (\"ID\" serial primary key, \"NAME\" VARCHAR(32))";
+ dropSchema = "drop schema oaas cascade";
+ break;
+ case MSSQL:
+ offset = 1;
+ createGarbage = "create table GARBAGE (\"ID\" int identity(1,1) primary key, \"TYPE\" varchar(32))";
+ dbDriver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
+ dbURL = "jdbc:sqlserver://localhost:1433;databaseName=tempdb;";
+ dbUser = "sa";
+ dbPwd = "sa";
+ peopleFirst = "create table PEOPLE (\"ID\" int identity(1,1) primary key, \"NAME\" VARCHAR(32), \"AGE\" INTEGER)";
+ peopleSecond = null;
+ versionStatements = new String[] { "create table VERSIONED (\"ID\" int identity(1,1) primary key, \"TEXT\" VARCHAR(255), \"VERSION\" rowversion not null)" };
+ sqlGen = new MSSQLGenerator();
+ break;
+ case ORACLE:
+ offset = 1;
+ createGarbage = "create table GARBAGE (\"ID\" integer primary key, \"TYPE\" varchar2(32))";
+ createGarbageSecond = "create sequence garbage_seq start with 1 increment by 1 nomaxvalue";
+ createGarbageThird = "create trigger garbage_trigger before insert on GARBAGE for each row begin select garbage_seq.nextval into :new.ID from dual; end;";
+ dbDriver = "oracle.jdbc.OracleDriver";
+ dbURL = "jdbc:oracle:thin:test/test@localhost:1521:XE";
+ dbUser = "test";
+ dbPwd = "test";
+ peopleFirst = "create table PEOPLE (\"ID\" integer primary key, \"NAME\" VARCHAR2(32), \"AGE\" INTEGER)";
+ peopleSecond = "create sequence people_seq start with 1 increment by 1 nomaxvalue";
+ peopleThird = "create trigger people_trigger before insert on PEOPLE for each row begin select people_seq.nextval into :new.ID from dual; end;";
+ versionStatements = new String[] {
+ "create table VERSIONED (\"ID\" integer primary key, \"TEXT\" VARCHAR(255), \"VERSION\" INTEGER DEFAULT 0)",
+ "create sequence versioned_seq start with 1 increment by 1 nomaxvalue",
+ "create trigger versioned_trigger before insert on VERSIONED for each row begin select versioned_seq.nextval into :new.ID from dual; end;",
+ "create sequence versioned_version start with 1 increment by 1 nomaxvalue",
+ "create trigger versioned_version_trigger before insert or update on VERSIONED for each row begin select versioned_version.nextval into :new.VERSION from dual; end;" };
+ sqlGen = new OracleGenerator();
+ break;
+ }
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/TicketTests.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/TicketTests.java
new file mode 100644
index 0000000000..e180e3f3e7
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/sqlcontainer/TicketTests.java
@@ -0,0 +1,198 @@
+package com.vaadin.data.util.sqlcontainer;
+
+import java.math.BigDecimal;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.Container.Filter;
+import com.vaadin.data.Item;
+import com.vaadin.data.util.filter.Compare.Equal;
+import com.vaadin.data.util.sqlcontainer.SQLTestsConstants.DB;
+import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool;
+import com.vaadin.data.util.sqlcontainer.query.FreeformQuery;
+import com.vaadin.data.util.sqlcontainer.query.FreeformStatementDelegate;
+import com.vaadin.data.util.sqlcontainer.query.TableQuery;
+import com.vaadin.data.util.sqlcontainer.query.ValidatingSimpleJDBCConnectionPool;
+import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
+import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.Window;
+
+public class TicketTests {
+
+ private JDBCConnectionPool connectionPool;
+
+ @Before
+ public void setUp() throws SQLException {
+ connectionPool = new ValidatingSimpleJDBCConnectionPool(
+ SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL,
+ SQLTestsConstants.dbUser, SQLTestsConstants.dbPwd, 2, 2);
+ DataGenerator.addPeopleToDatabase(connectionPool);
+ }
+
+ @Test
+ public void ticket5867_throwsIllegalState_transactionAlreadyActive()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people", Arrays.asList("ID"), connectionPool));
+ Table table = new Table();
+ Window w = new Window();
+ w.setContent(table);
+ table.setContainerDataSource(container);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void ticket6136_freeform_ageIs18() throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ FreeformStatementDelegate delegate = EasyMock
+ .createMock(FreeformStatementDelegate.class);
+ final ArrayList<Filter> filters = new ArrayList<Filter>();
+ delegate.setFilters(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setOrderBy(null);
+ EasyMock.expectLastCall().anyTimes();
+ delegate.setFilters(EasyMock.isA(List.class));
+ EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+ @Override
+ public Object answer() throws Throwable {
+ List<Filter> orders = (List<Filter>) EasyMock
+ .getCurrentArguments()[0];
+ filters.clear();
+ filters.addAll(orders);
+ return null;
+ }
+ }).anyTimes();
+ EasyMock.expect(
+ delegate.getQueryStatement(EasyMock.anyInt(), EasyMock.anyInt()))
+ .andAnswer(new IAnswer<StatementHelper>() {
+ @Override
+ public StatementHelper answer() throws Throwable {
+ Object[] args = EasyMock.getCurrentArguments();
+ int offset = (Integer) (args[0]);
+ int limit = (Integer) (args[1]);
+ return FreeformQueryUtil.getQueryWithFilters(filters,
+ offset, limit);
+ }
+ }).anyTimes();
+ EasyMock.expect(delegate.getCountStatement())
+ .andAnswer(new IAnswer<StatementHelper>() {
+ @Override
+ public StatementHelper answer() throws Throwable {
+ StatementHelper sh = new StatementHelper();
+ StringBuffer query = new StringBuffer(
+ "SELECT COUNT(*) FROM people");
+ if (!filters.isEmpty()) {
+ query.append(QueryBuilder.getWhereStringForFilters(
+ filters, sh));
+ }
+ sh.setQueryString(query.toString());
+ return sh;
+ }
+ }).anyTimes();
+
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+ SQLContainer container = new SQLContainer(query);
+ // Ville, Kalle, Pelle, Börje
+ Assert.assertEquals(4, container.size());
+ Assert.assertEquals("Börje",
+ container.getContainerProperty(container.lastItemId(), "NAME")
+ .getValue());
+
+ container.addContainerFilter(new Equal("AGE", 18));
+ // Pelle
+ Assert.assertEquals(1, container.size());
+ Assert.assertEquals("Pelle",
+ container.getContainerProperty(container.firstItemId(), "NAME")
+ .getValue());
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ Assert.assertEquals(new BigDecimal(18), container
+ .getContainerProperty(container.firstItemId(), "AGE")
+ .getValue());
+ } else {
+ Assert.assertEquals(
+ 18,
+ container.getContainerProperty(container.firstItemId(),
+ "AGE").getValue());
+ }
+
+ EasyMock.verify(delegate);
+ }
+
+ @Test
+ public void ticket6136_table_ageIs18() throws SQLException {
+ TableQuery query = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+ SQLContainer container = new SQLContainer(query);
+ // Ville, Kalle, Pelle, Börje
+ Assert.assertEquals(4, container.size());
+
+ container.addContainerFilter(new Equal("AGE", 18));
+
+ // Pelle
+ Assert.assertEquals(1, container.size());
+ Assert.assertEquals("Pelle",
+ container.getContainerProperty(container.firstItemId(), "NAME")
+ .getValue());
+ if (SQLTestsConstants.db == DB.ORACLE) {
+ Assert.assertEquals(new BigDecimal(18), container
+ .getContainerProperty(container.firstItemId(), "AGE")
+ .getValue());
+ } else {
+ Assert.assertEquals(
+ 18,
+ container.getContainerProperty(container.firstItemId(),
+ "AGE").getValue());
+ }
+ }
+
+ @Test
+ public void ticket7434_getItem_Modified_Changed_Unchanged()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, SQLTestsConstants.sqlGen));
+
+ Object id = container.firstItemId();
+ Item item = container.getItem(id);
+ String name = (String) item.getItemProperty("NAME").getValue();
+
+ // set a different name
+ item.getItemProperty("NAME").setValue("otherName");
+ Assert.assertEquals("otherName", item.getItemProperty("NAME")
+ .getValue());
+
+ // access the item and reset the name to its old value
+ Item item2 = container.getItem(id);
+ item2.getItemProperty("NAME").setValue(name);
+ Assert.assertEquals(name, item2.getItemProperty("NAME").getValue());
+
+ Item item3 = container.getItem(id);
+ String name3 = (String) item3.getItemProperty("NAME").getValue();
+
+ Assert.assertEquals(name, name3);
+ }
+
+ @Test
+ public void ticket10032_empty_set_metadata_correctly_handled()
+ throws SQLException {
+ // If problem exists will break when method getPropertyIds()
+ // is called in constructor SQLContainer(QueryDelegate delegate).
+ SQLContainer container = new SQLContainer(new FreeformQuery(
+ "SELECT * FROM people WHERE name='does_not_exist'",
+ Arrays.asList("ID"), connectionPool));
+ Assert.assertTrue("Got items while expected empty set",
+ container.size() == 0);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/UtilTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/UtilTest.java
new file mode 100644
index 0000000000..a575d649f1
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/sqlcontainer/UtilTest.java
@@ -0,0 +1,50 @@
+package com.vaadin.data.util.sqlcontainer;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class UtilTest {
+
+ @Test
+ public void escapeSQL_noQuotes_returnsSameString() {
+ Assert.assertEquals("asdf", SQLUtil.escapeSQL("asdf"));
+ }
+
+ @Test
+ public void escapeSQL_singleQuotes_returnsEscapedString() {
+ Assert.assertEquals("O''Brien", SQLUtil.escapeSQL("O'Brien"));
+ }
+
+ @Test
+ public void escapeSQL_severalQuotes_returnsEscapedString() {
+ Assert.assertEquals("asdf''ghjk''qwerty",
+ SQLUtil.escapeSQL("asdf'ghjk'qwerty"));
+ }
+
+ @Test
+ public void escapeSQL_doubleQuotes_returnsEscapedString() {
+ Assert.assertEquals("asdf\\\"foo", SQLUtil.escapeSQL("asdf\"foo"));
+ }
+
+ @Test
+ public void escapeSQL_multipleDoubleQuotes_returnsEscapedString() {
+ Assert.assertEquals("asdf\\\"foo\\\"bar",
+ SQLUtil.escapeSQL("asdf\"foo\"bar"));
+ }
+
+ @Test
+ public void escapeSQL_backslashes_returnsEscapedString() {
+ Assert.assertEquals("foo\\\\nbar\\\\r",
+ SQLUtil.escapeSQL("foo\\nbar\\r"));
+ }
+
+ @Test
+ public void escapeSQL_x00_removesX00() {
+ Assert.assertEquals("foobar", SQLUtil.escapeSQL("foo\\x00bar"));
+ }
+
+ @Test
+ public void escapeSQL_x1a_removesX1a() {
+ Assert.assertEquals("foobar", SQLUtil.escapeSQL("foo\\x1abar"));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPoolTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPoolTest.java
new file mode 100644
index 0000000000..1463a27217
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPoolTest.java
@@ -0,0 +1,107 @@
+package com.vaadin.data.util.sqlcontainer.connection;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.sql.DataSource;
+
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class J2EEConnectionPoolTest {
+
+ @Test
+ public void reserveConnection_dataSourceSpecified_shouldReturnValidConnection()
+ throws SQLException {
+ Connection connection = EasyMock.createMock(Connection.class);
+ connection.setAutoCommit(false);
+ EasyMock.expectLastCall();
+ DataSource ds = EasyMock.createMock(DataSource.class);
+ ds.getConnection();
+ EasyMock.expectLastCall().andReturn(connection);
+ EasyMock.replay(connection, ds);
+
+ J2EEConnectionPool pool = new J2EEConnectionPool(ds);
+ Connection c = pool.reserveConnection();
+ Assert.assertEquals(connection, c);
+ EasyMock.verify(connection, ds);
+ }
+
+ @Test
+ public void releaseConnection_shouldCloseConnection() throws SQLException {
+ Connection connection = EasyMock.createMock(Connection.class);
+ connection.setAutoCommit(false);
+ EasyMock.expectLastCall();
+ connection.close();
+ EasyMock.expectLastCall();
+ DataSource ds = EasyMock.createMock(DataSource.class);
+ ds.getConnection();
+ EasyMock.expectLastCall().andReturn(connection);
+ EasyMock.replay(connection, ds);
+
+ J2EEConnectionPool pool = new J2EEConnectionPool(ds);
+ Connection c = pool.reserveConnection();
+ Assert.assertEquals(connection, c);
+ pool.releaseConnection(c);
+ EasyMock.verify(connection, ds);
+ }
+
+ @Test
+ public void reserveConnection_dataSourceLookedUp_shouldReturnValidConnection()
+ throws SQLException, NamingException {
+ Connection connection = EasyMock.createMock(Connection.class);
+ connection.setAutoCommit(false);
+ EasyMock.expectLastCall();
+ connection.close();
+ EasyMock.expectLastCall();
+
+ DataSource ds = EasyMock.createMock(DataSource.class);
+ ds.getConnection();
+ EasyMock.expectLastCall().andReturn(connection);
+
+ System.setProperty("java.naming.factory.initial",
+ "com.vaadin.data.util.sqlcontainer.connection.MockInitialContextFactory");
+ Context context = EasyMock.createMock(Context.class);
+ context.lookup("testDataSource");
+ EasyMock.expectLastCall().andReturn(ds);
+ MockInitialContextFactory.setMockContext(context);
+
+ EasyMock.replay(context, connection, ds);
+
+ J2EEConnectionPool pool = new J2EEConnectionPool("testDataSource");
+ Connection c = pool.reserveConnection();
+ Assert.assertEquals(connection, c);
+ pool.releaseConnection(c);
+ EasyMock.verify(context, connection, ds);
+ }
+
+ @Test(expected = SQLException.class)
+ public void reserveConnection_nonExistantDataSourceLookedUp_shouldFail()
+ throws SQLException, NamingException {
+ System.setProperty("java.naming.factory.initial",
+ "com.vaadin.addon.sqlcontainer.connection.MockInitialContextFactory");
+ Context context = EasyMock.createMock(Context.class);
+ context.lookup("foo");
+ EasyMock.expectLastCall().andThrow(new NamingException("fail"));
+ MockInitialContextFactory.setMockContext(context);
+
+ EasyMock.replay(context);
+
+ J2EEConnectionPool pool = new J2EEConnectionPool("foo");
+ pool.reserveConnection();
+ EasyMock.verify(context);
+ }
+
+ @Test
+ public void releaseConnection_null_shouldSucceed() throws SQLException {
+ DataSource ds = EasyMock.createMock(DataSource.class);
+ EasyMock.replay(ds);
+
+ J2EEConnectionPool pool = new J2EEConnectionPool(ds);
+ pool.releaseConnection(null);
+ EasyMock.verify(ds);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/MockInitialContextFactory.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/MockInitialContextFactory.java
new file mode 100644
index 0000000000..1c70c8dad7
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/MockInitialContextFactory.java
@@ -0,0 +1,27 @@
+package com.vaadin.data.util.sqlcontainer.connection;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.spi.InitialContextFactory;
+
+import org.junit.Test;
+
+/**
+ * Provides a JNDI initial context factory for the MockContext.
+ */
+public class MockInitialContextFactory implements InitialContextFactory {
+ private static Context mockCtx = null;
+
+ public static void setMockContext(Context ctx) {
+ mockCtx = ctx;
+ }
+
+ @Override
+ public Context getInitialContext(java.util.Hashtable<?, ?> environment)
+ throws NamingException {
+ if (mockCtx == null) {
+ throw new IllegalStateException("mock context was not set.");
+ }
+ return mockCtx;
+ }
+}
diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPoolTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPoolTest.java
new file mode 100644
index 0000000000..b786f5b2de
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPoolTest.java
@@ -0,0 +1,183 @@
+package com.vaadin.data.util.sqlcontainer.connection;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.util.sqlcontainer.SQLTestsConstants;
+import com.vaadin.data.util.sqlcontainer.query.ValidatingSimpleJDBCConnectionPool;
+
+public class SimpleJDBCConnectionPoolTest {
+ private JDBCConnectionPool connectionPool;
+
+ @Before
+ public void setUp() throws SQLException {
+ connectionPool = new ValidatingSimpleJDBCConnectionPool(
+ SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL,
+ SQLTestsConstants.dbUser, SQLTestsConstants.dbPwd, 2, 2);
+ }
+
+ @Test
+ public void reserveConnection_reserveNewConnection_returnsConnection()
+ throws SQLException {
+ Connection conn = connectionPool.reserveConnection();
+ Assert.assertNotNull(conn);
+ }
+
+ @Test
+ public void releaseConnection_releaseUnused_shouldNotThrowException()
+ throws SQLException {
+ Connection conn = connectionPool.reserveConnection();
+ connectionPool.releaseConnection(conn);
+ Assert.assertFalse(conn.isClosed());
+ }
+
+ @Test(expected = SQLException.class)
+ public void reserveConnection_noConnectionsLeft_shouldFail()
+ throws SQLException {
+ try {
+ connectionPool.reserveConnection();
+ connectionPool.reserveConnection();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ Assert.fail("Exception before all connections used! "
+ + e.getMessage());
+ }
+
+ connectionPool.reserveConnection();
+ Assert.fail("Reserving connection didn't fail even though no connections are available!");
+ }
+
+ @Test
+ public void reserveConnection_oneConnectionLeft_returnsConnection()
+ throws SQLException {
+ try {
+ connectionPool.reserveConnection();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ Assert.fail("Exception before all connections used! "
+ + e.getMessage());
+ }
+
+ Connection conn = connectionPool.reserveConnection();
+ Assert.assertNotNull(conn);
+ }
+
+ @Test
+ public void reserveConnection_oneConnectionJustReleased_returnsConnection()
+ throws SQLException {
+ Connection conn2 = null;
+ try {
+ connectionPool.reserveConnection();
+ conn2 = connectionPool.reserveConnection();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ Assert.fail("Exception before all connections used! "
+ + e.getMessage());
+ }
+
+ connectionPool.releaseConnection(conn2);
+
+ connectionPool.reserveConnection();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void construct_allParametersNull_shouldFail() throws SQLException {
+ SimpleJDBCConnectionPool cp = new SimpleJDBCConnectionPool(null, null,
+ null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void construct_onlyDriverNameGiven_shouldFail() throws SQLException {
+ SimpleJDBCConnectionPool cp = new SimpleJDBCConnectionPool(
+ SQLTestsConstants.dbDriver, null, null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void construct_onlyDriverNameAndUrlGiven_shouldFail()
+ throws SQLException {
+ SimpleJDBCConnectionPool cp = new SimpleJDBCConnectionPool(
+ SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL, null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void construct_onlyDriverNameAndUrlAndUserGiven_shouldFail()
+ throws SQLException {
+ SimpleJDBCConnectionPool cp = new SimpleJDBCConnectionPool(
+ SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL,
+ SQLTestsConstants.dbUser, null);
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void construct_nonExistingDriver_shouldFail() throws SQLException {
+ SimpleJDBCConnectionPool cp = new SimpleJDBCConnectionPool("foo",
+ SQLTestsConstants.dbURL, SQLTestsConstants.dbUser,
+ SQLTestsConstants.dbPwd);
+ }
+
+ @Test
+ public void reserveConnection_newConnectionOpened_shouldSucceed()
+ throws SQLException {
+ connectionPool = new SimpleJDBCConnectionPool(
+ SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL,
+ SQLTestsConstants.dbUser, SQLTestsConstants.dbPwd, 0, 2);
+ Connection c = connectionPool.reserveConnection();
+ Assert.assertNotNull(c);
+ }
+
+ @Test
+ public void releaseConnection_nullConnection_shouldDoNothing() {
+ connectionPool.releaseConnection(null);
+ }
+
+ @Test
+ public void releaseConnection_failingRollback_shouldCallClose()
+ throws SQLException {
+ Connection c = EasyMock.createMock(Connection.class);
+ c.getAutoCommit();
+ EasyMock.expectLastCall().andReturn(false);
+ c.rollback();
+ EasyMock.expectLastCall().andThrow(new SQLException("Rollback failed"));
+ c.close();
+ EasyMock.expectLastCall().atLeastOnce();
+ EasyMock.replay(c);
+ // make sure the connection pool is initialized
+ // Bypass validation
+ JDBCConnectionPool realPool = ((ValidatingSimpleJDBCConnectionPool) connectionPool)
+ .getRealPool();
+ realPool.reserveConnection();
+ realPool.releaseConnection(c);
+ EasyMock.verify(c);
+ }
+
+ @Test
+ public void destroy_shouldCloseAllConnections() throws SQLException {
+ Connection c1 = connectionPool.reserveConnection();
+ Connection c2 = connectionPool.reserveConnection();
+ try {
+ connectionPool.destroy();
+ } catch (RuntimeException e) {
+ // The test connection pool throws an exception when the pool was
+ // not empty but only after cleanup of the real pool has been done
+ }
+
+ Assert.assertTrue(c1.isClosed());
+ Assert.assertTrue(c2.isClosed());
+ }
+
+ @Test
+ public void destroy_shouldCloseAllConnections2() throws SQLException {
+ Connection c1 = connectionPool.reserveConnection();
+ Connection c2 = connectionPool.reserveConnection();
+ connectionPool.releaseConnection(c1);
+ connectionPool.releaseConnection(c2);
+ connectionPool.destroy();
+ Assert.assertTrue(c1.isClosed());
+ Assert.assertTrue(c2.isClosed());
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/BetweenTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/BetweenTest.java
new file mode 100644
index 0000000000..6daf730e25
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/BetweenTest.java
@@ -0,0 +1,182 @@
+package com.vaadin.data.util.sqlcontainer.filters;
+
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.Item;
+import com.vaadin.data.Property;
+import com.vaadin.data.util.filter.Between;
+
+public class BetweenTest {
+
+ private Item itemWithPropertyValue(Object propertyId, Object value) {
+ Property<?> property = EasyMock.createMock(Property.class);
+ property.getValue();
+ EasyMock.expectLastCall().andReturn(value).anyTimes();
+ EasyMock.replay(property);
+
+ Item item = EasyMock.createMock(Item.class);
+ item.getItemProperty(propertyId);
+ EasyMock.expectLastCall().andReturn(property).anyTimes();
+ EasyMock.replay(item);
+ return item;
+ }
+
+ @Test
+ public void passesFilter_valueIsInRange_shouldBeTrue() {
+ Item item = itemWithPropertyValue("foo", 15);
+ Between between = new Between("foo", 1, 30);
+ Assert.assertTrue(between.passesFilter("foo", item));
+ }
+
+ @Test
+ public void passesFilter_valueIsOutOfRange_shouldBeFalse() {
+ Item item = itemWithPropertyValue("foo", 15);
+ Between between = new Between("foo", 0, 2);
+ Assert.assertFalse(between.passesFilter("foo", item));
+ }
+
+ @Test
+ public void passesFilter_valueNotComparable_shouldBeFalse() {
+ Item item = itemWithPropertyValue("foo", new Object());
+ Between between = new Between("foo", 0, 2);
+ Assert.assertFalse(between.passesFilter("foo", item));
+ }
+
+ @Test
+ public void appliesToProperty_differentProperties_shoudlBeFalse() {
+ Between between = new Between("foo", 0, 2);
+ Assert.assertFalse(between.appliesToProperty("bar"));
+ }
+
+ @Test
+ public void appliesToProperty_sameProperties_shouldBeTrue() {
+ Between between = new Between("foo", 0, 2);
+ Assert.assertTrue(between.appliesToProperty("foo"));
+ }
+
+ @Test
+ public void hashCode_equalInstances_shouldBeEqual() {
+ Between b1 = new Between("foo", 0, 2);
+ Between b2 = new Between("foo", 0, 2);
+ Assert.assertEquals(b1.hashCode(), b2.hashCode());
+ }
+
+ @Test
+ public void equals_differentObjects_shouldBeFalse() {
+ Between b1 = new Between("foo", 0, 2);
+ Object obj = new Object();
+ Assert.assertFalse(b1.equals(obj));
+ }
+
+ @Test
+ public void equals_sameInstance_shouldBeTrue() {
+ Between b1 = new Between("foo", 0, 2);
+ Between b2 = b1;
+ Assert.assertTrue(b1.equals(b2));
+ }
+
+ @Test
+ public void equals_equalInstances_shouldBeTrue() {
+ Between b1 = new Between("foo", 0, 2);
+ Between b2 = new Between("foo", 0, 2);
+ Assert.assertTrue(b1.equals(b2));
+ }
+
+ @Test
+ public void equals_equalInstances2_shouldBeTrue() {
+ Between b1 = new Between(null, null, null);
+ Between b2 = new Between(null, null, null);
+ Assert.assertTrue(b1.equals(b2));
+ }
+
+ @Test
+ public void equals_secondValueDiffers_shouldBeFalse() {
+ Between b1 = new Between("foo", 0, 1);
+ Between b2 = new Between("foo", 0, 2);
+ Assert.assertFalse(b1.equals(b2));
+ }
+
+ @Test
+ public void equals_firstAndSecondValueDiffers_shouldBeFalse() {
+ Between b1 = new Between("foo", 0, null);
+ Between b2 = new Between("foo", 1, 2);
+ Assert.assertFalse(b1.equals(b2));
+ }
+
+ @Test
+ public void equals_propertyAndFirstAndSecondValueDiffers_shouldBeFalse() {
+ Between b1 = new Between("foo", null, 1);
+ Between b2 = new Between("bar", 1, 2);
+ Assert.assertFalse(b1.equals(b2));
+ }
+
+ @Test
+ public void equals_propertiesDiffer_shouldBeFalse() {
+ Between b1 = new Between(null, 0, 1);
+ Between b2 = new Between("bar", 0, 1);
+ Assert.assertFalse(b1.equals(b2));
+ }
+
+ @Test
+ public void hashCode_nullStartValue_shouldBeEqual() {
+ Between b1 = new Between("foo", null, 2);
+ Between b2 = new Between("foo", null, 2);
+ Assert.assertEquals(b1.hashCode(), b2.hashCode());
+ }
+
+ @Test
+ public void hashCode_nullEndValue_shouldBeEqual() {
+ Between b1 = new Between("foo", 0, null);
+ Between b2 = new Between("foo", 0, null);
+ Assert.assertEquals(b1.hashCode(), b2.hashCode());
+ }
+
+ @Test
+ public void hashCode_nullPropertyId_shouldBeEqual() {
+ Between b1 = new Between(null, 0, 2);
+ Between b2 = new Between(null, 0, 2);
+ Assert.assertEquals(b1.hashCode(), b2.hashCode());
+ }
+
+ @Test
+ public void passesFilter_nullValue_filterIsPassed() {
+ String id = "id";
+ Between between = new Between(id, null, null);
+ Assert.assertTrue(between.passesFilter(id,
+ itemWithPropertyValue(id, null)));
+ }
+
+ @Test
+ public void passesFilter_nullStartValue_filterIsPassed() {
+ String id = "id";
+ Between between = new Between(id, null, 2);
+ Assert.assertTrue(between
+ .passesFilter(id, itemWithPropertyValue(id, 1)));
+ }
+
+ @Test
+ public void passesFilter_nullEndValue_filterIsPassed() {
+ String id = "id";
+ Between between = new Between(id, 0, null);
+ Assert.assertTrue(between
+ .passesFilter(id, itemWithPropertyValue(id, 1)));
+ }
+
+ @Test
+ public void passesFilter_nullStartValueAndEndValue_filterIsPassed() {
+ String id = "id";
+ Between between = new Between(id, null, null);
+ Assert.assertTrue(between
+ .passesFilter(id, itemWithPropertyValue(id, 1)));
+ }
+
+ @Test
+ public void passesFilter_nullStartValueAndEndValueAndValueIsNotComparable_filterIsNotPassed() {
+ String id = "id";
+ Between between = new Between(id, null, null);
+ Assert.assertFalse(between.passesFilter(id,
+ itemWithPropertyValue(id, new Object())));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/CompareTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/CompareTest.java
new file mode 100644
index 0000000000..252acd81fc
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/CompareTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.data.util.sqlcontainer.filters;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.util.filter.Compare;
+
+public class CompareTest {
+
+ @Test
+ public void testEquals() {
+ Compare c1 = new Compare.Equal("prop1", "val1");
+ Compare c2 = new Compare.Equal("prop1", "val1");
+ Assert.assertTrue(c1.equals(c2));
+ }
+
+ @Test
+ public void testDifferentTypeEquals() {
+ Compare c1 = new Compare.Equal("prop1", "val1");
+ Compare c2 = new Compare.Greater("prop1", "val1");
+ Assert.assertFalse(c1.equals(c2));
+ }
+
+ @Test
+ public void testEqualsNull() {
+ Compare c1 = new Compare.Equal("prop1", "val1");
+ Assert.assertFalse(c1.equals(null));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/LikeTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/LikeTest.java
new file mode 100644
index 0000000000..f1130aad80
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/LikeTest.java
@@ -0,0 +1,229 @@
+package com.vaadin.data.util.sqlcontainer.filters;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.Item;
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.data.util.PropertysetItem;
+import com.vaadin.data.util.filter.Like;
+
+public class LikeTest {
+
+ @Test
+ public void passesFilter_valueIsNotStringType_shouldFail() {
+ Like like = new Like("test", "%foo%");
+
+ Item item = new PropertysetItem();
+ item.addItemProperty("test", new ObjectProperty<Integer>(5));
+
+ Assert.assertFalse(like.passesFilter("id", item));
+ }
+
+ @Test
+ public void passesFilter_containsLikeQueryOnStringContainingValue_shouldSucceed() {
+ Like like = new Like("test", "%foo%");
+
+ Item item = new PropertysetItem();
+ item.addItemProperty("test", new ObjectProperty<String>("asdfooghij"));
+
+ Assert.assertTrue(like.passesFilter("id", item));
+ }
+
+ @Test
+ public void passesFilter_containsLikeQueryOnStringContainingValueCaseInsensitive_shouldSucceed() {
+ Like like = new Like("test", "%foo%");
+ like.setCaseSensitive(false);
+
+ Item item = new PropertysetItem();
+ item.addItemProperty("test", new ObjectProperty<String>("asdfOOghij"));
+
+ Assert.assertTrue(like.passesFilter("id", item));
+ }
+
+ @Test
+ public void passesFilter_containsLikeQueryOnStringContainingValueConstructedCaseInsensitive_shouldSucceed() {
+ Like like = new Like("test", "%foo%", false);
+
+ Item item = new PropertysetItem();
+ item.addItemProperty("test", new ObjectProperty<String>("asdfOOghij"));
+
+ Assert.assertTrue(like.passesFilter("id", item));
+ }
+
+ @Test
+ public void passesFilter_containsLikeQueryOnStringNotContainingValue_shouldFail() {
+ Like like = new Like("test", "%foo%");
+
+ Item item = new PropertysetItem();
+ item.addItemProperty("test", new ObjectProperty<String>("asdbarghij"));
+
+ Assert.assertFalse(like.passesFilter("id", item));
+ }
+
+ @Test
+ public void passesFilter_containsLikeQueryOnStringExactlyEqualToValue_shouldSucceed() {
+ Like like = new Like("test", "%foo%");
+
+ Item item = new PropertysetItem();
+ item.addItemProperty("test", new ObjectProperty<String>("foo"));
+
+ Assert.assertTrue(like.passesFilter("id", item));
+ }
+
+ @Test
+ public void passesFilter_containsLikeQueryOnStringEqualToValueMinusOneCharAtTheEnd_shouldFail() {
+ Like like = new Like("test", "%foo%");
+
+ Item item = new PropertysetItem();
+ item.addItemProperty("test", new ObjectProperty<String>("fo"));
+
+ Assert.assertFalse(like.passesFilter("id", item));
+ }
+
+ @Test
+ public void passesFilter_beginsWithLikeQueryOnStringBeginningWithValue_shouldSucceed() {
+ Like like = new Like("test", "foo%");
+
+ Item item = new PropertysetItem();
+ item.addItemProperty("test", new ObjectProperty<String>("foobar"));
+
+ Assert.assertTrue(like.passesFilter("id", item));
+ }
+
+ @Test
+ public void passesFilter_beginsWithLikeQueryOnStringNotBeginningWithValue_shouldFail() {
+ Like like = new Like("test", "foo%");
+
+ Item item = new PropertysetItem();
+ item.addItemProperty("test", new ObjectProperty<String>("barfoo"));
+
+ Assert.assertFalse(like.passesFilter("id", item));
+ }
+
+ @Test
+ public void passesFilter_endsWithLikeQueryOnStringEndingWithValue_shouldSucceed() {
+ Like like = new Like("test", "%foo");
+
+ Item item = new PropertysetItem();
+ item.addItemProperty("test", new ObjectProperty<String>("barfoo"));
+
+ Assert.assertTrue(like.passesFilter("id", item));
+ }
+
+ @Test
+ public void passesFilter_endsWithLikeQueryOnStringNotEndingWithValue_shouldFail() {
+ Like like = new Like("test", "%foo");
+
+ Item item = new PropertysetItem();
+ item.addItemProperty("test", new ObjectProperty<String>("foobar"));
+
+ Assert.assertFalse(like.passesFilter("id", item));
+ }
+
+ @Test
+ public void passesFilter_startsWithAndEndsWithOnMatchingValue_shouldSucceed() {
+ Like like = new Like("test", "foo%bar");
+
+ Item item = new PropertysetItem();
+ item.addItemProperty("test", new ObjectProperty<String>("fooASDFbar"));
+
+ Assert.assertTrue(like.passesFilter("id", item));
+ }
+
+ @Test
+ public void appliesToProperty_valueIsProperty_shouldBeTrue() {
+ Like like = new Like("test", "%foo");
+ Assert.assertTrue(like.appliesToProperty("test"));
+ }
+
+ @Test
+ public void appliesToProperty_valueIsNotProperty_shouldBeFalse() {
+ Like like = new Like("test", "%foo");
+ Assert.assertFalse(like.appliesToProperty("bar"));
+ }
+
+ @Test
+ public void equals_sameInstances_shouldBeTrue() {
+ Like like1 = new Like("test", "%foo");
+ Like like2 = like1;
+ Assert.assertTrue(like1.equals(like2));
+ }
+
+ @Test
+ public void equals_twoEqualInstances_shouldBeTrue() {
+ Like like1 = new Like("test", "foo");
+ Like like2 = new Like("test", "foo");
+ Assert.assertTrue(like1.equals(like2));
+ }
+
+ @Test
+ public void equals_differentValues_shouldBeFalse() {
+ Like like1 = new Like("test", "foo");
+ Like like2 = new Like("test", "bar");
+ Assert.assertFalse(like1.equals(like2));
+ }
+
+ @Test
+ public void equals_differentProperties_shouldBeFalse() {
+ Like like1 = new Like("foo", "test");
+ Like like2 = new Like("bar", "test");
+ Assert.assertFalse(like1.equals(like2));
+ }
+
+ @Test
+ public void equals_differentPropertiesAndValues_shouldBeFalse() {
+ Like like1 = new Like("foo", "bar");
+ Like like2 = new Like("baz", "zomg");
+ Assert.assertFalse(like1.equals(like2));
+ }
+
+ @Test
+ public void equals_differentClasses_shouldBeFalse() {
+ Like like1 = new Like("foo", "bar");
+ Object obj = new Object();
+ Assert.assertFalse(like1.equals(obj));
+ }
+
+ @Test
+ public void equals_bothHaveNullProperties_shouldBeTrue() {
+ Like like1 = new Like(null, "foo");
+ Like like2 = new Like(null, "foo");
+ Assert.assertTrue(like1.equals(like2));
+ }
+
+ @Test
+ public void equals_bothHaveNullValues_shouldBeTrue() {
+ Like like1 = new Like("foo", null);
+ Like like2 = new Like("foo", null);
+ Assert.assertTrue(like1.equals(like2));
+ }
+
+ @Test
+ public void equals_onePropertyIsNull_shouldBeFalse() {
+ Like like1 = new Like(null, "bar");
+ Like like2 = new Like("foo", "baz");
+ Assert.assertFalse(like1.equals(like2));
+ }
+
+ @Test
+ public void equals_oneValueIsNull_shouldBeFalse() {
+ Like like1 = new Like("foo", null);
+ Like like2 = new Like("baz", "bar");
+ Assert.assertFalse(like1.equals(like2));
+ }
+
+ @Test
+ public void hashCode_equalInstances_shouldBeEqual() {
+ Like like1 = new Like("test", "foo");
+ Like like2 = new Like("test", "foo");
+ Assert.assertEquals(like1.hashCode(), like2.hashCode());
+ }
+
+ @Test
+ public void hashCode_differentPropertiesAndValues_shouldNotEqual() {
+ Like like1 = new Like("foo", "bar");
+ Like like2 = new Like("baz", "zomg");
+ Assert.assertTrue(like1.hashCode() != like2.hashCode());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/generator/SQLGeneratorsTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/generator/SQLGeneratorsTest.java
new file mode 100644
index 0000000000..c2dbf0f12a
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/sqlcontainer/generator/SQLGeneratorsTest.java
@@ -0,0 +1,242 @@
+package com.vaadin.data.util.sqlcontainer.generator;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.Container.Filter;
+import com.vaadin.data.util.filter.Like;
+import com.vaadin.data.util.filter.Or;
+import com.vaadin.data.util.sqlcontainer.DataGenerator;
+import com.vaadin.data.util.sqlcontainer.RowItem;
+import com.vaadin.data.util.sqlcontainer.SQLContainer;
+import com.vaadin.data.util.sqlcontainer.SQLTestsConstants;
+import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool;
+import com.vaadin.data.util.sqlcontainer.query.OrderBy;
+import com.vaadin.data.util.sqlcontainer.query.TableQuery;
+import com.vaadin.data.util.sqlcontainer.query.ValidatingSimpleJDBCConnectionPool;
+import com.vaadin.data.util.sqlcontainer.query.generator.DefaultSQLGenerator;
+import com.vaadin.data.util.sqlcontainer.query.generator.MSSQLGenerator;
+import com.vaadin.data.util.sqlcontainer.query.generator.OracleGenerator;
+import com.vaadin.data.util.sqlcontainer.query.generator.SQLGenerator;
+import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
+
+public class SQLGeneratorsTest {
+ private JDBCConnectionPool connectionPool;
+
+ @Before
+ public void setUp() throws SQLException {
+
+ try {
+ connectionPool = new ValidatingSimpleJDBCConnectionPool(
+ SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL,
+ SQLTestsConstants.dbUser, SQLTestsConstants.dbPwd, 2, 2);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ Assert.fail(e.getMessage());
+ }
+
+ DataGenerator.addPeopleToDatabase(connectionPool);
+ }
+
+ @After
+ public void tearDown() {
+ if (connectionPool != null) {
+ connectionPool.destroy();
+ }
+ }
+
+ @Test
+ public void generateSelectQuery_basicQuery_shouldSucceed() {
+ SQLGenerator sg = new DefaultSQLGenerator();
+ StatementHelper sh = sg.generateSelectQuery("TABLE", null, null, 0, 0,
+ null);
+ Assert.assertEquals(sh.getQueryString(), "SELECT * FROM TABLE");
+ }
+
+ @Test
+ public void generateSelectQuery_pagingAndColumnsSet_shouldSucceed() {
+ SQLGenerator sg = new DefaultSQLGenerator();
+ StatementHelper sh = sg.generateSelectQuery("TABLE", null, null, 4, 8,
+ "COL1, COL2, COL3");
+ Assert.assertEquals(sh.getQueryString(),
+ "SELECT COL1, COL2, COL3 FROM TABLE LIMIT 8 OFFSET 4");
+ }
+
+ /**
+ * Note: Only tests one kind of filter and ordering.
+ */
+ @Test
+ public void generateSelectQuery_filtersAndOrderingSet_shouldSucceed() {
+ SQLGenerator sg = new DefaultSQLGenerator();
+ List<com.vaadin.data.Container.Filter> f = new ArrayList<Filter>();
+ f.add(new Like("name", "%lle"));
+ List<OrderBy> ob = Arrays.asList(new OrderBy("name", true));
+ StatementHelper sh = sg.generateSelectQuery("TABLE", f, ob, 0, 0, null);
+ Assert.assertEquals(sh.getQueryString(),
+ "SELECT * FROM TABLE WHERE \"name\" LIKE ? ORDER BY \"name\" ASC");
+ }
+
+ @Test
+ public void generateSelectQuery_filtersAndOrderingSet_exclusiveFilteringMode_shouldSucceed() {
+ SQLGenerator sg = new DefaultSQLGenerator();
+ List<Filter> f = new ArrayList<Filter>();
+ f.add(new Or(new Like("name", "%lle"), new Like("name", "vi%")));
+ List<OrderBy> ob = Arrays.asList(new OrderBy("name", true));
+ StatementHelper sh = sg.generateSelectQuery("TABLE", f, ob, 0, 0, null);
+ // TODO
+ Assert.assertEquals(sh.getQueryString(),
+ "SELECT * FROM TABLE WHERE (\"name\" LIKE ? "
+ + "OR \"name\" LIKE ?) ORDER BY \"name\" ASC");
+ }
+
+ @Test
+ public void generateDeleteQuery_basicQuery_shouldSucceed()
+ throws SQLException {
+ /*
+ * No need to run this for Oracle/MSSQL generators since the
+ * DefaultSQLGenerator method would be called anyway.
+ */
+ if (SQLTestsConstants.sqlGen instanceof MSSQLGenerator
+ || SQLTestsConstants.sqlGen instanceof OracleGenerator) {
+ return;
+ }
+ SQLGenerator sg = SQLTestsConstants.sqlGen;
+ TableQuery query = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+ SQLContainer container = new SQLContainer(query);
+
+ StatementHelper sh = sg.generateDeleteQuery(
+ "people",
+ query.getPrimaryKeyColumns(),
+ null,
+ (RowItem) container.getItem(container.getItemIds().iterator()
+ .next()));
+ Assert.assertEquals("DELETE FROM people WHERE \"ID\" = ?",
+ sh.getQueryString());
+ }
+
+ @Test
+ public void generateUpdateQuery_basicQuery_shouldSucceed()
+ throws SQLException {
+ /*
+ * No need to run this for Oracle/MSSQL generators since the
+ * DefaultSQLGenerator method would be called anyway.
+ */
+ if (SQLTestsConstants.sqlGen instanceof MSSQLGenerator
+ || SQLTestsConstants.sqlGen instanceof OracleGenerator) {
+ return;
+ }
+ SQLGenerator sg = new DefaultSQLGenerator();
+ TableQuery query = new TableQuery("people", connectionPool);
+ SQLContainer container = new SQLContainer(query);
+
+ RowItem ri = (RowItem) container.getItem(container.getItemIds()
+ .iterator().next());
+ ri.getItemProperty("NAME").setValue("Viljami");
+
+ StatementHelper sh = sg.generateUpdateQuery("people", ri);
+ Assert.assertTrue("UPDATE people SET \"NAME\" = ?, \"AGE\" = ? WHERE \"ID\" = ?"
+ .equals(sh.getQueryString())
+ || "UPDATE people SET \"AGE\" = ?, \"NAME\" = ? WHERE \"ID\" = ?"
+ .equals(sh.getQueryString()));
+ }
+
+ @Test
+ public void generateInsertQuery_basicQuery_shouldSucceed()
+ throws SQLException {
+ /*
+ * No need to run this for Oracle/MSSQL generators since the
+ * DefaultSQLGenerator method would be called anyway.
+ */
+ if (SQLTestsConstants.sqlGen instanceof MSSQLGenerator
+ || SQLTestsConstants.sqlGen instanceof OracleGenerator) {
+ return;
+ }
+ SQLGenerator sg = new DefaultSQLGenerator();
+ TableQuery query = new TableQuery("people", connectionPool);
+ SQLContainer container = new SQLContainer(query);
+
+ RowItem ri = (RowItem) container.getItem(container.addItem());
+ ri.getItemProperty("NAME").setValue("Viljami");
+
+ StatementHelper sh = sg.generateInsertQuery("people", ri);
+
+ Assert.assertTrue("INSERT INTO people (\"NAME\", \"AGE\") VALUES (?, ?)"
+ .equals(sh.getQueryString())
+ || "INSERT INTO people (\"AGE\", \"NAME\") VALUES (?, ?)"
+ .equals(sh.getQueryString()));
+ }
+
+ @Test
+ public void generateComplexSelectQuery_forOracle_shouldSucceed()
+ throws SQLException {
+ SQLGenerator sg = new OracleGenerator();
+ List<Filter> f = new ArrayList<Filter>();
+ f.add(new Like("name", "%lle"));
+ List<OrderBy> ob = Arrays.asList(new OrderBy("name", true));
+ StatementHelper sh = sg.generateSelectQuery("TABLE", f, ob, 4, 8,
+ "NAME, ID");
+ Assert.assertEquals(
+ "SELECT * FROM (SELECT x.*, ROWNUM AS \"rownum\" FROM"
+ + " (SELECT NAME, ID FROM TABLE WHERE \"name\" LIKE ?"
+ + " ORDER BY \"name\" ASC) x) WHERE \"rownum\" BETWEEN 5 AND 12",
+ sh.getQueryString());
+ }
+
+ @Test
+ public void generateComplexSelectQuery_forMSSQL_shouldSucceed()
+ throws SQLException {
+ SQLGenerator sg = new MSSQLGenerator();
+ List<Filter> f = new ArrayList<Filter>();
+ f.add(new Like("name", "%lle"));
+ List<OrderBy> ob = Arrays.asList(new OrderBy("name", true));
+ StatementHelper sh = sg.generateSelectQuery("TABLE", f, ob, 4, 8,
+ "NAME, ID");
+ Assert.assertEquals(sh.getQueryString(),
+ "SELECT * FROM (SELECT row_number() OVER "
+ + "( ORDER BY \"name\" ASC) AS rownum, NAME, ID "
+ + "FROM TABLE WHERE \"name\" LIKE ?) "
+ + "AS a WHERE a.rownum BETWEEN 5 AND 12");
+ }
+
+ @Test
+ public void generateComplexSelectQuery_forOracle_exclusiveFilteringMode_shouldSucceed()
+ throws SQLException {
+ SQLGenerator sg = new OracleGenerator();
+ List<Filter> f = new ArrayList<Filter>();
+ f.add(new Or(new Like("name", "%lle"), new Like("name", "vi%")));
+ List<OrderBy> ob = Arrays.asList(new OrderBy("name", true));
+ StatementHelper sh = sg.generateSelectQuery("TABLE", f, ob, 4, 8,
+ "NAME, ID");
+ Assert.assertEquals(
+ sh.getQueryString(),
+ "SELECT * FROM (SELECT x.*, ROWNUM AS \"rownum\" FROM"
+ + " (SELECT NAME, ID FROM TABLE WHERE (\"name\" LIKE ?"
+ + " OR \"name\" LIKE ?) "
+ + "ORDER BY \"name\" ASC) x) WHERE \"rownum\" BETWEEN 5 AND 12");
+ }
+
+ @Test
+ public void generateComplexSelectQuery_forMSSQL_exclusiveFilteringMode_shouldSucceed()
+ throws SQLException {
+ SQLGenerator sg = new MSSQLGenerator();
+ List<Filter> f = new ArrayList<Filter>();
+ f.add(new Or(new Like("name", "%lle"), new Like("name", "vi%")));
+ List<OrderBy> ob = Arrays.asList(new OrderBy("name", true));
+ StatementHelper sh = sg.generateSelectQuery("TABLE", f, ob, 4, 8,
+ "NAME, ID");
+ Assert.assertEquals(sh.getQueryString(),
+ "SELECT * FROM (SELECT row_number() OVER "
+ + "( ORDER BY \"name\" ASC) AS rownum, NAME, ID "
+ + "FROM TABLE WHERE (\"name\" LIKE ? "
+ + "OR \"name\" LIKE ?)) "
+ + "AS a WHERE a.rownum BETWEEN 5 AND 12");
+ }
+}
diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/generator/StatementHelperTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/generator/StatementHelperTest.java
new file mode 100644
index 0000000000..b89b7e747d
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/sqlcontainer/generator/StatementHelperTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.data.util.sqlcontainer.generator;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
+
+/**
+ *
+ * @author Vaadin Ltd
+ */
+public class StatementHelperTest {
+
+ @Test
+ public void testSetValueNullParameter() throws SQLException {
+ StatementHelper helper = new StatementHelper();
+ helper.addParameterValue(null, StatementHelper.class);
+ PreparedStatement statement = EasyMock
+ .createMock(PreparedStatement.class);
+ // should throw SQLException, not NPE
+ try {
+ helper.setParameterValuesToStatement(statement);
+ Assert.fail("Expected SQLExecption for unsupported type");
+ } catch (SQLException e) {
+ // Exception should contain info about which parameter and the type
+ // which was unsupported
+ Assert.assertTrue(e.getMessage().contains("parameter 0"));
+ Assert.assertTrue(e.getMessage().contains(
+ StatementHelper.class.getName()));
+ }
+ }
+
+ @Test
+ public void testSetByteArrayValue() throws SQLException {
+ StatementHelper helper = new StatementHelper();
+ helper.addParameterValue(null, byte[].class);
+ PreparedStatement statement = EasyMock
+ .createMock(PreparedStatement.class);
+ // should not throw SQLException
+ helper.setParameterValuesToStatement(statement);
+
+ EasyMock.replay(statement);
+ statement.setBytes(1, null);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/query/FreeformQueryTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/query/FreeformQueryTest.java
new file mode 100644
index 0000000000..bbf083c158
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/sqlcontainer/query/FreeformQueryTest.java
@@ -0,0 +1,1010 @@
+package com.vaadin.data.util.sqlcontainer.query;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.Container.Filter;
+import com.vaadin.data.util.filter.Like;
+import com.vaadin.data.util.sqlcontainer.DataGenerator;
+import com.vaadin.data.util.sqlcontainer.RowId;
+import com.vaadin.data.util.sqlcontainer.RowItem;
+import com.vaadin.data.util.sqlcontainer.SQLContainer;
+import com.vaadin.data.util.sqlcontainer.SQLTestsConstants;
+import com.vaadin.data.util.sqlcontainer.SQLTestsConstants.DB;
+import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool;
+import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
+
+public class FreeformQueryTest {
+
+ private static final int offset = SQLTestsConstants.offset;
+ private JDBCConnectionPool connectionPool;
+
+ @Before
+ public void setUp() throws SQLException {
+
+ try {
+ connectionPool = new ValidatingSimpleJDBCConnectionPool(
+ SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL,
+ SQLTestsConstants.dbUser, SQLTestsConstants.dbPwd, 2, 2);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ Assert.fail(e.getMessage());
+ }
+
+ DataGenerator.addPeopleToDatabase(connectionPool);
+ }
+
+ @After
+ public void tearDown() {
+ if (connectionPool != null) {
+ connectionPool.destroy();
+ }
+ }
+
+ @Test
+ public void construction_legalParameters_shouldSucceed() {
+ FreeformQuery ffQuery = new FreeformQuery("SELECT * FROM foo",
+ Arrays.asList("ID"), connectionPool);
+ Assert.assertArrayEquals(new Object[] { "ID" }, ffQuery
+ .getPrimaryKeyColumns().toArray());
+
+ Assert.assertEquals("SELECT * FROM foo", ffQuery.getQueryString());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void construction_emptyQueryString_shouldFail() {
+ new FreeformQuery("", Arrays.asList("ID"), connectionPool);
+ }
+
+ @Test
+ public void construction_nullPrimaryKeys_shouldSucceed() {
+ new FreeformQuery("SELECT * FROM foo", null, connectionPool);
+ }
+
+ @Test
+ public void construction_nullPrimaryKeys2_shouldSucceed() {
+ new FreeformQuery("SELECT * FROM foo", connectionPool);
+ }
+
+ @Test
+ public void construction_emptyPrimaryKeys_shouldSucceed() {
+ new FreeformQuery("SELECT * FROM foo", connectionPool);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void construction_emptyStringsInPrimaryKeys_shouldFail() {
+ new FreeformQuery("SELECT * FROM foo", Arrays.asList(""),
+ connectionPool);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void construction_nullConnectionPool_shouldFail() {
+ new FreeformQuery("SELECT * FROM foo", Arrays.asList("ID"), null);
+ }
+
+ @Test
+ public void getCount_simpleQuery_returnsFour() throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ Assert.assertEquals(4, query.getCount());
+ }
+
+ @Test(expected = SQLException.class)
+ public void getCount_illegalQuery_shouldThrowSQLException()
+ throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM asdf",
+ Arrays.asList("ID"), connectionPool);
+ query.getResults(0, 50);
+ }
+
+ @Test
+ public void getCount_simpleQueryTwoMorePeopleAdded_returnsSix()
+ throws SQLException {
+ // Add some people
+ Connection conn = connectionPool.reserveConnection();
+ Statement statement = conn.createStatement();
+ if (SQLTestsConstants.db == DB.MSSQL) {
+ statement.executeUpdate("insert into people values('Bengt', 30)");
+ statement.executeUpdate("insert into people values('Ingvar', 50)");
+ } else {
+ statement
+ .executeUpdate("insert into people values(default, 'Bengt', 30)");
+ statement
+ .executeUpdate("insert into people values(default, 'Ingvar', 50)");
+ }
+ statement.close();
+ conn.commit();
+ connectionPool.releaseConnection(conn);
+
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+
+ Assert.assertEquals(6, query.getCount());
+ }
+
+ @Test
+ public void getCount_moreComplexQuery_returnsThree() throws SQLException {
+ FreeformQuery query = new FreeformQuery(
+ "SELECT * FROM people WHERE \"NAME\" LIKE '%lle'",
+ connectionPool, new String[] { "ID" });
+ Assert.assertEquals(3, query.getCount());
+ }
+
+ @Test
+ public void getCount_normalState_releasesConnection() throws SQLException {
+ FreeformQuery query = new FreeformQuery(
+ "SELECT * FROM people WHERE \"NAME\" LIKE '%lle'",
+ connectionPool, "ID");
+ query.getCount();
+ query.getCount();
+ Connection c = connectionPool.reserveConnection();
+ Assert.assertNotNull(c);
+ // Cleanup to make test connection pool happy
+ connectionPool.releaseConnection(c);
+ }
+
+ @Test
+ public void getCount_delegateRegistered_shouldUseDelegate()
+ throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ EasyMock.expect(delegate.getCountQuery()).andReturn(
+ "SELECT COUNT(*) FROM people WHERE \"NAME\" LIKE '%lle'");
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+ Assert.assertEquals(3, query.getCount());
+ EasyMock.verify(delegate);
+ }
+
+ @Test
+ public void getCount_delegateRegisteredZeroRows_returnsZero()
+ throws SQLException {
+ DataGenerator.createGarbage(connectionPool);
+ FreeformQuery query = new FreeformQuery("SELECT * FROM GARBAGE",
+ Arrays.asList("ID"), connectionPool);
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ EasyMock.expect(delegate.getCountQuery()).andReturn(
+ "SELECT COUNT(*) FROM GARBAGE");
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+ Assert.assertEquals(0, query.getCount());
+ EasyMock.verify(delegate);
+ }
+
+ @Test
+ public void getResults_simpleQuery_returnsFourRecords() throws SQLException {
+ FreeformQuery query = new FreeformQuery(
+ "SELECT \"ID\",\"NAME\" FROM people", Arrays.asList("ID"),
+ connectionPool);
+ query.beginTransaction();
+ ResultSet rs = query.getResults(0, 0);
+
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(0 + offset, rs.getInt(1));
+ Assert.assertEquals("Ville", rs.getString(2));
+
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(1 + offset, rs.getInt(1));
+ Assert.assertEquals("Kalle", rs.getString(2));
+
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(2 + offset, rs.getInt(1));
+ Assert.assertEquals("Pelle", rs.getString(2));
+
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(3 + offset, rs.getInt(1));
+ Assert.assertEquals("Börje", rs.getString(2));
+
+ Assert.assertFalse(rs.next());
+ query.commit();
+ }
+
+ @Test
+ public void getResults_moreComplexQuery_returnsThreeRecords()
+ throws SQLException {
+ FreeformQuery query = new FreeformQuery(
+ "SELECT * FROM people WHERE \"NAME\" LIKE '%lle'",
+ Arrays.asList("ID"), connectionPool);
+ query.beginTransaction();
+ ResultSet rs = query.getResults(0, 0);
+
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(0 + offset, rs.getInt(1));
+ Assert.assertEquals("Ville", rs.getString(2));
+
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(1 + offset, rs.getInt(1));
+ Assert.assertEquals("Kalle", rs.getString(2));
+
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(2 + offset, rs.getInt(1));
+ Assert.assertEquals("Pelle", rs.getString(2));
+
+ Assert.assertFalse(rs.next());
+ query.commit();
+ }
+
+ @Test
+ public void getResults_noDelegate5000Rows_returns5000rows()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ query.beginTransaction();
+ ResultSet rs = query.getResults(0, 0);
+ for (int i = 0; i < 5000; i++) {
+ Assert.assertTrue(rs.next());
+ }
+ Assert.assertFalse(rs.next());
+ query.commit();
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void setFilters_noDelegate_shouldFail() {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ ArrayList<Filter> filters = new ArrayList<Filter>();
+ filters.add(new Like("name", "%lle"));
+ query.setFilters(filters);
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void setOrderBy_noDelegate_shouldFail() {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ query.setOrderBy(Arrays.asList(new OrderBy("name", true)));
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void storeRow_noDelegateNoTransactionActive_shouldFail()
+ throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ query.storeRow(new RowItem(new SQLContainer(query), new RowId(
+ new Object[] { 1 }), null));
+ }
+
+ @Test
+ public void storeRow_noDelegate_shouldFail() throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ SQLContainer container = EasyMock.createNiceMock(SQLContainer.class);
+ EasyMock.replay(container);
+ query.beginTransaction();
+ try {
+ query.storeRow(new RowItem(container,
+ new RowId(new Object[] { 1 }), null));
+ Assert.fail("storeRow should fail when there is no delegate");
+ } catch (UnsupportedOperationException e) {
+ // Cleanup to make test connection pool happy
+ query.rollback();
+ }
+ }
+
+ @Test
+ public void removeRow_noDelegate_shouldFail() throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ SQLContainer container = EasyMock.createNiceMock(SQLContainer.class);
+ EasyMock.replay(container);
+ query.beginTransaction();
+ try {
+ query.removeRow(new RowItem(container,
+ new RowId(new Object[] { 1 }), null));
+ Assert.fail("removeRow should fail when there is no delgate");
+ } catch (UnsupportedOperationException e) {
+ // Cleanup to make test connection pool happy
+ query.rollback();
+ }
+ }
+
+ @Test
+ public void commit_readOnly_shouldSucceed() throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ query.beginTransaction();
+ query.commit();
+ }
+
+ @Test
+ public void rollback_readOnly_shouldSucceed() throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ query.beginTransaction();
+ query.rollback();
+ }
+
+ @Test(expected = SQLException.class)
+ public void commit_noActiveTransaction_shouldFail() throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ query.commit();
+ }
+
+ @Test(expected = SQLException.class)
+ public void rollback_noActiveTransaction_shouldFail() throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ query.rollback();
+ }
+
+ @Test
+ public void containsRowWithKeys_simpleQueryWithExistingKeys_returnsTrue()
+ throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ Assert.assertTrue(query.containsRowWithKey(1));
+ }
+
+ @Test
+ public void containsRowWithKeys_simpleQueryWithNonexistingKeys_returnsTrue()
+ throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ Assert.assertFalse(query.containsRowWithKey(1337));
+ }
+
+ // (expected = SQLException.class)
+ @Test
+ public void containsRowWithKeys_simpleQueryWithInvalidKeys_shouldFail()
+ throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ Assert.assertFalse(query.containsRowWithKey(38796));
+ }
+
+ @Test
+ public void containsRowWithKeys_queryContainingWhereClauseAndExistingKeys_returnsTrue()
+ throws SQLException {
+ FreeformQuery query = new FreeformQuery(
+ "SELECT * FROM people WHERE \"NAME\" LIKE '%lle'",
+ Arrays.asList("ID"), connectionPool);
+ Assert.assertTrue(query.containsRowWithKey(1));
+ }
+
+ @Test
+ public void containsRowWithKeys_queryContainingLowercaseWhereClauseAndExistingKeys_returnsTrue()
+ throws SQLException {
+ FreeformQuery query = new FreeformQuery(
+ "select * from people where \"NAME\" like '%lle'",
+ Arrays.asList("ID"), connectionPool);
+ Assert.assertTrue(query.containsRowWithKey(1));
+ }
+
+ @Test
+ public void containsRowWithKeys_nullKeys_shouldFailAndReleaseConnections()
+ throws SQLException {
+ FreeformQuery query = new FreeformQuery(
+ "select * from people where \"NAME\" like '%lle'",
+ Arrays.asList("ID"), connectionPool);
+ try {
+ query.containsRowWithKey(new Object[] { null });
+ } catch (SQLException e) {
+ // We should now be able to reserve two connections
+ connectionPool.reserveConnection();
+ connectionPool.reserveConnection();
+ }
+ }
+
+ /*
+ * -------- Tests with a delegate ---------
+ */
+
+ @Test
+ public void setDelegate_noExistingDelegate_shouldRegisterNewDelegate() {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ query.setDelegate(delegate);
+ Assert.assertEquals(delegate, query.getDelegate());
+ }
+
+ @Test
+ public void getResults_hasDelegate_shouldCallDelegate() throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ if (SQLTestsConstants.db == DB.MSSQL) {
+ EasyMock.expect(delegate.getQueryString(0, 2))
+ .andReturn(
+ "SELECT * FROM (SELECT row_number()"
+ + "OVER (ORDER BY id ASC) AS rownum, * FROM people)"
+ + " AS a WHERE a.rownum BETWEEN 0 AND 2");
+ } else if (SQLTestsConstants.db == DB.ORACLE) {
+ EasyMock.expect(delegate.getQueryString(0, 2))
+ .andReturn(
+ "SELECT * FROM (SELECT x.*, ROWNUM AS r FROM"
+ + " (SELECT * FROM people) x) WHERE r BETWEEN 1 AND 2");
+ } else {
+ EasyMock.expect(delegate.getQueryString(0, 2)).andReturn(
+ "SELECT * FROM people LIMIT 2 OFFSET 0");
+ }
+ EasyMock.replay(delegate);
+
+ query.setDelegate(delegate);
+ query.beginTransaction();
+ query.getResults(0, 2);
+ EasyMock.verify(delegate);
+ query.commit();
+ }
+
+ @Test
+ public void getResults_delegateImplementsGetQueryString_shouldHonorOffsetAndPagelength()
+ throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ if (SQLTestsConstants.db == DB.MSSQL) {
+ EasyMock.expect(delegate.getQueryString(0, 2))
+ .andReturn(
+ "SELECT * FROM (SELECT row_number()"
+ + "OVER (ORDER BY id ASC) AS rownum, * FROM people)"
+ + " AS a WHERE a.rownum BETWEEN 0 AND 2");
+ } else if (SQLTestsConstants.db == DB.ORACLE) {
+ EasyMock.expect(delegate.getQueryString(0, 2))
+ .andReturn(
+ "SELECT * FROM (SELECT x.*, ROWNUM AS r FROM"
+ + " (SELECT * FROM people) x) WHERE r BETWEEN 1 AND 2");
+ } else {
+ EasyMock.expect(delegate.getQueryString(0, 2)).andReturn(
+ "SELECT * FROM people LIMIT 2 OFFSET 0");
+ }
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+
+ query.beginTransaction();
+ ResultSet rs = query.getResults(0, 2);
+ int rsoffset = 0;
+ if (SQLTestsConstants.db == DB.MSSQL) {
+ rsoffset++;
+ }
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(0 + offset, rs.getInt(1 + rsoffset));
+ Assert.assertEquals("Ville", rs.getString(2 + rsoffset));
+
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(1 + offset, rs.getInt(1 + rsoffset));
+ Assert.assertEquals("Kalle", rs.getString(2 + rsoffset));
+
+ Assert.assertFalse(rs.next());
+
+ EasyMock.verify(delegate);
+ query.commit();
+ }
+
+ @Test
+ public void getResults_delegateRegistered5000Rows_returns100rows()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ if (SQLTestsConstants.db == DB.MSSQL) {
+ EasyMock.expect(delegate.getQueryString(200, 100))
+ .andReturn(
+ "SELECT * FROM (SELECT row_number()"
+ + "OVER (ORDER BY id ASC) AS rownum, * FROM people)"
+ + " AS a WHERE a.rownum BETWEEN 201 AND 300");
+ } else if (SQLTestsConstants.db == DB.ORACLE) {
+ EasyMock.expect(delegate.getQueryString(200, 100))
+ .andReturn(
+ "SELECT * FROM (SELECT x.*, ROWNUM AS r FROM"
+ + " (SELECT * FROM people ORDER BY ID ASC) x) WHERE r BETWEEN 201 AND 300");
+ } else {
+ EasyMock.expect(delegate.getQueryString(200, 100)).andReturn(
+ "SELECT * FROM people LIMIT 100 OFFSET 200");
+ }
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+
+ query.beginTransaction();
+ ResultSet rs = query.getResults(200, 100);
+ for (int i = 0; i < 100; i++) {
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(200 + i + offset, rs.getInt("ID"));
+ }
+ Assert.assertFalse(rs.next());
+ query.commit();
+ }
+
+ @Test
+ public void setFilters_delegateImplementsSetFilters_shouldPassFiltersToDelegate() {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ List<Filter> filters = new ArrayList<Filter>();
+ filters.add(new Like("name", "%lle"));
+ delegate.setFilters(filters);
+
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+
+ query.setFilters(filters);
+
+ EasyMock.verify(delegate);
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void setFilters_delegateDoesNotImplementSetFilters_shouldFail() {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ List<Filter> filters = new ArrayList<Filter>();
+ filters.add(new Like("name", "%lle"));
+ delegate.setFilters(filters);
+ EasyMock.expectLastCall().andThrow(new UnsupportedOperationException());
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+
+ query.setFilters(filters);
+
+ EasyMock.verify(delegate);
+ }
+
+ @Test
+ public void setOrderBy_delegateImplementsSetOrderBy_shouldPassArgumentsToDelegate() {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ List<OrderBy> orderBys = Arrays.asList(new OrderBy("name", false));
+ delegate.setOrderBy(orderBys);
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+
+ query.setOrderBy(orderBys);
+
+ EasyMock.verify(delegate);
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void setOrderBy_delegateDoesNotImplementSetOrderBy_shouldFail() {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ List<OrderBy> orderBys = Arrays.asList(new OrderBy("name", false));
+ delegate.setOrderBy(orderBys);
+ EasyMock.expectLastCall().andThrow(new UnsupportedOperationException());
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+
+ query.setOrderBy(orderBys);
+
+ EasyMock.verify(delegate);
+ }
+
+ @Test
+ public void setFilters_noDelegateAndNullParameter_shouldSucceed() {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ query.setFilters(null);
+ }
+
+ @Test
+ public void setOrderBy_noDelegateAndNullParameter_shouldSucceed() {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ query.setOrderBy(null);
+ }
+
+ @Test
+ public void storeRow_delegateImplementsStoreRow_shouldPassToDelegate()
+ throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ EasyMock.expect(
+ delegate.storeRow(EasyMock.isA(Connection.class),
+ EasyMock.isA(RowItem.class))).andReturn(1);
+ SQLContainer container = EasyMock.createNiceMock(SQLContainer.class);
+ EasyMock.replay(delegate, container);
+ query.setDelegate(delegate);
+
+ query.beginTransaction();
+ RowItem row = new RowItem(container, new RowId(new Object[] { 1 }),
+ null);
+ query.storeRow(row);
+ query.commit();
+
+ EasyMock.verify(delegate, container);
+ }
+
+ @Test
+ public void storeRow_delegateDoesNotImplementStoreRow_shouldFail()
+ throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ EasyMock.expect(
+ delegate.storeRow(EasyMock.isA(Connection.class),
+ EasyMock.isA(RowItem.class))).andThrow(
+ new UnsupportedOperationException());
+ SQLContainer container = EasyMock.createNiceMock(SQLContainer.class);
+ EasyMock.replay(delegate, container);
+ query.setDelegate(delegate);
+
+ query.beginTransaction();
+ RowItem row = new RowItem(container, new RowId(new Object[] { 1 }),
+ null);
+ try {
+ query.storeRow(row);
+ Assert.fail("storeRow should fail when delgate does not implement storeRow");
+ } catch (UnsupportedOperationException e) {
+ // Cleanup to make test connection pool happy
+ query.rollback();
+ }
+ }
+
+ @Test
+ public void removeRow_delegateImplementsRemoveRow_shouldPassToDelegate()
+ throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ EasyMock.expect(
+ delegate.removeRow(EasyMock.isA(Connection.class),
+ EasyMock.isA(RowItem.class))).andReturn(true);
+ SQLContainer container = EasyMock.createNiceMock(SQLContainer.class);
+ EasyMock.replay(delegate, container);
+ query.setDelegate(delegate);
+
+ query.beginTransaction();
+ RowItem row = new RowItem(container, new RowId(new Object[] { 1 }),
+ null);
+ query.removeRow(row);
+ query.commit();
+
+ EasyMock.verify(delegate, container);
+ }
+
+ @Test
+ public void removeRow_delegateDoesNotImplementRemoveRow_shouldFail()
+ throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ EasyMock.expect(
+ delegate.removeRow(EasyMock.isA(Connection.class),
+ EasyMock.isA(RowItem.class))).andThrow(
+ new UnsupportedOperationException());
+ SQLContainer container = EasyMock.createNiceMock(SQLContainer.class);
+ EasyMock.replay(delegate, container);
+ query.setDelegate(delegate);
+
+ query.beginTransaction();
+ RowItem row = new RowItem(container, new RowId(new Object[] { 1 }),
+ null);
+ try {
+ query.removeRow(row);
+ Assert.fail("removeRow should fail when delegate does not implement removeRow");
+ } catch (UnsupportedOperationException e) {
+ // Cleanup to make test connection pool happy
+ query.rollback();
+ }
+ }
+
+ @Test
+ public void beginTransaction_delegateRegistered_shouldSucceed()
+ throws UnsupportedOperationException, SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+
+ query.beginTransaction();
+ // Cleanup to make test connection pool happy
+ query.rollback();
+ }
+
+ @Test
+ public void beginTransaction_transactionAlreadyActive_shouldFail()
+ throws SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+
+ query.beginTransaction();
+ try {
+ query.beginTransaction();
+ Assert.fail("Should throw exception when starting a transaction while already in a transaction");
+ } catch (IllegalStateException e) {
+ // Cleanup to make test connection pool happy
+ query.rollback();
+ }
+ }
+
+ @Test(expected = SQLException.class)
+ public void commit_delegateRegisteredNoActiveTransaction_shouldFail()
+ throws UnsupportedOperationException, SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+
+ query.commit();
+ }
+
+ @Test
+ public void commit_delegateRegisteredActiveTransaction_shouldSucceed()
+ throws UnsupportedOperationException, SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+
+ query.beginTransaction();
+ query.commit();
+ }
+
+ @Test(expected = SQLException.class)
+ public void commit_delegateRegisteredActiveTransactionDoubleCommit_shouldFail()
+ throws UnsupportedOperationException, SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+
+ query.beginTransaction();
+ query.commit();
+ query.commit();
+ }
+
+ @Test(expected = SQLException.class)
+ public void rollback_delegateRegisteredNoActiveTransaction_shouldFail()
+ throws UnsupportedOperationException, SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+
+ query.rollback();
+ }
+
+ @Test
+ public void rollback_delegateRegisteredActiveTransaction_shouldSucceed()
+ throws UnsupportedOperationException, SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+
+ query.beginTransaction();
+ query.rollback();
+ }
+
+ @Test(expected = SQLException.class)
+ public void rollback_delegateRegisteredActiveTransactionDoubleRollback_shouldFail()
+ throws UnsupportedOperationException, SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+
+ query.beginTransaction();
+ query.rollback();
+ query.rollback();
+ }
+
+ @Test(expected = SQLException.class)
+ public void rollback_delegateRegisteredCommittedTransaction_shouldFail()
+ throws UnsupportedOperationException, SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+
+ query.beginTransaction();
+ query.commit();
+ query.rollback();
+ }
+
+ @Test(expected = SQLException.class)
+ public void commit_delegateRegisteredRollbackedTransaction_shouldFail()
+ throws UnsupportedOperationException, SQLException {
+ FreeformQuery query = new FreeformQuery("SELECT * FROM people",
+ Arrays.asList("ID"), connectionPool);
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+
+ query.beginTransaction();
+ query.rollback();
+ query.commit();
+ }
+
+ @Test(expected = SQLException.class)
+ public void containsRowWithKeys_delegateRegistered_shouldCallGetContainsRowQueryString()
+ throws SQLException {
+ FreeformQuery query = new FreeformQuery(
+ "SELECT * FROM people WHERE name LIKE '%lle'",
+ Arrays.asList("ID"), connectionPool);
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ EasyMock.expect(delegate.getContainsRowQueryString(1)).andReturn("");
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+
+ query.containsRowWithKey(1);
+
+ EasyMock.verify(delegate);
+ }
+
+ @Test
+ public void containsRowWithKeys_delegateRegistered_shouldUseResultFromGetContainsRowQueryString()
+ throws SQLException {
+ FreeformQuery query = new FreeformQuery(
+ "SELECT * FROM people WHERE \"NAME\" LIKE '%lle'",
+ Arrays.asList("ID"), connectionPool);
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ // In order to test that this is the query that is actually used, we use
+ // a non-existing id in place of the existing one.
+ EasyMock.expect(delegate.getContainsRowQueryString(1))
+ .andReturn(
+ "SELECT * FROM people WHERE \"NAME\" LIKE '%lle' AND \"ID\" = 1337");
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+
+ // The id (key) used should be 1337 as above, for the call with key = 1
+ Assert.assertFalse(query.containsRowWithKey(1));
+
+ EasyMock.verify(delegate);
+ }
+
+ public static class NonMatchingDelegateWithGroupBy implements
+ FreeformQueryDelegate {
+
+ private String fromWhere = "FROM people p1 LEFT JOIN people p2 ON p2.id = p1.id WHERE p1.\"NAME\" LIKE 'notfound' GROUP BY p1.ID";
+
+ @Override
+ public int storeRow(Connection conn, RowItem row)
+ throws UnsupportedOperationException, SQLException {
+ // Not used in this test
+ return 0;
+ }
+
+ @Override
+ public void setOrderBy(List<OrderBy> orderBys)
+ throws UnsupportedOperationException {
+ // Not used in this test
+ }
+
+ @Override
+ public void setFilters(List<Filter> filters)
+ throws UnsupportedOperationException {
+ // Not used in this test
+ }
+
+ @Override
+ public boolean removeRow(Connection conn, RowItem row)
+ throws UnsupportedOperationException, SQLException {
+ // Not used in this test
+ return false;
+ }
+
+ @Override
+ public String getQueryString(int offset, int limit)
+ throws UnsupportedOperationException {
+ return "SELECT * " + fromWhere;
+ }
+
+ @Override
+ public String getCountQuery() throws UnsupportedOperationException {
+ return "SELECT COUNT(*) " + fromWhere;
+ }
+
+ @Override
+ public String getContainsRowQueryString(Object... keys)
+ throws UnsupportedOperationException {
+ // Not used in this test
+ return null;
+ }
+ }
+
+ public static class NonMatchingStatementDelegateWithGroupBy extends
+ NonMatchingDelegateWithGroupBy implements FreeformStatementDelegate {
+
+ @Override
+ public StatementHelper getQueryStatement(int offset, int limit)
+ throws UnsupportedOperationException {
+ StatementHelper sh = new StatementHelper();
+ sh.setQueryString(getQueryString(offset, limit));
+ return sh;
+ }
+
+ @Override
+ public StatementHelper getCountStatement()
+ throws UnsupportedOperationException {
+ StatementHelper sh = new StatementHelper();
+ sh.setQueryString(getCountQuery());
+ return sh;
+ }
+
+ @Override
+ public StatementHelper getContainsRowQueryStatement(Object... keys)
+ throws UnsupportedOperationException {
+ // Not used in this test
+ return null;
+ }
+ }
+
+ @Test
+ public void containsRowWithKeys_delegateRegisteredGetContainsRowQueryStringNotImplemented_shouldBuildQueryString()
+ throws SQLException {
+ FreeformQuery query = new FreeformQuery(
+ "SELECT * FROM people WHERE \"NAME\" LIKE '%lle'",
+ Arrays.asList("ID"), connectionPool);
+ FreeformQueryDelegate delegate = EasyMock
+ .createMock(FreeformQueryDelegate.class);
+ EasyMock.expect(delegate.getContainsRowQueryString(1)).andThrow(
+ new UnsupportedOperationException());
+ EasyMock.replay(delegate);
+ query.setDelegate(delegate);
+
+ Assert.assertTrue(query.containsRowWithKey(1));
+
+ EasyMock.verify(delegate);
+ }
+
+ @Test
+ public void delegateStatementCountWithGroupBy() throws SQLException {
+ String dummyNotUsed = "foo";
+ FreeformQuery query = new FreeformQuery(dummyNotUsed, connectionPool,
+ "p1.ID");
+ query.setDelegate(new NonMatchingStatementDelegateWithGroupBy());
+
+ Assert.assertEquals(0, query.getCount());
+ }
+
+ @Test
+ public void delegateCountWithGroupBy() throws SQLException {
+ String dummyNotUsed = "foo";
+ FreeformQuery query = new FreeformQuery(dummyNotUsed, connectionPool,
+ "p1.ID");
+ query.setDelegate(new NonMatchingDelegateWithGroupBy());
+
+ Assert.assertEquals(0, query.getCount());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/query/QueryBuilderTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/query/QueryBuilderTest.java
new file mode 100644
index 0000000000..596f28cf5e
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/sqlcontainer/query/QueryBuilderTest.java
@@ -0,0 +1,310 @@
+package com.vaadin.data.util.sqlcontainer.query;
+
+import java.util.ArrayList;
+
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.Container.Filter;
+import com.vaadin.data.util.filter.And;
+import com.vaadin.data.util.filter.Between;
+import com.vaadin.data.util.filter.Compare.Equal;
+import com.vaadin.data.util.filter.Compare.Greater;
+import com.vaadin.data.util.filter.Compare.GreaterOrEqual;
+import com.vaadin.data.util.filter.Compare.Less;
+import com.vaadin.data.util.filter.Compare.LessOrEqual;
+import com.vaadin.data.util.filter.IsNull;
+import com.vaadin.data.util.filter.Like;
+import com.vaadin.data.util.filter.Not;
+import com.vaadin.data.util.filter.Or;
+import com.vaadin.data.util.filter.SimpleStringFilter;
+import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
+import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder;
+import com.vaadin.data.util.sqlcontainer.query.generator.filter.StringDecorator;
+
+public class QueryBuilderTest {
+
+ private StatementHelper mockedStatementHelper(Object... values) {
+ StatementHelper sh = EasyMock.createMock(StatementHelper.class);
+ for (Object val : values) {
+ sh.addParameterValue(val);
+ EasyMock.expectLastCall();
+ }
+ EasyMock.replay(sh);
+ return sh;
+ }
+
+ // escape bad characters and wildcards
+
+ @Test
+ public void getWhereStringForFilter_equals() {
+ StatementHelper sh = mockedStatementHelper("Fido");
+ Equal f = new Equal("NAME", "Fido");
+ Assert.assertEquals("\"NAME\" = ?",
+ QueryBuilder.getWhereStringForFilter(f, sh));
+ EasyMock.verify(sh);
+ }
+
+ @Test
+ public void getWhereStringForFilter_greater() {
+ StatementHelper sh = mockedStatementHelper(18);
+ Greater f = new Greater("AGE", 18);
+ Assert.assertEquals("\"AGE\" > ?",
+ QueryBuilder.getWhereStringForFilter(f, sh));
+ EasyMock.verify(sh);
+ }
+
+ @Test
+ public void getWhereStringForFilter_less() {
+ StatementHelper sh = mockedStatementHelper(65);
+ Less f = new Less("AGE", 65);
+ Assert.assertEquals("\"AGE\" < ?",
+ QueryBuilder.getWhereStringForFilter(f, sh));
+ EasyMock.verify(sh);
+ }
+
+ @Test
+ public void getWhereStringForFilter_greaterOrEqual() {
+ StatementHelper sh = mockedStatementHelper(18);
+ GreaterOrEqual f = new GreaterOrEqual("AGE", 18);
+ Assert.assertEquals("\"AGE\" >= ?",
+ QueryBuilder.getWhereStringForFilter(f, sh));
+ EasyMock.verify(sh);
+ }
+
+ @Test
+ public void getWhereStringForFilter_lessOrEqual() {
+ StatementHelper sh = mockedStatementHelper(65);
+ LessOrEqual f = new LessOrEqual("AGE", 65);
+ Assert.assertEquals("\"AGE\" <= ?",
+ QueryBuilder.getWhereStringForFilter(f, sh));
+ EasyMock.verify(sh);
+ }
+
+ @Test
+ public void getWhereStringForFilter_simpleStringFilter() {
+ StatementHelper sh = mockedStatementHelper("Vi%");
+ SimpleStringFilter f = new SimpleStringFilter("NAME", "Vi", false, true);
+ Assert.assertEquals("\"NAME\" LIKE ?",
+ QueryBuilder.getWhereStringForFilter(f, sh));
+ EasyMock.verify(sh);
+ }
+
+ @Test
+ public void getWhereStringForFilter_simpleStringFilterMatchAnywhere() {
+ StatementHelper sh = mockedStatementHelper("%Vi%");
+ SimpleStringFilter f = new SimpleStringFilter("NAME", "Vi", false,
+ false);
+ Assert.assertEquals("\"NAME\" LIKE ?",
+ QueryBuilder.getWhereStringForFilter(f, sh));
+ EasyMock.verify(sh);
+ }
+
+ @Test
+ public void getWhereStringForFilter_simpleStringFilterMatchAnywhereIgnoreCase() {
+ StatementHelper sh = mockedStatementHelper("%VI%");
+ SimpleStringFilter f = new SimpleStringFilter("NAME", "Vi", true, false);
+ Assert.assertEquals("UPPER(\"NAME\") LIKE ?",
+ QueryBuilder.getWhereStringForFilter(f, sh));
+ EasyMock.verify(sh);
+ }
+
+ @Test
+ public void getWhereStringForFilter_startsWith() {
+ StatementHelper sh = mockedStatementHelper("Vi%");
+ Like f = new Like("NAME", "Vi%");
+ Assert.assertEquals("\"NAME\" LIKE ?",
+ QueryBuilder.getWhereStringForFilter(f, sh));
+ EasyMock.verify(sh);
+ }
+
+ @Test
+ public void getWhereStringForFilter_startsWithNumber() {
+ StatementHelper sh = mockedStatementHelper("1%");
+ Like f = new Like("AGE", "1%");
+ Assert.assertEquals("\"AGE\" LIKE ?",
+ QueryBuilder.getWhereStringForFilter(f, sh));
+ EasyMock.verify(sh);
+ }
+
+ @Test
+ public void getWhereStringForFilter_endsWith() {
+ StatementHelper sh = mockedStatementHelper("%lle");
+ Like f = new Like("NAME", "%lle");
+ Assert.assertEquals("\"NAME\" LIKE ?",
+ QueryBuilder.getWhereStringForFilter(f, sh));
+ EasyMock.verify(sh);
+ }
+
+ @Test
+ public void getWhereStringForFilter_contains() {
+ StatementHelper sh = mockedStatementHelper("%ill%");
+ Like f = new Like("NAME", "%ill%");
+ Assert.assertEquals("\"NAME\" LIKE ?",
+ QueryBuilder.getWhereStringForFilter(f, sh));
+ EasyMock.verify(sh);
+ }
+
+ @Test
+ public void getWhereStringForFilter_between() {
+ StatementHelper sh = mockedStatementHelper(18, 65);
+ Between f = new Between("AGE", 18, 65);
+ Assert.assertEquals("\"AGE\" BETWEEN ? AND ?",
+ QueryBuilder.getWhereStringForFilter(f, sh));
+ EasyMock.verify(sh);
+ }
+
+ @Test
+ public void getWhereStringForFilter_caseInsensitive_equals() {
+ StatementHelper sh = mockedStatementHelper("FIDO");
+ Like f = new Like("NAME", "Fido");
+ f.setCaseSensitive(false);
+ Assert.assertEquals("UPPER(\"NAME\") LIKE ?",
+ QueryBuilder.getWhereStringForFilter(f, sh));
+ EasyMock.verify(sh);
+ }
+
+ @Test
+ public void getWhereStringForFilter_caseInsensitive_startsWith() {
+ StatementHelper sh = mockedStatementHelper("VI%");
+ Like f = new Like("NAME", "Vi%");
+ f.setCaseSensitive(false);
+ Assert.assertEquals("UPPER(\"NAME\") LIKE ?",
+ QueryBuilder.getWhereStringForFilter(f, sh));
+ EasyMock.verify(sh);
+ }
+
+ @Test
+ public void getWhereStringForFilter_caseInsensitive_endsWith() {
+ StatementHelper sh = mockedStatementHelper("%LLE");
+ Like f = new Like("NAME", "%lle");
+ f.setCaseSensitive(false);
+ Assert.assertEquals("UPPER(\"NAME\") LIKE ?",
+ QueryBuilder.getWhereStringForFilter(f, sh));
+ EasyMock.verify(sh);
+ }
+
+ @Test
+ public void getWhereStringForFilter_caseInsensitive_contains() {
+ StatementHelper sh = mockedStatementHelper("%ILL%");
+ Like f = new Like("NAME", "%ill%");
+ f.setCaseSensitive(false);
+ Assert.assertEquals("UPPER(\"NAME\") LIKE ?",
+ QueryBuilder.getWhereStringForFilter(f, sh));
+ EasyMock.verify(sh);
+ }
+
+ @Test
+ public void getWhereStringForFilters_listOfFilters() {
+ StatementHelper sh = mockedStatementHelper("%lle", 18);
+ ArrayList<Filter> filters = new ArrayList<Filter>();
+ filters.add(new Like("NAME", "%lle"));
+ filters.add(new Greater("AGE", 18));
+ Assert.assertEquals(" WHERE \"NAME\" LIKE ? AND \"AGE\" > ?",
+ QueryBuilder.getWhereStringForFilters(filters, sh));
+ EasyMock.verify(sh);
+ }
+
+ @Test
+ public void getWhereStringForFilters_oneAndFilter() {
+ StatementHelper sh = mockedStatementHelper("%lle", 18);
+ ArrayList<Filter> filters = new ArrayList<Filter>();
+ filters.add(new And(new Like("NAME", "%lle"), new Greater("AGE", 18)));
+ Assert.assertEquals(" WHERE (\"NAME\" LIKE ? AND \"AGE\" > ?)",
+ QueryBuilder.getWhereStringForFilters(filters, sh));
+ EasyMock.verify(sh);
+ }
+
+ @Test
+ public void getWhereStringForFilters_oneOrFilter() {
+ StatementHelper sh = mockedStatementHelper("%lle", 18);
+ ArrayList<Filter> filters = new ArrayList<Filter>();
+ filters.add(new Or(new Like("NAME", "%lle"), new Greater("AGE", 18)));
+ Assert.assertEquals(" WHERE (\"NAME\" LIKE ? OR \"AGE\" > ?)",
+ QueryBuilder.getWhereStringForFilters(filters, sh));
+ EasyMock.verify(sh);
+ }
+
+ @Test
+ public void getWhereStringForFilters_complexCompoundFilters() {
+ StatementHelper sh = mockedStatementHelper("%lle", 18, 65, "Pelle");
+ ArrayList<Filter> filters = new ArrayList<Filter>();
+ filters.add(new Or(new And(new Like("NAME", "%lle"), new Or(new Less(
+ "AGE", 18), new Greater("AGE", 65))),
+ new Equal("NAME", "Pelle")));
+ Assert.assertEquals(
+ " WHERE ((\"NAME\" LIKE ? AND (\"AGE\" < ? OR \"AGE\" > ?)) OR \"NAME\" = ?)",
+ QueryBuilder.getWhereStringForFilters(filters, sh));
+ EasyMock.verify(sh);
+ }
+
+ @Test
+ public void getWhereStringForFilters_complexCompoundFiltersAndSingleFilter() {
+ StatementHelper sh = mockedStatementHelper("%lle", 18, 65, "Pelle",
+ "Virtanen");
+ ArrayList<Filter> filters = new ArrayList<Filter>();
+ filters.add(new Or(new And(new Like("NAME", "%lle"), new Or(new Less(
+ "AGE", 18), new Greater("AGE", 65))),
+ new Equal("NAME", "Pelle")));
+ filters.add(new Equal("LASTNAME", "Virtanen"));
+ Assert.assertEquals(
+ " WHERE ((\"NAME\" LIKE ? AND (\"AGE\" < ? OR \"AGE\" > ?)) OR \"NAME\" = ?) AND \"LASTNAME\" = ?",
+ QueryBuilder.getWhereStringForFilters(filters, sh));
+ EasyMock.verify(sh);
+ }
+
+ @Test
+ public void getWhereStringForFilters_emptyList_shouldReturnEmptyString() {
+ ArrayList<Filter> filters = new ArrayList<Filter>();
+ Assert.assertEquals("", QueryBuilder.getWhereStringForFilters(filters,
+ new StatementHelper()));
+ }
+
+ @Test
+ public void getWhereStringForFilters_NotFilter() {
+ StatementHelper sh = mockedStatementHelper(18);
+ ArrayList<Filter> filters = new ArrayList<Filter>();
+ filters.add(new Not(new Equal("AGE", 18)));
+ Assert.assertEquals(" WHERE NOT \"AGE\" = ?",
+ QueryBuilder.getWhereStringForFilters(filters, sh));
+ EasyMock.verify(sh);
+ }
+
+ @Test
+ public void getWhereStringForFilters_complexNegatedFilter() {
+ StatementHelper sh = mockedStatementHelper(65, 18);
+ ArrayList<Filter> filters = new ArrayList<Filter>();
+ filters.add(new Not(new Or(new Equal("AGE", 65), new Equal("AGE", 18))));
+ Assert.assertEquals(" WHERE NOT (\"AGE\" = ? OR \"AGE\" = ?)",
+ QueryBuilder.getWhereStringForFilters(filters, sh));
+ EasyMock.verify(sh);
+ }
+
+ @Test
+ public void getWhereStringForFilters_isNull() {
+ ArrayList<Filter> filters = new ArrayList<Filter>();
+ filters.add(new IsNull("NAME"));
+ Assert.assertEquals(" WHERE \"NAME\" IS NULL", QueryBuilder
+ .getWhereStringForFilters(filters, new StatementHelper()));
+ }
+
+ @Test
+ public void getWhereStringForFilters_isNotNull() {
+ ArrayList<Filter> filters = new ArrayList<Filter>();
+ filters.add(new Not(new IsNull("NAME")));
+ Assert.assertEquals(" WHERE \"NAME\" IS NOT NULL", QueryBuilder
+ .getWhereStringForFilters(filters, new StatementHelper()));
+ }
+
+ @Test
+ public void getWhereStringForFilters_customStringDecorator() {
+ QueryBuilder.setStringDecorator(new StringDecorator("[", "]"));
+ ArrayList<Filter> filters = new ArrayList<Filter>();
+ filters.add(new Not(new IsNull("NAME")));
+ Assert.assertEquals(" WHERE [NAME] IS NOT NULL", QueryBuilder
+ .getWhereStringForFilters(filters, new StatementHelper()));
+ // Reset the default string decorator
+ QueryBuilder.setStringDecorator(new StringDecorator("\"", "\""));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/query/TableQueryTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/query/TableQueryTest.java
new file mode 100644
index 0000000000..1cb3d722c6
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/sqlcontainer/query/TableQueryTest.java
@@ -0,0 +1,743 @@
+package com.vaadin.data.util.sqlcontainer.query;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.Container.Filter;
+import com.vaadin.data.util.filter.Compare.Equal;
+import com.vaadin.data.util.filter.Like;
+import com.vaadin.data.util.sqlcontainer.DataGenerator;
+import com.vaadin.data.util.sqlcontainer.OptimisticLockException;
+import com.vaadin.data.util.sqlcontainer.RowItem;
+import com.vaadin.data.util.sqlcontainer.SQLContainer;
+import com.vaadin.data.util.sqlcontainer.SQLTestsConstants;
+import com.vaadin.data.util.sqlcontainer.SQLTestsConstants.DB;
+import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool;
+import com.vaadin.data.util.sqlcontainer.query.generator.DefaultSQLGenerator;
+
+public class TableQueryTest {
+ private static final int offset = SQLTestsConstants.offset;
+ private JDBCConnectionPool connectionPool;
+
+ @Before
+ public void setUp() throws SQLException {
+ try {
+ connectionPool = new ValidatingSimpleJDBCConnectionPool(
+ SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL,
+ SQLTestsConstants.dbUser, SQLTestsConstants.dbPwd, 2, 2);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ Assert.fail(e.getMessage());
+ }
+ DataGenerator.addPeopleToDatabase(connectionPool);
+ }
+
+ @After
+ public void tearDown() {
+ if (connectionPool != null) {
+ connectionPool.destroy();
+ }
+ }
+
+ /**********************************************************************
+ * TableQuery construction tests
+ **********************************************************************/
+ @Test
+ public void construction_legalParameters_shouldSucceed() {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ new DefaultSQLGenerator());
+ Assert.assertArrayEquals(new Object[] { "ID" }, tQuery
+ .getPrimaryKeyColumns().toArray());
+ boolean correctTableName = "people".equalsIgnoreCase(tQuery
+ .getTableName());
+ Assert.assertTrue(correctTableName);
+ }
+
+ @Test
+ public void construction_legalParameters_defaultGenerator_shouldSucceed() {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+ Assert.assertArrayEquals(new Object[] { "ID" }, tQuery
+ .getPrimaryKeyColumns().toArray());
+ boolean correctTableName = "people".equalsIgnoreCase(tQuery
+ .getTableName());
+ Assert.assertTrue(correctTableName);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void construction_nonExistingTableName_shouldFail() {
+ new TableQuery("skgwaguhsd", connectionPool, new DefaultSQLGenerator());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void construction_emptyTableName_shouldFail() {
+ new TableQuery("", connectionPool, new DefaultSQLGenerator());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void construction_nullSqlGenerator_shouldFail() {
+ new TableQuery("people", connectionPool, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void construction_nullConnectionPool_shouldFail() {
+ new TableQuery("people", null, new DefaultSQLGenerator());
+ }
+
+ /**********************************************************************
+ * TableQuery row count tests
+ **********************************************************************/
+ @Test
+ public void getCount_simpleQuery_returnsFour() throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+ Assert.assertEquals(4, tQuery.getCount());
+ }
+
+ @Test
+ public void getCount_simpleQueryTwoMorePeopleAdded_returnsSix()
+ throws SQLException {
+ // Add some people
+ Connection conn = connectionPool.reserveConnection();
+ Statement statement = conn.createStatement();
+ if (SQLTestsConstants.db == DB.MSSQL) {
+ statement.executeUpdate("insert into people values('Bengt', 30)");
+ statement.executeUpdate("insert into people values('Ingvar', 50)");
+ } else {
+ statement
+ .executeUpdate("insert into people values(default, 'Bengt', 30)");
+ statement
+ .executeUpdate("insert into people values(default, 'Ingvar', 50)");
+ }
+ statement.close();
+ conn.commit();
+ connectionPool.releaseConnection(conn);
+
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+
+ Assert.assertEquals(6, tQuery.getCount());
+ }
+
+ @Test
+ public void getCount_normalState_releasesConnection() throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+ tQuery.getCount();
+ tQuery.getCount();
+ Connection c = connectionPool.reserveConnection();
+ Assert.assertNotNull(c);
+ connectionPool.releaseConnection(c);
+ }
+
+ /**********************************************************************
+ * TableQuery get results tests
+ **********************************************************************/
+ @Test
+ public void getResults_simpleQuery_returnsFourRecords() throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+ tQuery.beginTransaction();
+ ResultSet rs = tQuery.getResults(0, 0);
+
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(0 + offset, rs.getInt(1));
+ Assert.assertEquals("Ville", rs.getString(2));
+
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(1 + offset, rs.getInt(1));
+ Assert.assertEquals("Kalle", rs.getString(2));
+
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(2 + offset, rs.getInt(1));
+ Assert.assertEquals("Pelle", rs.getString(2));
+
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(3 + offset, rs.getInt(1));
+ Assert.assertEquals("Börje", rs.getString(2));
+
+ Assert.assertFalse(rs.next());
+ tQuery.commit();
+ }
+
+ @Test
+ public void getResults_noDelegate5000Rows_returns5000rows()
+ throws SQLException {
+ DataGenerator.addFiveThousandPeople(connectionPool);
+
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+
+ tQuery.beginTransaction();
+ ResultSet rs = tQuery.getResults(0, 0);
+ for (int i = 0; i < 5000; i++) {
+ Assert.assertTrue(rs.next());
+ }
+ Assert.assertFalse(rs.next());
+ tQuery.commit();
+ }
+
+ /**********************************************************************
+ * TableQuery transaction management tests
+ **********************************************************************/
+ @Test
+ public void beginTransaction_transactionAlreadyActive_shouldFail()
+ throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+
+ tQuery.beginTransaction();
+ try {
+ tQuery.beginTransaction();
+ Assert.fail("Should throw exception when starting a transaction while already in a transaction");
+ } catch (IllegalStateException e) {
+ // Cleanup to make test connection pool happy
+ tQuery.rollback();
+ }
+ }
+
+ @Test
+ public void commit_readOnly_shouldSucceed() throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+ tQuery.beginTransaction();
+ tQuery.commit();
+ }
+
+ @Test
+ public void rollback_readOnly_shouldSucceed() throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+ tQuery.beginTransaction();
+ tQuery.rollback();
+ }
+
+ @Test(expected = SQLException.class)
+ public void commit_noActiveTransaction_shouldFail() throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+ tQuery.commit();
+ }
+
+ @Test(expected = SQLException.class)
+ public void rollback_noActiveTransaction_shouldFail() throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+ tQuery.rollback();
+ }
+
+ /**********************************************************************
+ * TableQuery row query with given keys tests
+ **********************************************************************/
+ @Test
+ public void containsRowWithKeys_existingKeys_returnsTrue()
+ throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+ Assert.assertTrue(tQuery.containsRowWithKey(1));
+ }
+
+ @Test
+ public void containsRowWithKeys_nonexistingKeys_returnsTrue()
+ throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+
+ Assert.assertFalse(tQuery.containsRowWithKey(1337));
+ }
+
+ @Test
+ public void containsRowWithKeys_invalidKeys_shouldFail()
+ throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+ boolean b = true;
+ try {
+ b = tQuery.containsRowWithKey("foo");
+ } catch (SQLException se) {
+ return;
+ }
+ Assert.assertFalse(b);
+ }
+
+ @Test
+ public void containsRowWithKeys_nullKeys_shouldFailAndReleaseConnections()
+ throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+ try {
+ tQuery.containsRowWithKey(new Object[] { null });
+ org.junit.Assert
+ .fail("null should throw an IllegalArgumentException from StatementHelper");
+ } catch (IllegalArgumentException e) {
+ // We should now be able to reserve two connections
+ Connection c1 = connectionPool.reserveConnection();
+ Connection c2 = connectionPool.reserveConnection();
+
+ // Cleanup to make test connection pool happy
+ connectionPool.releaseConnection(c1);
+ connectionPool.releaseConnection(c2);
+
+ }
+ }
+
+ /**********************************************************************
+ * TableQuery filtering and ordering tests
+ **********************************************************************/
+ @Test
+ public void setFilters_shouldReturnCorrectCount() throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+ List<Filter> filters = new ArrayList<Filter>();
+ filters.add(new Like("NAME", "%lle"));
+ tQuery.setFilters(filters);
+ Assert.assertEquals(3, tQuery.getCount());
+ }
+
+ @Test
+ public void setOrderByNameAscending_shouldReturnCorrectOrder()
+ throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+
+ List<OrderBy> orderBys = Arrays.asList(new OrderBy("NAME", true));
+ tQuery.setOrderBy(orderBys);
+
+ tQuery.beginTransaction();
+ ResultSet rs;
+ rs = tQuery.getResults(0, 0);
+
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(3 + offset, rs.getInt(1));
+ Assert.assertEquals("Börje", rs.getString(2));
+
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(1 + offset, rs.getInt(1));
+ Assert.assertEquals("Kalle", rs.getString(2));
+
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(2 + offset, rs.getInt(1));
+ Assert.assertEquals("Pelle", rs.getString(2));
+
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(0 + offset, rs.getInt(1));
+ Assert.assertEquals("Ville", rs.getString(2));
+
+ Assert.assertFalse(rs.next());
+ tQuery.commit();
+ }
+
+ @Test
+ public void setOrderByNameDescending_shouldReturnCorrectOrder()
+ throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+
+ List<OrderBy> orderBys = Arrays.asList(new OrderBy("NAME", false));
+ tQuery.setOrderBy(orderBys);
+
+ tQuery.beginTransaction();
+ ResultSet rs;
+ rs = tQuery.getResults(0, 0);
+
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(0 + offset, rs.getInt(1));
+ Assert.assertEquals("Ville", rs.getString(2));
+
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(2 + offset, rs.getInt(1));
+ Assert.assertEquals("Pelle", rs.getString(2));
+
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(1 + offset, rs.getInt(1));
+ Assert.assertEquals("Kalle", rs.getString(2));
+
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(3 + offset, rs.getInt(1));
+ Assert.assertEquals("Börje", rs.getString(2));
+
+ Assert.assertFalse(rs.next());
+ tQuery.commit();
+ }
+
+ @Test
+ public void setFilters_nullParameter_shouldSucceed() {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+ tQuery.setFilters(null);
+ }
+
+ @Test
+ public void setOrderBy_nullParameter_shouldSucceed() {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+ tQuery.setOrderBy(null);
+ }
+
+ /**********************************************************************
+ * TableQuery row removal tests
+ **********************************************************************/
+ @Test
+ public void removeRowThroughContainer_legalRowItem_shouldSucceed()
+ throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+ SQLContainer container = new SQLContainer(tQuery);
+ container.setAutoCommit(false);
+ Assert.assertTrue(container.removeItem(container.getItemIds()
+ .iterator().next()));
+
+ Assert.assertEquals(4, tQuery.getCount());
+ Assert.assertEquals(3, container.size());
+ container.commit();
+
+ Assert.assertEquals(3, tQuery.getCount());
+ Assert.assertEquals(3, container.size());
+ }
+
+ @Test
+ public void removeRowThroughContainer_nonexistingRowId_shouldFail()
+ throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+
+ SQLContainer container = new SQLContainer(tQuery);
+ container.setAutoCommit(true);
+ Assert.assertFalse(container.removeItem("foo"));
+ }
+
+ /**********************************************************************
+ * TableQuery row adding / modification tests
+ **********************************************************************/
+ @Test
+ public void insertRowThroughContainer_shouldSucceed() throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+ tQuery.setVersionColumn("ID");
+
+ SQLContainer container = new SQLContainer(tQuery);
+ container.setAutoCommit(false);
+
+ Object item = container.addItem();
+ Assert.assertNotNull(item);
+
+ Assert.assertEquals(4, tQuery.getCount());
+ Assert.assertEquals(5, container.size());
+ container.commit();
+
+ Assert.assertEquals(5, tQuery.getCount());
+ Assert.assertEquals(5, container.size());
+ }
+
+ @Test
+ public void modifyRowThroughContainer_shouldSucceed() throws SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+
+ // In this test the primary key is used as a version column
+ tQuery.setVersionColumn("ID");
+ SQLContainer container = new SQLContainer(tQuery);
+ container.setAutoCommit(false);
+
+ /* Check that the container size is correct and there is no 'Viljami' */
+ Assert.assertEquals(4, container.size());
+ List<Filter> filters = new ArrayList<Filter>();
+ filters.add(new Equal("NAME", "Viljami"));
+ tQuery.setFilters(filters);
+ Assert.assertEquals(0, tQuery.getCount());
+ tQuery.setFilters(null);
+
+ /* Fetch first item, modify and commit */
+ Object item = container.getItem(container.getItemIds().iterator()
+ .next());
+ Assert.assertNotNull(item);
+
+ RowItem ri = (RowItem) item;
+ Assert.assertNotNull(ri.getItemProperty("NAME"));
+ ri.getItemProperty("NAME").setValue("Viljami");
+
+ container.commit();
+
+ // Check that the size is still correct and only 1 'Viljami' is found
+ Assert.assertEquals(4, tQuery.getCount());
+ Assert.assertEquals(4, container.size());
+ tQuery.setFilters(filters);
+ Assert.assertEquals(1, tQuery.getCount());
+ }
+
+ @Test
+ public void storeRow_noVersionColumn_shouldSucceed()
+ throws UnsupportedOperationException, SQLException {
+ TableQuery tQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+ SQLContainer container = new SQLContainer(tQuery);
+ Object id = container.addItem();
+ RowItem row = (RowItem) container.getItem(id);
+ row.getItemProperty("NAME").setValue("R2D2");
+ row.getItemProperty("AGE").setValue(123);
+ tQuery.beginTransaction();
+ tQuery.storeRow(row);
+ tQuery.commit();
+
+ Connection conn = connectionPool.reserveConnection();
+ PreparedStatement stmt = conn
+ .prepareStatement("SELECT * FROM PEOPLE WHERE \"NAME\" = ?");
+ stmt.setString(1, "R2D2");
+ ResultSet rs = stmt.executeQuery();
+ Assert.assertTrue(rs.next());
+ rs.close();
+ stmt.close();
+ connectionPool.releaseConnection(conn);
+ }
+
+ @Test
+ public void storeRow_versionSetAndEqualToDBValue_shouldSucceed()
+ throws SQLException {
+ DataGenerator.addVersionedData(connectionPool);
+
+ TableQuery tQuery = new TableQuery("versioned", connectionPool,
+ SQLTestsConstants.sqlGen);
+ tQuery.setVersionColumn("VERSION");
+ SQLContainer container = new SQLContainer(tQuery);
+ RowItem row = (RowItem) container.getItem(container.firstItemId());
+ Assert.assertEquals("Junk", row.getItemProperty("TEXT").getValue());
+
+ row.getItemProperty("TEXT").setValue("asdf");
+ container.commit();
+
+ Connection conn = connectionPool.reserveConnection();
+ PreparedStatement stmt = conn
+ .prepareStatement("SELECT * FROM VERSIONED WHERE \"TEXT\" = ?");
+ stmt.setString(1, "asdf");
+ ResultSet rs = stmt.executeQuery();
+ Assert.assertTrue(rs.next());
+ rs.close();
+ stmt.close();
+ conn.commit();
+ connectionPool.releaseConnection(conn);
+ }
+
+ @Test(expected = OptimisticLockException.class)
+ public void storeRow_versionSetAndLessThanDBValue_shouldThrowException()
+ throws SQLException {
+ if (SQLTestsConstants.db == DB.HSQLDB) {
+ throw new OptimisticLockException(
+ "HSQLDB doesn't support row versioning for optimistic locking - don't run this test.",
+ null);
+ }
+ DataGenerator.addVersionedData(connectionPool);
+
+ TableQuery tQuery = new TableQuery("versioned", connectionPool,
+ SQLTestsConstants.sqlGen);
+ tQuery.setVersionColumn("VERSION");
+ SQLContainer container = new SQLContainer(tQuery);
+ RowItem row = (RowItem) container.getItem(container.firstItemId());
+ Assert.assertEquals("Junk", row.getItemProperty("TEXT").getValue());
+
+ row.getItemProperty("TEXT").setValue("asdf");
+
+ // Update the version using another connection.
+ Connection conn = connectionPool.reserveConnection();
+ PreparedStatement stmt = conn
+ .prepareStatement("UPDATE VERSIONED SET \"TEXT\" = ? WHERE \"ID\" = ?");
+ stmt.setString(1, "foo");
+ stmt.setObject(2, row.getItemProperty("ID").getValue());
+ stmt.executeUpdate();
+ stmt.close();
+ conn.commit();
+ connectionPool.releaseConnection(conn);
+
+ container.commit();
+ }
+
+ @Test
+ public void removeRow_versionSetAndEqualToDBValue_shouldSucceed()
+ throws SQLException {
+ DataGenerator.addVersionedData(connectionPool);
+
+ TableQuery tQuery = new TableQuery("versioned", connectionPool,
+ SQLTestsConstants.sqlGen);
+ tQuery.setVersionColumn("VERSION");
+ SQLContainer container = new SQLContainer(tQuery);
+ RowItem row = (RowItem) container.getItem(container.firstItemId());
+ Assert.assertEquals("Junk", row.getItemProperty("TEXT").getValue());
+
+ container.removeItem(container.firstItemId());
+ container.commit();
+
+ Connection conn = connectionPool.reserveConnection();
+ PreparedStatement stmt = conn
+ .prepareStatement("SELECT * FROM VERSIONED WHERE \"TEXT\" = ?");
+ stmt.setString(1, "Junk");
+ ResultSet rs = stmt.executeQuery();
+ Assert.assertFalse(rs.next());
+ rs.close();
+ stmt.close();
+ conn.commit();
+ connectionPool.releaseConnection(conn);
+ }
+
+ @Test(expected = OptimisticLockException.class)
+ public void removeRow_versionSetAndLessThanDBValue_shouldThrowException()
+ throws SQLException {
+ if (SQLTestsConstants.db == SQLTestsConstants.DB.HSQLDB) {
+ // HSQLDB doesn't support versioning, so this is to make the test
+ // green.
+ throw new OptimisticLockException(null);
+ }
+ DataGenerator.addVersionedData(connectionPool);
+
+ TableQuery tQuery = new TableQuery("versioned", connectionPool,
+ SQLTestsConstants.sqlGen);
+ tQuery.setVersionColumn("VERSION");
+ SQLContainer container = new SQLContainer(tQuery);
+ RowItem row = (RowItem) container.getItem(container.firstItemId());
+ Assert.assertEquals("Junk", row.getItemProperty("TEXT").getValue());
+
+ // Update the version using another connection.
+ Connection conn = connectionPool.reserveConnection();
+ PreparedStatement stmt = conn
+ .prepareStatement("UPDATE VERSIONED SET \"TEXT\" = ? WHERE \"ID\" = ?");
+ stmt.setString(1, "asdf");
+ stmt.setObject(2, row.getItemProperty("ID").getValue());
+ stmt.executeUpdate();
+ stmt.close();
+ conn.commit();
+ connectionPool.releaseConnection(conn);
+
+ container.removeItem(container.firstItemId());
+ container.commit();
+ }
+
+ @Test
+ public void removeRow_throwsOptimisticLockException_shouldStillWork()
+ throws SQLException {
+ if (SQLTestsConstants.db == SQLTestsConstants.DB.HSQLDB) {
+ // HSQLDB doesn't support versioning, so this is to make the test
+ // green.
+ return;
+ }
+ DataGenerator.addVersionedData(connectionPool);
+
+ TableQuery tQuery = new TableQuery("versioned", connectionPool,
+ SQLTestsConstants.sqlGen);
+ tQuery.setVersionColumn("VERSION");
+ SQLContainer container = new SQLContainer(tQuery);
+ RowItem row = (RowItem) container.getItem(container.firstItemId());
+ Assert.assertEquals("Junk", row.getItemProperty("TEXT").getValue());
+
+ // Update the version using another connection.
+ Connection conn = connectionPool.reserveConnection();
+ PreparedStatement stmt = conn
+ .prepareStatement("UPDATE VERSIONED SET \"TEXT\" = ? WHERE \"ID\" = ?");
+ stmt.setString(1, "asdf");
+ stmt.setObject(2, row.getItemProperty("ID").getValue());
+ stmt.executeUpdate();
+ stmt.close();
+ conn.commit();
+ connectionPool.releaseConnection(conn);
+
+ Object itemToRemove = container.firstItemId();
+ try {
+ container.removeItem(itemToRemove);
+ container.commit();
+ } catch (OptimisticLockException e) {
+ // This is expected, refresh and try again.
+ container.rollback();
+ container.removeItem(itemToRemove);
+ container.commit();
+ }
+ Object id = container.addItem();
+ RowItem item = (RowItem) container.getItem(id);
+ item.getItemProperty("TEXT").setValue("foo");
+ container.commit();
+ }
+
+ @Test
+ public void construction_explicitSchema_shouldSucceed() throws SQLException {
+ if (SQLTestsConstants.createSchema == null
+ || SQLTestsConstants.createProductTable == null
+ || SQLTestsConstants.dropSchema == null) {
+ // only perform the test on the databases for which the setup and
+ // cleanup statements are available
+ return;
+ }
+
+ // create schema "oaas" and table "product" in it
+ Connection conn = connectionPool.reserveConnection();
+ Statement statement = conn.createStatement();
+ try {
+ statement.execute(SQLTestsConstants.dropSchema);
+ } catch (SQLException e) {
+ // May fail if schema doesn't exist, which is OK.
+ conn.rollback();
+ }
+ statement.execute(SQLTestsConstants.createSchema);
+ statement.execute(SQLTestsConstants.createProductTable);
+ conn.commit();
+
+ try {
+ // metadata scanning at query creation time should not fail
+ TableQuery tq1 = new TableQuery(null, "oaas", "product",
+ connectionPool, SQLTestsConstants.sqlGen);
+ Assert.assertNotNull(tq1);
+ } finally {
+ // cleanup - might not be an in-memory DB
+ statement.execute(SQLTestsConstants.dropSchema);
+ }
+
+ // Cleanup to make test connection pool happy
+ connectionPool.releaseConnection(conn);
+ }
+
+ @Test
+ public void construction_explicitCatalogAndSchema_shouldSucceed()
+ throws SQLException {
+ // not all databases support explicit catalogs, test with PostgreSQL
+ // using database name as catalog
+ if (SQLTestsConstants.db != SQLTestsConstants.DB.POSTGRESQL
+ || SQLTestsConstants.createSchema == null
+ || SQLTestsConstants.createProductTable == null
+ || SQLTestsConstants.dropSchema == null) {
+ // only perform the test on the databases for which the setup and
+ // cleanup statements are available
+ return;
+ }
+
+ // create schema "oaas" and table "product" in it
+ Connection conn = connectionPool.reserveConnection();
+ Statement statement = conn.createStatement();
+ try {
+ statement.execute(SQLTestsConstants.dropSchema);
+ } catch (SQLException e) {
+ // May fail if schema doesn't exist, which is OK.
+ conn.rollback();
+ }
+ statement.execute(SQLTestsConstants.createSchema);
+ statement.execute(SQLTestsConstants.createProductTable);
+ conn.commit();
+
+ try {
+ // metadata scanning at query creation time should not fail
+ // note that for most DBMS, catalog is just an optional database
+ // name
+ TableQuery tq1 = new TableQuery("sqlcontainer", "oaas", "product",
+ connectionPool, SQLTestsConstants.sqlGen);
+ Assert.assertNotNull(tq1);
+ } finally {
+ // cleanup - might not be an in-memory DB
+ statement.execute(SQLTestsConstants.dropSchema);
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/query/ValidatingSimpleJDBCConnectionPool.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/query/ValidatingSimpleJDBCConnectionPool.java
new file mode 100644
index 0000000000..f40455f1d7
--- /dev/null
+++ b/server/src/test/java/com/vaadin/data/util/sqlcontainer/query/ValidatingSimpleJDBCConnectionPool.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.data.util.sqlcontainer.query;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool;
+import com.vaadin.data.util.sqlcontainer.connection.SimpleJDBCConnectionPool;
+
+/**
+ * Connection pool for testing SQLContainer. Ensures that only reserved
+ * connections are released and that all connections are released before the
+ * pool is destroyed.
+ *
+ * @author Vaadin Ltd
+ */
+public class ValidatingSimpleJDBCConnectionPool implements JDBCConnectionPool {
+
+ private JDBCConnectionPool realPool;
+ private Set<Connection> reserved = new HashSet<Connection>();
+ private Set<Connection> alreadyReleased = new HashSet<Connection>();
+
+ public ValidatingSimpleJDBCConnectionPool(String driverName,
+ String connectionUri, String userName, String password,
+ int initialConnections, int maxConnections) throws SQLException {
+ realPool = new SimpleJDBCConnectionPool(driverName, connectionUri,
+ userName, password, initialConnections, maxConnections);
+ }
+
+ @Deprecated
+ public JDBCConnectionPool getRealPool() {
+ return realPool;
+ }
+
+ @Override
+ public Connection reserveConnection() throws SQLException {
+ Connection c = realPool.reserveConnection();
+ reserved.add(c);
+ return c;
+ }
+
+ @Override
+ public void releaseConnection(Connection conn) {
+ if (conn != null && !reserved.remove(conn)) {
+ if (alreadyReleased.contains(conn)) {
+ getLogger().severe(
+ "Tried to release connection (" + conn
+ + ") which has already been released");
+ } else {
+ throw new RuntimeException("Tried to release connection ("
+ + conn + ") not reserved using reserveConnection");
+ }
+ }
+ realPool.releaseConnection(conn);
+ alreadyReleased.add(conn);
+
+ }
+
+ @Override
+ public void destroy() {
+ realPool.destroy();
+ if (!reserved.isEmpty()) {
+ throw new RuntimeException(reserved.size()
+ + " connections never released");
+ }
+ }
+
+ private static Logger getLogger() {
+ return Logger.getLogger(ValidatingSimpleJDBCConnectionPool.class
+ .getName());
+ }
+} \ No newline at end of file
diff --git a/server/src/test/java/com/vaadin/server/AbstractClientConnectorProxyHandlingTest.java b/server/src/test/java/com/vaadin/server/AbstractClientConnectorProxyHandlingTest.java
new file mode 100644
index 0000000000..c15676c18e
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/AbstractClientConnectorProxyHandlingTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2000-2014 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.server;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * We test that AbstractClientConnector has a suitable isThis method which is
+ * needed to correctly perform an equals check between a proxy and it's
+ * underlying instance.
+ *
+ * @author Vaadin Ltd
+ */
+public class AbstractClientConnectorProxyHandlingTest {
+
+ @Test
+ public void abstractClientConnectorTest() {
+ try {
+ Method method = AbstractClientConnector.class.getDeclaredMethod(
+ "isThis", Object.class);
+ int modifiers = method.getModifiers();
+ if (Modifier.isFinal(modifiers) || !Modifier.isProtected(modifiers)
+ || Modifier.isStatic(modifiers)) {
+ Assert.fail("isThis has invalid modifiers, CDI proxies will not work.");
+ }
+ } catch (SecurityException e) {
+ // Ignore, no can do
+ } catch (NoSuchMethodException e) {
+ Assert.fail("isThis is missing, CDI proxies will not work.");
+ }
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/server/AbstractClientConnectorTest.java b/server/src/test/java/com/vaadin/server/AbstractClientConnectorTest.java
new file mode 100644
index 0000000000..96ca82a0b3
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/AbstractClientConnectorTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2000-2014 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.server;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import com.vaadin.shared.MouseEventDetails;
+import com.vaadin.shared.communication.FieldRpc.BlurServerRpc;
+import com.vaadin.shared.ui.ClickRpc;
+
+/**
+ * We test that AbstractClientConnector has a suitable isThis method which is
+ * needed to correctly perform an equals check between a proxy and it's
+ * underlying instance.
+ *
+ * @author Vaadin Ltd
+ */
+public class AbstractClientConnectorTest {
+
+ @Test
+ public void registerRPCMultiInterfaceTest() {
+ AbstractClientConnector mock = mock(AbstractClientConnector.class);
+ MultiServerRpcMock implementation = new MultiServerRpcMock();
+ Mockito.doCallRealMethod().when(mock).registerRpc(implementation);
+ try {
+ mock.registerRpc(implementation);
+ Assert.fail("expected exception");
+ } catch (Exception expected) {
+ Assert.assertEquals(
+ expected.getMessage(),
+ "Use registerRpc(T implementation, Class<T> rpcInterfaceType) if the Rpc implementation implements more than one interface");
+ }
+ }
+
+ @Test
+ public void registerRPCInterfaceTest() {
+ AbstractClientConnector mock = mock(AbstractClientConnector.class);
+ ServerRpcMock implementation = new ServerRpcMock();
+ Mockito.doCallRealMethod().when(mock).registerRpc(implementation);
+ mock.registerRpc(implementation);
+ verify(mock, times(1)).registerRpc(implementation, ClickRpc.class);
+ }
+
+ @Test
+ public void registerRPCInterfaceLastTest() {
+ AbstractClientConnector mock = mock(AbstractClientConnector.class);
+ ServerRpcLastMock implementation = new ServerRpcLastMock();
+ Mockito.doCallRealMethod().when(mock).registerRpc(implementation);
+ mock.registerRpc(implementation);
+ verify(mock, times(1)).registerRpc(implementation, ClickRpc.class);
+ }
+
+ private class ServerRpcLastMock implements Comparable<ServerRpcLastMock>,
+ ClickRpc {
+ private static final long serialVersionUID = -2822356895755286180L;
+
+ @Override
+ public void click(MouseEventDetails mouseDetails) {
+ }
+
+ @Override
+ public int compareTo(ServerRpcLastMock o) {
+ return 0;
+ }
+
+ }
+
+ private class ServerRpcMock implements ClickRpc {
+ private static final long serialVersionUID = 2822356895755286180L;
+
+ @Override
+ public void click(MouseEventDetails mouseDetails) {
+ }
+
+ }
+
+ private class MultiServerRpcMock implements ClickRpc, BlurServerRpc {
+
+ private static final long serialVersionUID = -7611999715560330373L;
+
+ @Override
+ public void blur() {
+
+ }
+
+ @Override
+ public void click(MouseEventDetails mouseDetails) {
+
+ }
+
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/server/AbstractDeploymentConfigurationTest.java b/server/src/test/java/com/vaadin/server/AbstractDeploymentConfigurationTest.java
new file mode 100644
index 0000000000..0518bea650
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/AbstractDeploymentConfigurationTest.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2000-2014 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.server;
+
+import java.util.Properties;
+import java.util.UUID;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.shared.communication.PushMode;
+
+/**
+ * Test for {@link AbstractDeploymentConfiguration}
+ *
+ * @author Vaadin Ltd
+ */
+public class AbstractDeploymentConfigurationTest {
+
+ @Test
+ public void getUIClass_returnsUIParameterPropertyValue() {
+ String ui = UUID.randomUUID().toString();
+ DeploymentConfiguration config = getConfig(VaadinSession.UI_PARAMETER,
+ ui);
+ Assert.assertEquals("Unexpected UI class configuration option value",
+ ui, config.getUIClassName());
+ }
+
+ @Test
+ public void getUIProviderClass_returnsUIProviderPropertyValue() {
+ String uiProvider = UUID.randomUUID().toString();
+ DeploymentConfiguration config = getConfig(
+ Constants.SERVLET_PARAMETER_UI_PROVIDER, uiProvider);
+ Assert.assertEquals(
+ "Unexpected UI providerclass configuration option value",
+ uiProvider, config.getUIProviderClassName());
+ }
+
+ @Test
+ public void getWidgetset_returnsWidgetsetProviderPropertyValue() {
+ String widgetset = UUID.randomUUID().toString();
+ DeploymentConfiguration config = getConfig(
+ Constants.PARAMETER_WIDGETSET, widgetset);
+ Assert.assertEquals("Unexpected widgetset configuration option value",
+ widgetset, config.getWidgetset(null));
+ }
+
+ @Test
+ public void getWidgetset_noWidgetsetPropertyValue_returnsProvidedDefaultValue() {
+ DeploymentConfiguration config = getConfig(null, null);
+ String widgetset = UUID.randomUUID().toString();
+ Assert.assertEquals("Unexpected widgetset configuration option value",
+ widgetset, config.getWidgetset(widgetset));
+ }
+
+ @Test
+ public void getResourcesPath_returnsResourcesPathPropertyValue() {
+ String resources = UUID.randomUUID().toString();
+ DeploymentConfiguration config = getConfig(
+ Constants.PARAMETER_VAADIN_RESOURCES, resources);
+ Assert.assertEquals(
+ "Unexpected resources path configuration option value",
+ resources, config.getResourcesPath());
+ }
+
+ @Test
+ public void getClassLoader_returnsClassloaderPropertyValue() {
+ String classLoader = UUID.randomUUID().toString();
+ DeploymentConfiguration config = getConfig("ClassLoader", classLoader);
+ Assert.assertEquals(
+ "Unexpected classLoader configuration option value",
+ classLoader, config.getClassLoaderName());
+ }
+
+ private DeploymentConfiguration getConfig(String property, String value) {
+ Properties props = new Properties();
+ if (property != null) {
+ props.put(property, value);
+ }
+ return new DeploymentConfigImpl(props);
+ }
+
+ private static class DeploymentConfigImpl extends
+ AbstractDeploymentConfiguration {
+
+ private Properties properties;
+
+ DeploymentConfigImpl(Properties props) {
+ properties = props;
+ }
+
+ @Override
+ public boolean isProductionMode() {
+ return false;
+ }
+
+ @Override
+ public boolean isXsrfProtectionEnabled() {
+ return false;
+ }
+
+ @Override
+ public boolean isSyncIdCheckEnabled() {
+ return false;
+ }
+
+ @Override
+ public int getResourceCacheTime() {
+ return 0;
+ }
+
+ @Override
+ public int getHeartbeatInterval() {
+ return 0;
+ }
+
+ @Override
+ public boolean isCloseIdleSessions() {
+ return false;
+ }
+
+ @Override
+ public PushMode getPushMode() {
+ return null;
+ }
+
+ @Override
+ public Properties getInitParameters() {
+ return null;
+ }
+
+ @Override
+ public String getApplicationOrSystemProperty(String propertyName,
+ String defaultValue) {
+ return properties.getProperty(propertyName, defaultValue);
+ }
+
+ @Override
+ public LegacyProperyToStringMode getLegacyPropertyToStringMode() {
+ return null;
+ }
+
+ @Override
+ public boolean isSendUrlsAsParameters() {
+ return DefaultDeploymentConfiguration.DEFAULT_SEND_URLS_AS_PARAMETERS;
+ }
+
+ }
+}
diff --git a/server/src/test/java/com/vaadin/server/BrowserWindowOpenerTest.java b/server/src/test/java/com/vaadin/server/BrowserWindowOpenerTest.java
new file mode 100644
index 0000000000..7c76f7d421
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/BrowserWindowOpenerTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2000-2014 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.server;
+
+import static org.junit.Assert.assertEquals;
+
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.shared.communication.URLReference;
+import com.vaadin.shared.ui.BrowserWindowOpenerState;
+
+/**
+ *
+ * @author Vaadin Ltd
+ */
+public class BrowserWindowOpenerTest {
+
+ @Test
+ public void setResource_urlBasedOpener_resourceIsSetAndUrlIsNull() {
+ BrowserWindowOpener opener = new BrowserWindowOpener("url");
+
+ StreamResource resource = EasyMock.createMock(StreamResource.class);
+ opener.setResource(resource);
+
+ assertEquals("Unexpected resource is got on getResource() method",
+ resource, opener.getResource());
+ Assert.assertNull("Unexpected resource is got on getUrl() method",
+ opener.getUrl());
+
+ URLReference ref = opener.getState(false).resources
+ .get(BrowserWindowOpenerState.locationResource);
+ Assert.assertTrue(
+ "Url reference in the state is not ResourceReference",
+ ref instanceof ResourceReference);
+ Assert.assertEquals("Unexpected resource saved in state", resource,
+ ((ResourceReference) ref).getResource());
+ }
+
+ @Test
+ public void setUrl_urlBasedOpener_urlIsSet() {
+ BrowserWindowOpener opener = new BrowserWindowOpener("url");
+
+ String url = "newUrl";
+ opener.setUrl(url);
+
+ assertEquals("Unexpected URL is got on getURL() method", url,
+ opener.getUrl());
+ Assert.assertNotNull(
+ "Unexpected resource is got on getResource() method",
+ opener.getResource());
+
+ URLReference ref = opener.getState(false).resources
+ .get(BrowserWindowOpenerState.locationResource);
+ Assert.assertTrue(
+ "Url reference in the state is not ResourceReference",
+ ref instanceof ResourceReference);
+ Resource resource = ((ResourceReference) ref).getResource();
+ Assert.assertTrue("Resource reference is not ExternalResource",
+ resource instanceof ExternalResource);
+ Assert.assertEquals("Unexpected URL in resource saved in state", url,
+ ((ExternalResource) resource).getURL());
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/server/ConnectorResourceHandlerTest.java b/server/src/test/java/com/vaadin/server/ConnectorResourceHandlerTest.java
new file mode 100644
index 0000000000..a5746065d6
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/ConnectorResourceHandlerTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2000-2014 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.server;
+
+import java.io.IOException;
+
+import org.easymock.EasyMock;
+import org.easymock.IMocksControl;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.ui.Button;
+import com.vaadin.ui.UI;
+
+public class ConnectorResourceHandlerTest {
+
+ VaadinRequest request;
+ VaadinResponse response;
+ VaadinSession session;
+ UI ui;
+
+ @Before
+ public void setUp() {
+ IMocksControl control = EasyMock.createNiceControl();
+
+ request = control.createMock(VaadinRequest.class);
+ response = control.createMock(VaadinResponse.class);
+ VaadinService service = control.createMock(VaadinService.class);
+
+ EasyMock.expect(request.getPathInfo())
+ .andReturn("/APP/connector/0/1/2");
+
+ control.replay();
+
+ session = new MockVaadinSession(service);
+
+ ui = new UI() {
+ @Override
+ protected void init(VaadinRequest request) {
+ }
+ };
+ ui.doInit(request, 0, "");
+
+ session.lock();
+ try {
+ session.setCommunicationManager(new LegacyCommunicationManager(
+ session));
+ ui.setSession(session);
+ session.addUI(ui);
+ } finally {
+ session.unlock();
+ }
+ }
+
+ @Test
+ public void testErrorHandling() throws IOException {
+
+ ErrorHandler errorHandler = EasyMock.createMock(ErrorHandler.class);
+ errorHandler.error(EasyMock.anyObject(ErrorEvent.class));
+ EasyMock.replay(errorHandler);
+
+ Button button = new Button() {
+ @Override
+ public boolean handleConnectorRequest(VaadinRequest request,
+ VaadinResponse response, String path) {
+ throw new RuntimeException();
+ }
+ };
+ button.setErrorHandler(errorHandler);
+
+ session.lock();
+ try {
+ ui.setContent(button);
+ } finally {
+ session.unlock();
+ }
+
+ ConnectorResourceHandler handler = new ConnectorResourceHandler();
+ Assert.assertTrue(handler.handleRequest(session, request, response));
+
+ EasyMock.verify(errorHandler);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/server/DefaultDeploymentConfigurationTest.java b/server/src/test/java/com/vaadin/server/DefaultDeploymentConfigurationTest.java
new file mode 100644
index 0000000000..7cbb73af17
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/DefaultDeploymentConfigurationTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2000-2014 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.server;
+
+import java.util.Properties;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Tests for {@link DefaultDeploymentConfiguration}
+ *
+ * @author Vaadin Ltd
+ * @since 7.2
+ */
+public class DefaultDeploymentConfigurationTest {
+
+ @Test
+ public void testGetSystemPropertyForDefaultPackage()
+ throws ClassNotFoundException {
+ Class<?> clazz = Class.forName("ClassInDefaultPackage");
+ String value = "value";
+ String prop = "prop";
+ System.setProperty(prop, value);
+ DefaultDeploymentConfiguration config = new DefaultDeploymentConfiguration(
+ clazz, new Properties());
+ Assert.assertEquals(value, config.getSystemProperty(prop));
+ }
+
+ @Test
+ public void testGetSystemProperty() throws ClassNotFoundException {
+ String value = "value";
+ String prop = "prop";
+ System.setProperty(DefaultDeploymentConfigurationTest.class
+ .getPackage().getName() + '.' + prop, value);
+ DefaultDeploymentConfiguration config = new DefaultDeploymentConfiguration(
+ DefaultDeploymentConfigurationTest.class, new Properties());
+ Assert.assertEquals(value, config.getSystemProperty(prop));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/server/DownloadStreamTest.java b/server/src/test/java/com/vaadin/server/DownloadStreamTest.java
new file mode 100644
index 0000000000..180b2e348b
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/DownloadStreamTest.java
@@ -0,0 +1,39 @@
+package com.vaadin.server;
+
+import static org.mockito.Matchers.contains;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URLEncoder;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class DownloadStreamTest {
+ private String filename = "日本語.png";
+ private DownloadStream stream;
+
+ @Before
+ public void setup() {
+ stream = new DownloadStream(mock(InputStream.class), "", filename);
+ }
+
+ @Test
+ public void contentDispositionFilenameIsUtf8Encoded() throws IOException {
+ VaadinResponse response = mock(VaadinResponse.class);
+
+ stream.writeResponse(mock(VaadinRequest.class), response);
+
+ String encodedFileName = URLEncoder.encode(filename, "utf-8");
+ verify(response).setHeader(eq(DownloadStream.CONTENT_DISPOSITION),
+ contains(String.format("filename=\"%s\";", encodedFileName)));
+ verify(response)
+ .setHeader(
+ eq(DownloadStream.CONTENT_DISPOSITION),
+ contains(String.format("filename*=utf-8''%s",
+ encodedFileName)));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/server/DragAndDropServiceTest.java b/server/src/test/java/com/vaadin/server/DragAndDropServiceTest.java
new file mode 100644
index 0000000000..d0cb0ca5a6
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/DragAndDropServiceTest.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2000-2014 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.server;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+import java.util.logging.StreamHandler;
+
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.event.dd.DropHandler;
+import com.vaadin.event.dd.TargetDetails;
+import com.vaadin.ui.AbstractComponent;
+
+/**
+ * Tests for {@link DragAndDropService}.
+ *
+ * @author Vaadin Ltd
+ */
+public class DragAndDropServiceTest {
+
+ @Test
+ public void changeVariables_isSourceConnectorEnabledCalled() {
+ final List<Level> levels = new ArrayList<Level>();
+ Logger.getLogger(DragAndDropService.class.getName()).addHandler(
+ new StreamHandler() {
+ @Override
+ public synchronized void publish(LogRecord record) {
+ levels.add(record.getLevel());
+ }
+ });
+ Map<String, Object> variables = new HashMap<String, Object>();
+ final boolean[] isConnectorEnabledCalled = new boolean[1];
+ AbstractComponent component = new AbstractComponent() {
+ @Override
+ public boolean isConnectorEnabled() {
+ isConnectorEnabledCalled[0] = true;
+ return false;
+ }
+ };
+ variables.put("component", component);
+
+ DragAndDropService service = new DragAndDropService(
+ EasyMock.createMock(VaadinSession.class));
+ service.changeVariables(null, variables);
+
+ Assert.assertTrue("isConnectorEnabled() method is not called",
+ isConnectorEnabledCalled[0]);
+ Assert.assertTrue("No warning on drop from disabled source",
+ levels.contains(Level.WARNING));
+
+ }
+
+ @Test
+ public void changeVariables_isTargetConnectorEnabledCalled() {
+ final List<Level> levels = new ArrayList<Level>();
+ Logger.getLogger(DragAndDropService.class.getName()).addHandler(
+ new StreamHandler() {
+ @Override
+ public void publish(LogRecord record) {
+ levels.add(record.getLevel());
+ }
+ });
+ Map<String, Object> variables = new HashMap<String, Object>();
+ TestDropTarget target = new TestDropTarget();
+ variables.put("dhowner", target);
+
+ DragAndDropService service = new DragAndDropService(
+ EasyMock.createMock(VaadinSession.class));
+ service.changeVariables(null, variables);
+
+ Assert.assertTrue("isConnectorEnabled() method is not called",
+ target.isConnectorEnabledCalled());
+ Assert.assertTrue("No warning on drop to disabled target",
+ levels.contains(Level.WARNING));
+
+ }
+
+ private static class TestDropTarget extends AbstractComponent implements
+ com.vaadin.event.dd.DropTarget {
+ @Override
+ public boolean isConnectorEnabled() {
+ isConnectorEnabledCalled = true;
+ return false;
+ }
+
+ @Override
+ public DropHandler getDropHandler() {
+ return null;
+ }
+
+ @Override
+ public TargetDetails translateDropTargetDetails(
+ Map<String, Object> clientVariables) {
+ return null;
+ }
+
+ boolean isConnectorEnabledCalled() {
+ return isConnectorEnabledCalled;
+ }
+
+ private boolean isConnectorEnabledCalled;
+
+ }
+}
diff --git a/server/src/test/java/com/vaadin/server/JSONSerializerTest.java b/server/src/test/java/com/vaadin/server/JSONSerializerTest.java
new file mode 100644
index 0000000000..6c57445564
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/JSONSerializerTest.java
@@ -0,0 +1,171 @@
+package com.vaadin.server;
+
+/*
+ * Copyright 2000-2014 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.AssertionFailedError;
+import junit.framework.TestCase;
+
+import com.vaadin.server.JsonCodec.BeanProperty;
+import com.vaadin.shared.communication.UidlValue;
+import com.vaadin.shared.ui.splitpanel.AbstractSplitPanelState;
+
+import elemental.json.Json;
+import elemental.json.JsonArray;
+import elemental.json.JsonException;
+import elemental.json.JsonValue;
+
+/**
+ * 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.caption = "State 1";
+ s.id = "foo";
+ s2.caption = "State 2";
+ s2.id = "bar";
+ stringToStateMap.put("string - state 1", s);
+ stringToStateMap.put("String - state 2", s2);
+
+ JsonValue 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.caption = "State 1";
+ s2.caption = "State 2";
+ stateToStringMap.put(s, "string - state 1");
+ stateToStringMap.put(s2, "String - state 2");
+
+ JsonValue encodedMap = JsonCodec.encode(stateToStringMap, null,
+ mapType, null).getEncodedValue();
+
+ ensureDecodedCorrectly(stateToStringMap, encodedMap, mapType);
+ }
+
+ public void testNullLegacyValue() throws JsonException {
+ JsonArray inputArray = Json.createArray();
+ inputArray.set(0, "n");
+ inputArray.set(1, Json.createNull());
+ UidlValue decodedObject = (UidlValue) JsonCodec.decodeInternalType(
+ UidlValue.class, true, inputArray, null);
+ assertNull(decodedObject.getValue());
+ }
+
+ public void testNullTypeOtherValue() {
+ try {
+ JsonArray inputArray = Json.createArray();
+ inputArray.set(0, "n");
+ inputArray.set(1, "a");
+ UidlValue decodedObject = (UidlValue) JsonCodec.decodeInternalType(
+ UidlValue.class, true, inputArray, null);
+
+ throw new AssertionFailedError("No JsonException thrown");
+ } catch (JsonException e) {
+ // Should throw exception
+ }
+ }
+
+ private void ensureDecodedCorrectly(Object original, JsonValue 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/src/test/java/com/vaadin/server/JsonEqualsTest.java b/server/src/test/java/com/vaadin/server/JsonEqualsTest.java
new file mode 100644
index 0000000000..ca3bfced79
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/JsonEqualsTest.java
@@ -0,0 +1,276 @@
+/*
+ * Copyright 2000-2014 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.server;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import elemental.json.Json;
+import elemental.json.JsonArray;
+import elemental.json.JsonObject;
+import elemental.json.JsonValue;
+
+public class JsonEqualsTest {
+
+ @Test
+ public void differentTypes_notEqual() {
+ boolean equals = JsonCodec.jsonEquals(Json.create(5), Json.create("5"));
+
+ Assert.assertFalse("Different types should not be equal", equals);
+ }
+
+ @Test
+ public void nulls_equal() {
+ boolean equals = JsonCodec.jsonEquals(Json.createNull(),
+ Json.createNull());
+
+ Assert.assertTrue("Null and null should be equal", equals);
+ }
+
+ @Test
+ public void differentBooleans_notEqual() {
+ boolean equals = JsonCodec.jsonEquals(Json.create(true),
+ Json.create(false));
+
+ Assert.assertFalse("Different booleans should not be equal", equals);
+ }
+
+ @Test
+ public void sameBooleans_equal() {
+ boolean equals = JsonCodec.jsonEquals(Json.create(false),
+ Json.create(false));
+
+ Assert.assertTrue("Same booleans should be equal", equals);
+ }
+
+ @Test
+ public void differentNumbers_notEqual() {
+ boolean equals = JsonCodec.jsonEquals(Json.create(2), Json.create(5.6));
+
+ Assert.assertFalse("Different numbers should not be equal", equals);
+ }
+
+ @Test
+ public void sameNumbers_equal() {
+ boolean equals = JsonCodec.jsonEquals(Json.create(3.14),
+ Json.create(3.14));
+
+ Assert.assertTrue("Same numbers should be equal", equals);
+ }
+
+ @Test
+ public void differentStrings_notEqual() {
+ boolean equals = JsonCodec.jsonEquals(Json.create("abc"),
+ Json.create("def"));
+
+ Assert.assertFalse("Different strings should not be equal", equals);
+ }
+
+ @Test
+ public void sameStrings_equal() {
+ boolean equals = JsonCodec.jsonEquals(Json.create("abc"),
+ Json.create("abc"));
+
+ Assert.assertTrue("Same strings should be equal", equals);
+ }
+
+ @Test
+ public void differentKeyCountObject_notEqual() {
+ JsonObject o1 = Json.createObject();
+ o1.put("key", "value");
+
+ JsonObject o2 = Json.createObject();
+
+ boolean equals = JsonCodec.jsonEquals(o1, o2);
+
+ Assert.assertFalse(
+ "Object with different key counts should not be equal", equals);
+ }
+
+ @Test
+ public void differentKeySetObject_notEqual() {
+ JsonObject o1 = Json.createObject();
+ o1.put("key", "value");
+
+ JsonObject o2 = Json.createObject();
+ o2.put("key2", "value");
+
+ boolean equals = JsonCodec.jsonEquals(o1, o2);
+
+ Assert.assertFalse("Object with different keys should not be equal",
+ equals);
+ }
+
+ @Test
+ public void differentChildValuesObject_notEqual() {
+ JsonObject o1 = Json.createObject();
+ o1.put("key", "value");
+
+ JsonObject o2 = Json.createObject();
+ o2.put("key", true);
+
+ boolean equals = JsonCodec.jsonEquals(o1, o2);
+
+ Assert.assertFalse(
+ "Object with different child values should not be equal",
+ equals);
+ }
+
+ @Test
+ public void emptyObjects_equal() {
+ JsonObject o1 = Json.createObject();
+ JsonObject o2 = Json.createObject();
+
+ boolean equals = JsonCodec.jsonEquals(o1, o2);
+
+ Assert.assertTrue("Empty objects should be equal", equals);
+ }
+
+ @Test
+ public void sameObjects_equal() {
+ JsonObject o1 = Json.createObject();
+ o1.put("key", "value");
+
+ JsonObject o2 = Json.createObject();
+ o2.put("key", "value");
+
+ boolean equals = JsonCodec.jsonEquals(o1, o2);
+
+ Assert.assertTrue("Same objects should be equal", equals);
+ }
+
+ @Test
+ public void sameObjectsWithNullValues_equal() {
+ JsonObject o1 = Json.createObject();
+ o1.put("key", Json.createNull());
+
+ JsonObject o2 = Json.createObject();
+ o2.put("key", Json.createNull());
+
+ boolean equals = JsonCodec.jsonEquals(o1, o2);
+
+ Assert.assertTrue("Same objects should be equal", equals);
+ }
+
+ @Test
+ public void differentSizeArray_notEqual() {
+ JsonArray a1 = Json.createArray();
+ a1.set(0, 0);
+
+ JsonArray a2 = Json.createArray();
+
+ boolean equals = JsonCodec.jsonEquals(a1, a2);
+
+ Assert.assertFalse("Arrays with different sizes should not be equal",
+ equals);
+ }
+
+ @Test
+ public void differentContentArray_notEqual() {
+ JsonArray a1 = Json.createArray();
+ a1.set(0, 0);
+
+ JsonArray a2 = Json.createArray();
+ a2.set(0, 1);
+
+ boolean equals = JsonCodec.jsonEquals(a1, a2);
+
+ Assert.assertFalse("Arrays with different content should not be equal",
+ equals);
+ }
+
+ @Test
+ public void differentOrderArray_notEqual() {
+ JsonArray a1 = Json.createArray();
+ a1.set(0, 0);
+ a1.set(1, true);
+
+ JsonArray a2 = Json.createArray();
+ a2.set(0, true);
+ a2.set(1, 0);
+
+ boolean equals = JsonCodec.jsonEquals(a1, a2);
+
+ Assert.assertFalse("Arrays with different order should not be equal",
+ equals);
+ }
+
+ @Test
+ public void emptyArrays_equal() {
+ JsonArray a1 = Json.createArray();
+ JsonArray a2 = Json.createArray();
+
+ boolean equals = JsonCodec.jsonEquals(a1, a2);
+
+ Assert.assertTrue("Empty arrays should be equal", equals);
+ }
+
+ @Test
+ public void sameArrays_equal() {
+ JsonArray a1 = Json.createArray();
+ a1.set(0, 0);
+ a1.set(1, true);
+
+ JsonArray a2 = Json.createArray();
+ a2.set(0, 0);
+ a2.set(1, true);
+
+ boolean equals = JsonCodec.jsonEquals(a1, a2);
+
+ Assert.assertTrue("Same arrays should be equal", equals);
+ }
+
+ @Test
+ public void sameArraysWitNull_equal() {
+ JsonArray a1 = Json.createArray();
+ a1.set(0, Json.createNull());
+
+ JsonArray a2 = Json.createArray();
+ a2.set(0, Json.createNull());
+
+ boolean equals = JsonCodec.jsonEquals(a1, a2);
+
+ Assert.assertTrue("Same arrays should be equal", equals);
+ }
+
+ @Test
+ public void differentDeeplyNested_notEquals() {
+ boolean equals = JsonCodec.jsonEquals(createDeeplyNestedValue(1),
+ createDeeplyNestedValue(2));
+
+ Assert.assertFalse("Values should not be equal", equals);
+ }
+
+ @Test
+ public void sameDeeplyNested_equals() {
+ boolean equals = JsonCodec.jsonEquals(createDeeplyNestedValue(1),
+ createDeeplyNestedValue(1));
+
+ Assert.assertTrue("Values should be equal", equals);
+ }
+
+ private static JsonValue createDeeplyNestedValue(int leafValue) {
+ JsonObject childObject = Json.createObject();
+ childObject.put("value", leafValue);
+
+ JsonArray childArray = Json.createArray();
+ childArray.set(0, childObject);
+
+ JsonObject value = Json.createObject();
+ value.put("child", childArray);
+ return value;
+ }
+}
diff --git a/server/src/test/java/com/vaadin/server/MockServletConfig.java b/server/src/test/java/com/vaadin/server/MockServletConfig.java
new file mode 100644
index 0000000000..d9d0e4d773
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/MockServletConfig.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2000-2014 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.server;
+
+import java.util.Enumeration;
+import java.util.Properties;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+
+/**
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class MockServletConfig implements ServletConfig {
+
+ private ServletContext context = new MockServletContext();
+ private final Properties initParameters;
+
+ public MockServletConfig() {
+ this(new Properties());
+ }
+
+ public MockServletConfig(Properties initParameters) {
+ this.initParameters = initParameters;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletConfig#getServletName()
+ */
+ @Override
+ public String getServletName() {
+ return "Mock Servlet";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletConfig#getServletContext()
+ */
+ @Override
+ public ServletContext getServletContext() {
+ return context;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletConfig#getInitParameter(java.lang.String)
+ */
+ @Override
+ public String getInitParameter(String name) {
+ return initParameters.getProperty(name);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletConfig#getInitParameterNames()
+ */
+ @Override
+ public Enumeration getInitParameterNames() {
+ return initParameters.propertyNames();
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/server/MockServletContext.java b/server/src/test/java/com/vaadin/server/MockServletContext.java
new file mode 100644
index 0000000000..e9471fc9ee
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/MockServletContext.java
@@ -0,0 +1,569 @@
+/*
+ * Copyright 2000-2014 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.server;
+
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.EventListener;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterRegistration;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRegistration;
+import javax.servlet.ServletRegistration.Dynamic;
+import javax.servlet.SessionCookieConfig;
+import javax.servlet.SessionTrackingMode;
+import javax.servlet.descriptor.JspConfigDescriptor;
+
+/**
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class MockServletContext implements ServletContext {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getContext(java.lang.String)
+ */
+ @Override
+ public ServletContext getContext(String uripath) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getMajorVersion()
+ */
+ @Override
+ public int getMajorVersion() {
+ return 3;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getMinorVersion()
+ */
+ @Override
+ public int getMinorVersion() {
+ return 0;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getMimeType(java.lang.String)
+ */
+ @Override
+ public String getMimeType(String file) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getResourcePaths(java.lang.String)
+ */
+ @Override
+ public Set getResourcePaths(String path) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getResource(java.lang.String)
+ */
+ @Override
+ public URL getResource(String path) throws MalformedURLException {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getResourceAsStream(java.lang.String)
+ */
+ @Override
+ public InputStream getResourceAsStream(String path) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getRequestDispatcher(java.lang.String)
+ */
+ @Override
+ public RequestDispatcher getRequestDispatcher(String path) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getNamedDispatcher(java.lang.String)
+ */
+ @Override
+ public RequestDispatcher getNamedDispatcher(String name) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getServlet(java.lang.String)
+ */
+ @Override
+ public Servlet getServlet(String name) throws ServletException {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getServlets()
+ */
+ @Override
+ public Enumeration getServlets() {
+ return Collections.enumeration(Collections.EMPTY_SET);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getServletNames()
+ */
+ @Override
+ public Enumeration getServletNames() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#log(java.lang.String)
+ */
+ @Override
+ public void log(String msg) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#log(java.lang.Exception,
+ * java.lang.String)
+ */
+ @Override
+ public void log(Exception exception, String msg) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#log(java.lang.String,
+ * java.lang.Throwable)
+ */
+ @Override
+ public void log(String message, Throwable throwable) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getRealPath(java.lang.String)
+ */
+ @Override
+ public String getRealPath(String path) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getServerInfo()
+ */
+ @Override
+ public String getServerInfo() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getInitParameter(java.lang.String)
+ */
+ @Override
+ public String getInitParameter(String name) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getInitParameterNames()
+ */
+ @Override
+ public Enumeration getInitParameterNames() {
+ return Collections.enumeration(Collections.EMPTY_LIST);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getAttribute(java.lang.String)
+ */
+ @Override
+ public Object getAttribute(String name) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getAttributeNames()
+ */
+ @Override
+ public Enumeration getAttributeNames() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#setAttribute(java.lang.String,
+ * java.lang.Object)
+ */
+ @Override
+ public void setAttribute(String name, Object object) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#removeAttribute(java.lang.String)
+ */
+ @Override
+ public void removeAttribute(String name) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getServletContextName()
+ */
+ @Override
+ public String getServletContextName() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getContextPath()
+ */
+ @Override
+ public String getContextPath() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getEffectiveMajorVersion()
+ */
+ @Override
+ public int getEffectiveMajorVersion() {
+ return 3;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getEffectiveMinorVersion()
+ */
+ @Override
+ public int getEffectiveMinorVersion() {
+ return 0;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#setInitParameter(java.lang.String,
+ * java.lang.String)
+ */
+ @Override
+ public boolean setInitParameter(String name, String value) {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#addServlet(java.lang.String,
+ * java.lang.String)
+ */
+ @Override
+ public Dynamic addServlet(String servletName, String className) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#addServlet(java.lang.String,
+ * javax.servlet.Servlet)
+ */
+ @Override
+ public Dynamic addServlet(String servletName, Servlet servlet) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#addServlet(java.lang.String,
+ * java.lang.Class)
+ */
+ @Override
+ public Dynamic addServlet(String servletName,
+ Class<? extends Servlet> servletClass) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#createServlet(java.lang.Class)
+ */
+ @Override
+ public <T extends Servlet> T createServlet(Class<T> clazz)
+ throws ServletException {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * javax.servlet.ServletContext#getServletRegistration(java.lang.String)
+ */
+ @Override
+ public ServletRegistration getServletRegistration(String servletName) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getServletRegistrations()
+ */
+ @Override
+ public Map<String, ? extends ServletRegistration> getServletRegistrations() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#addFilter(java.lang.String,
+ * java.lang.String)
+ */
+ @Override
+ public javax.servlet.FilterRegistration.Dynamic addFilter(
+ String filterName, String className) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#addFilter(java.lang.String,
+ * javax.servlet.Filter)
+ */
+ @Override
+ public javax.servlet.FilterRegistration.Dynamic addFilter(
+ String filterName, Filter filter) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#addFilter(java.lang.String,
+ * java.lang.Class)
+ */
+ @Override
+ public javax.servlet.FilterRegistration.Dynamic addFilter(
+ String filterName, Class<? extends Filter> filterClass) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#createFilter(java.lang.Class)
+ */
+ @Override
+ public <T extends Filter> T createFilter(Class<T> clazz)
+ throws ServletException {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getFilterRegistration(java.lang.String)
+ */
+ @Override
+ public FilterRegistration getFilterRegistration(String filterName) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getFilterRegistrations()
+ */
+ @Override
+ public Map<String, ? extends FilterRegistration> getFilterRegistrations() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getSessionCookieConfig()
+ */
+ @Override
+ public SessionCookieConfig getSessionCookieConfig() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#setSessionTrackingModes(java.util.Set)
+ */
+ @Override
+ public void setSessionTrackingModes(
+ Set<SessionTrackingMode> sessionTrackingModes) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getDefaultSessionTrackingModes()
+ */
+ @Override
+ public Set<SessionTrackingMode> getDefaultSessionTrackingModes() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getEffectiveSessionTrackingModes()
+ */
+ @Override
+ public Set<SessionTrackingMode> getEffectiveSessionTrackingModes() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#addListener(java.lang.String)
+ */
+ @Override
+ public void addListener(String className) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#addListener(java.util.EventListener)
+ */
+ @Override
+ public <T extends EventListener> void addListener(T t) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#addListener(java.lang.Class)
+ */
+ @Override
+ public void addListener(Class<? extends EventListener> listenerClass) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#createListener(java.lang.Class)
+ */
+ @Override
+ public <T extends EventListener> T createListener(Class<T> clazz)
+ throws ServletException {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getJspConfigDescriptor()
+ */
+ @Override
+ public JspConfigDescriptor getJspConfigDescriptor() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getClassLoader()
+ */
+ @Override
+ public ClassLoader getClassLoader() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#declareRoles(java.lang.String[])
+ */
+ @Override
+ public void declareRoles(String... roleNames) {
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/server/MockUIContainingServlet.java b/server/src/test/java/com/vaadin/server/MockUIContainingServlet.java
new file mode 100644
index 0000000000..d54242e31f
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/MockUIContainingServlet.java
@@ -0,0 +1,16 @@
+package com.vaadin.server;
+
+import com.vaadin.ui.UI;
+
+public class MockUIContainingServlet extends UI {
+
+ public static class ServletInUI extends VaadinServlet {
+ // This servlet should automatically be configured to use the
+ // enclosing UI class
+ }
+
+ @Override
+ protected void init(VaadinRequest request) {
+ // Do nothing
+ }
+}
diff --git a/server/src/test/java/com/vaadin/server/MockVaadinSession.java b/server/src/test/java/com/vaadin/server/MockVaadinSession.java
new file mode 100644
index 0000000000..e1def5bcee
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/MockVaadinSession.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2000-2014 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.server;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ *
+ * @author Vaadin Ltd
+ */
+public class MockVaadinSession extends VaadinSession {
+ /*
+ * Used to make sure there's at least one reference to the mock session
+ * while it's locked. This is used to prevent the session from being eaten
+ * by GC in tests where @Before creates a session and sets it as the current
+ * instance without keeping any direct reference to it. This pattern has a
+ * chance of leaking memory if the session is not unlocked in the right way,
+ * but it should be acceptable for testing use.
+ */
+ private static final ThreadLocal<MockVaadinSession> referenceKeeper = new ThreadLocal<MockVaadinSession>();
+
+ public MockVaadinSession(VaadinService service) {
+ super(service);
+ }
+
+ @Override
+ public void close() {
+ super.close();
+ closeCount++;
+ }
+
+ public int getCloseCount() {
+ return closeCount;
+ }
+
+ @Override
+ public Lock getLockInstance() {
+ return lock;
+ }
+
+ @Override
+ public void lock() {
+ super.lock();
+ referenceKeeper.set(this);
+ }
+
+ @Override
+ public void unlock() {
+ super.unlock();
+ referenceKeeper.remove();
+ }
+
+ private int closeCount;
+
+ private ReentrantLock lock = new ReentrantLock();
+}
diff --git a/server/src/test/java/com/vaadin/server/PageTest.java b/server/src/test/java/com/vaadin/server/PageTest.java
new file mode 100644
index 0000000000..b782b1f67d
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/PageTest.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2000-2014 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.server;
+
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.server.Page.BrowserWindowResizeEvent;
+import com.vaadin.server.Page.BrowserWindowResizeListener;
+import com.vaadin.shared.ui.ui.PageState;
+import com.vaadin.ui.UI;
+
+/**
+ *
+ * Tests for {@link Page}
+ *
+ * @author Vaadin Ltd
+ */
+public class PageTest {
+
+ @Test
+ public void removeBrowserWindowResizeListener_listenerIsAttached_listenerRemoved() {
+ Page page = new Page(EasyMock.createMock(UI.class),
+ EasyMock.createMock(PageState.class));
+
+ TestBrowserWindowResizeListener listener = new TestBrowserWindowResizeListener();
+ page.addBrowserWindowResizeListener(listener);
+ page.removeBrowserWindowResizeListener(listener);
+
+ page.updateBrowserWindowSize(0, 0, true);
+
+ Assert.assertFalse("Listener is called after removal",
+ listener.isCalled());
+ }
+
+ @Test
+ public void removeBrowserWindowResizeListener_listenerIsNotAttached_stateIsUpdated() {
+ TestPage page = new TestPage(EasyMock.createMock(UI.class),
+ EasyMock.createMock(PageState.class));
+
+ BrowserWindowResizeListener listener = EasyMock
+ .createMock(BrowserWindowResizeListener.class);
+ page.removeBrowserWindowResizeListener(listener);
+
+ Assert.assertFalse(
+ "Page state 'hasResizeListeners' property has wrong value",
+ page.getState(false).hasResizeListeners);
+ }
+
+ private static class TestPage extends Page {
+
+ public TestPage(UI uI, PageState state) {
+ super(uI, state);
+ }
+
+ @Override
+ protected PageState getState(boolean markAsDirty) {
+ return super.getState(markAsDirty);
+ }
+
+ }
+
+ private static class TestBrowserWindowResizeListener implements
+ BrowserWindowResizeListener {
+
+ @Override
+ public void browserWindowResized(BrowserWindowResizeEvent event) {
+ isCalled = true;
+ }
+
+ public boolean isCalled() {
+ return isCalled;
+ }
+
+ private boolean isCalled;
+
+ }
+}
diff --git a/server/src/test/java/com/vaadin/server/TestAbstractApplicationServletStaticFilesLocation.java b/server/src/test/java/com/vaadin/server/TestAbstractApplicationServletStaticFilesLocation.java
new file mode 100644
index 0000000000..3f940ae0a7
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/TestAbstractApplicationServletStaticFilesLocation.java
@@ -0,0 +1,153 @@
+package com.vaadin.server;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import javax.servlet.http.HttpServletRequest;
+
+import junit.framework.TestCase;
+
+public class TestAbstractApplicationServletStaticFilesLocation extends TestCase {
+
+ VaadinServlet servlet;
+
+ // private Method getStaticFilesLocationMethod;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ servlet = new VaadinServlet();
+ servlet.init(new MockServletConfig());
+ }
+
+ public void testWidgetSetLocation() throws Exception {
+ String location;
+
+ /* SERVLETS */
+ // http://dummy.host:8080/contextpath/servlet
+ // should return . (relative url resolving to /contextpath)
+ location = testLocation("http://dummy.host:8080", "/contextpath",
+ "/servlet", "");
+ assertEquals(".", location);
+
+ // http://dummy.host:8080/contextpath/servlet/
+ // should return ./.. (relative url resolving to /contextpath)
+ location = testLocation("http://dummy.host:8080", "/contextpath",
+ "/servlet", "/");
+ assertEquals("./..", 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 ./../.. (relative url resolving to /contextpath)
+ location = testLocation("http://dummy.host", "/contextpath",
+ "/servlet", "/extra/stuff");
+ assertEquals("./../..", location);
+
+ // http://dummy.host/context/path/servlet/extra/stuff
+ // should return ./../.. (relative url resolving to /context/path)
+ location = testLocation("http://dummy.host", "/context/path",
+ "/servlet", "/extra/stuff");
+ assertEquals("./../..", location);
+
+ /* Include requests */
+ // Include request support dropped with support for portlet1
+ // Might reconsider when JSP integration support is implemented
+ // 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 = servlet.getService().getStaticFileLocation(
+ servlet.createVaadinRequest(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 = servlet.getService().getStaticFileLocation(
+ servlet.createVaadinRequest(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/src/test/java/com/vaadin/server/VaadinGateInRequestTest.java b/server/src/test/java/com/vaadin/server/VaadinGateInRequestTest.java
new file mode 100644
index 0000000000..eda2b3a006
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/VaadinGateInRequestTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2014 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.server;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import com.vaadin.server.VaadinPortlet.VaadinGateInRequest;
+
+public class VaadinGateInRequestTest extends
+ VaadinHttpAndPortletRequestTestBase<VaadinGateInRequest> {
+
+ @Override
+ protected VaadinGateInRequest createSut() {
+
+ VaadinGateInRequest request = new VaadinGateInRequest(portletRequest,
+ vaadinPortletService);
+
+ // Although partial mocking can be considered a code smell,
+ // here it's actually quite useful to mock reflection calls.
+ VaadinGateInRequest spy = spy(request);
+ doReturn(servletRequest).when(spy).getServletRequest(portletRequest);
+
+ return spy;
+ }
+}
diff --git a/server/src/test/java/com/vaadin/server/VaadinHttpAndPortletRequestTestBase.java b/server/src/test/java/com/vaadin/server/VaadinHttpAndPortletRequestTestBase.java
new file mode 100644
index 0000000000..0f7cce5f75
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/VaadinHttpAndPortletRequestTestBase.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2000-2014 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.server;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Enumeration;
+import java.util.Map;
+
+import javax.portlet.PortletRequest;
+import javax.servlet.http.HttpServletRequest;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import com.vaadin.server.VaadinPortlet.VaadinHttpAndPortletRequest;
+import com.vaadin.server.VaadinPortletService;
+
+public abstract class VaadinHttpAndPortletRequestTestBase<T extends VaadinHttpAndPortletRequest> {
+
+ protected VaadinHttpAndPortletRequest sut;
+ protected HttpServletRequest servletRequest;
+ protected PortletRequest portletRequest;
+ protected VaadinPortletService vaadinPortletService;
+
+ protected abstract T createSut();
+
+ @Before
+ public void setup() {
+ portletRequest = mock(PortletRequest.class);
+ vaadinPortletService = mock(VaadinPortletService.class);
+ servletRequest = mock(HttpServletRequest.class);
+
+ sut = createSut();
+ }
+
+ @Test
+ public void parameterIsFetchedFromServletRequest() {
+ when(servletRequest.getParameter("foo")).thenReturn("bar");
+
+ String parameter = sut.getParameter("foo");
+
+ assertThat(parameter, is("bar"));
+ }
+
+ @Test
+ public void originalParameterIsOverridden() {
+ when(servletRequest.getParameter("foo")).thenReturn("braa");
+ when(portletRequest.getParameter("foo")).thenReturn("bar");
+
+ String parameter = sut.getParameter("foo");
+
+ assertThat(parameter, is("bar"));
+ }
+
+ @Test
+ public void remoteAddressIsFetchedFromServletRequest() {
+ when(servletRequest.getRemoteAddr()).thenReturn("foo");
+
+ String remoteAddr = sut.getRemoteAddr();
+
+ assertThat(remoteAddr, is("foo"));
+ }
+
+ @Test
+ public void remoteHostIsFetchedFromServletRequest() {
+ when(servletRequest.getRemoteHost()).thenReturn("foo");
+
+ String remoteHost = sut.getRemoteHost();
+
+ assertThat(remoteHost, is("foo"));
+ }
+
+ @Test
+ public void remotePortIsFetchedFromServletRequest() {
+ when(servletRequest.getRemotePort()).thenReturn(12345);
+
+ int remotePort = sut.getRemotePort();
+
+ assertThat(remotePort, is(12345));
+ }
+
+ @Test
+ public void headerIsFetchedFromServletRequest() {
+ when(servletRequest.getHeader("foo")).thenReturn("bar");
+
+ String header = sut.getHeader("foo");
+
+ assertThat(header, is("bar"));
+ }
+
+ @Test
+ public void headerNamesAreFetchedFromServletRequest() {
+ Enumeration expectedHeaderNames = mock(Enumeration.class);
+ when(servletRequest.getHeaderNames()).thenReturn(expectedHeaderNames);
+
+ Enumeration<String> actualHeaderNames = sut.getHeaderNames();
+
+ assertThat(actualHeaderNames, is(expectedHeaderNames));
+ }
+
+ @Test
+ public void headersAreFetchedFromServletRequest() {
+ Enumeration expectedHeaders = mock(Enumeration.class);
+ when(servletRequest.getHeaders("foo")).thenReturn(expectedHeaders);
+
+ Enumeration<String> actualHeaders = sut.getHeaders("foo");
+
+ assertThat(actualHeaders, is(expectedHeaders));
+ }
+
+ @Test
+ public void parameterMapIsFetchedFromServletRequest() {
+ Map expectedParameterMap = mock(Map.class);
+ when(servletRequest.getParameterMap()).thenReturn(expectedParameterMap);
+
+ Map<String, String[]> actualParameterMap = sut.getParameterMap();
+
+ assertThat(actualParameterMap, is(expectedParameterMap));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/server/VaadinLiferayRequestTest.java b/server/src/test/java/com/vaadin/server/VaadinLiferayRequestTest.java
new file mode 100644
index 0000000000..3024cd652f
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/VaadinLiferayRequestTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2014 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.server;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import com.vaadin.server.VaadinPortlet.VaadinLiferayRequest;
+
+public class VaadinLiferayRequestTest extends
+ VaadinHttpAndPortletRequestTestBase<VaadinLiferayRequest> {
+
+ @Override
+ protected VaadinLiferayRequest createSut() {
+
+ VaadinLiferayRequest request = new VaadinLiferayRequest(portletRequest,
+ vaadinPortletService);
+
+ // Although partial mocking can be considered a code smell,
+ // here it's actually quite useful to mock reflection calls.
+ VaadinLiferayRequest spy = spy(request);
+ doReturn(servletRequest).when(spy).getServletRequest(portletRequest);
+
+ return spy;
+ }
+}
diff --git a/server/src/test/java/com/vaadin/server/VaadinPortletRequestTests.java b/server/src/test/java/com/vaadin/server/VaadinPortletRequestTests.java
new file mode 100644
index 0000000000..bf2b809529
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/VaadinPortletRequestTests.java
@@ -0,0 +1,53 @@
+package com.vaadin.server;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.portlet.PortletPreferences;
+import javax.portlet.PortletRequest;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class VaadinPortletRequestTests {
+
+ private PortletRequest request;
+ private VaadinPortletRequest sut;
+ private VaadinPortletService service;
+ private PortletPreferences preferences;
+
+ @Before
+ public void setup() {
+ request = mock(PortletRequest.class);
+ service = mock(VaadinPortletService.class);
+
+ sut = new VaadinPortletRequest(request, service);
+
+ preferences = mock(PortletPreferences.class);
+ when(request.getPreferences()).thenReturn(preferences);
+ }
+
+ @Test
+ public void portletPreferenceIsFetched() {
+ when(preferences.getValue(eq("foo"), anyString())).thenReturn("bar");
+
+ String value = sut.getPortletPreference("foo");
+
+ assertThat(value, is("bar"));
+ }
+
+ @Test
+ public void defaultValueForPortletPreferenceIsNull() {
+ when(preferences.getValue(anyString(), isNull(String.class)))
+ .thenReturn(null);
+
+ String value = sut.getPortletPreference("foo");
+
+ assertNull(value);
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/server/VaadinPortletServiceTests.java b/server/src/test/java/com/vaadin/server/VaadinPortletServiceTests.java
new file mode 100644
index 0000000000..38f3b85043
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/VaadinPortletServiceTests.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright 2000-2014 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.server;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import com.vaadin.shared.ui.ui.UIConstants;
+import com.vaadin.ui.UI;
+
+public class VaadinPortletServiceTests {
+
+ private VaadinPortletService sut;
+ private VaadinPortletRequest request;
+ private DeploymentConfiguration conf;
+
+ @Before
+ public void setup() throws ServiceException {
+ VaadinPortlet portlet = mock(VaadinPortlet.class);
+ conf = mock(DeploymentConfiguration.class);
+
+ sut = new VaadinPortletService(portlet, conf);
+
+ request = mock(VaadinPortletRequest.class);
+ }
+
+ private void mockFileLocationProperty(String location) {
+ mockPortalProperty(Constants.PORTAL_PARAMETER_VAADIN_RESOURCE_PATH,
+ location);
+ }
+
+ private void mockPortalProperty(String name, String value) {
+ when(request.getPortalProperty(name)).thenReturn(value);
+ }
+
+ private void mockFileLocationPreference(String location) {
+ when(
+ request.getPortletPreference(Constants.PORTAL_PARAMETER_VAADIN_RESOURCE_PATH))
+ .thenReturn(location);
+ }
+
+ private void mockLocationDeploymentConfiguration(String location) {
+ when(
+ conf.getApplicationOrSystemProperty(
+ Constants.PORTAL_PARAMETER_VAADIN_RESOURCE_PATH, null))
+ .thenReturn(location);
+ }
+
+ private String getStaticFileLocation() {
+ return sut.getStaticFileLocation(request);
+ }
+
+ private String getTheme() {
+ return sut.getConfiguredTheme(request);
+ }
+
+ private void mockThemeProperty(String theme) {
+ mockPortalProperty(Constants.PORTAL_PARAMETER_VAADIN_THEME, theme);
+ }
+
+ private void mockWidgetsetProperty(String widgetset) {
+ mockPortalProperty(Constants.PORTAL_PARAMETER_VAADIN_WIDGETSET,
+ widgetset);
+ }
+
+ private void mockWidgetsetConfiguration(String widgetset) {
+ when(conf.getWidgetset(null)).thenReturn(widgetset);
+ }
+
+ @Test
+ public void preferencesOverrideDeploymentConfiguration() {
+ mockFileLocationPreference("prefs");
+ mockLocationDeploymentConfiguration("conf");
+
+ String location = getStaticFileLocation();
+
+ assertThat(location, is("prefs"));
+ }
+
+ @Test
+ public void deploymentConfigurationOverridesProperties() {
+ mockFileLocationPreference(null);
+ mockLocationDeploymentConfiguration("conf");
+ mockFileLocationProperty("props");
+
+ String location = getStaticFileLocation();
+
+ assertThat(location, is("conf"));
+ }
+
+ @Test
+ public void defaultFileLocationIsSet() {
+ mockFileLocationPreference(null);
+ mockLocationDeploymentConfiguration(null);
+ mockFileLocationProperty(null);
+
+ String location = getStaticFileLocation();
+
+ assertThat(location, is("/html"));
+ }
+
+ @Test
+ public void trailingSlashesAreTrimmedFromStaticFileLocation() {
+ mockFileLocationPreference("/content////");
+
+ String staticFileLocation = getStaticFileLocation();
+
+ assertThat(staticFileLocation, is("/content"));
+ }
+
+ @Test
+ public void themeCanBeOverridden() {
+ mockThemeProperty("foobar");
+
+ String theme = getTheme();
+
+ assertThat(theme, is("foobar"));
+ }
+
+ @Test
+ public void defaultThemeIsSet() {
+ mockThemeProperty(null);
+
+ String theme = getTheme();
+
+ assertThat(theme, is(Constants.DEFAULT_THEME_NAME));
+ }
+
+ private String getWidgetset() {
+ return sut.getConfiguredWidgetset(request);
+ }
+
+ @Test
+ public void defaultWidgetsetIsSet() {
+ mockWidgetsetProperty(null);
+ mockWidgetsetConfiguration(null);
+
+ String widgetset = getWidgetset();
+
+ assertThat(widgetset, is(Constants.DEFAULT_WIDGETSET));
+ }
+
+ @Test
+ public void configurationWidgetsetOverridesProperty() {
+ mockWidgetsetProperty("foo");
+ mockWidgetsetConfiguration("bar");
+
+ String widgetset = getWidgetset();
+
+ assertThat(widgetset, is("bar"));
+ }
+
+ @Test
+ public void oldDefaultWidgetsetIsMappedToDefaultWidgetset() {
+ mockWidgetsetConfiguration(null);
+ mockWidgetsetProperty("com.vaadin.portal.gwt.PortalDefaultWidgetSet");
+
+ String widgetset = getWidgetset();
+
+ assertThat(widgetset, is(Constants.DEFAULT_WIDGETSET));
+ }
+
+ @Test
+ public void oldDefaultWidgetSetIsNotMappedToDefaultWidgetset() {
+ mockWidgetsetConfiguration("com.vaadin.portal.gwt.PortalDefaultWidgetSet");
+ mockWidgetsetProperty(null);
+
+ String widgetset = getWidgetset();
+
+ assertThat(widgetset,
+ is("com.vaadin.portal.gwt.PortalDefaultWidgetSet"));
+ }
+
+ @Test
+ public void findUIDoesntThrowNPE() {
+ try {
+ ReentrantLock mockLock = Mockito.mock(ReentrantLock.class);
+ when(mockLock.isHeldByCurrentThread()).thenReturn(true);
+
+ WrappedSession emptyWrappedSession = Mockito
+ .mock(WrappedPortletSession.class);
+ when(emptyWrappedSession.getAttribute("null.lock")).thenReturn(
+ mockLock);
+ VaadinRequest requestWithUIIDSet = Mockito
+ .mock(VaadinRequest.class);
+ when(requestWithUIIDSet.getParameter(UIConstants.UI_ID_PARAMETER))
+ .thenReturn("1");
+ when(requestWithUIIDSet.getWrappedSession()).thenReturn(
+ emptyWrappedSession);
+
+ UI ui = sut.findUI(requestWithUIIDSet);
+ Assert.assertNull("Unset session did not return null", ui);
+ } catch (NullPointerException e) {
+ Assert.fail("findUI threw a NullPointerException");
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/server/VaadinPortletTests.java b/server/src/test/java/com/vaadin/server/VaadinPortletTests.java
new file mode 100644
index 0000000000..f92aa0dcaa
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/VaadinPortletTests.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2000-2014 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.server;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import javax.portlet.PortalContext;
+import javax.portlet.PortletRequest;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.server.VaadinPortlet.VaadinGateInRequest;
+import com.vaadin.server.VaadinPortlet.VaadinLiferayRequest;
+import com.vaadin.server.VaadinPortlet.VaadinWebSpherePortalRequest;
+
+public class VaadinPortletTests {
+
+ private VaadinPortlet sut;
+ private PortletRequest portletRequest;
+ private PortalContext portalContext;
+
+ @Before
+ public void setup() {
+ sut = new VaadinPortlet();
+
+ portletRequest = mock(PortletRequest.class);
+ portalContext = mock(PortalContext.class);
+
+ when(portletRequest.getPortalContext()).thenReturn(portalContext);
+ }
+
+ private void mockPortalInfo(String name) {
+ when(portalContext.getPortalInfo()).thenReturn(name);
+ }
+
+ private VaadinPortletRequest createRequest() {
+ VaadinPortletRequest request = sut.createVaadinRequest(portletRequest);
+ return request;
+ }
+
+ @Test
+ public void gateInRequestIsCreated() {
+ mockPortalInfo("gatein");
+
+ VaadinPortletRequest request = createRequest();
+
+ assertThat(request, instanceOf(VaadinGateInRequest.class));
+ }
+
+ @Test
+ public void liferayRequestIsCreated() {
+ mockPortalInfo("liferay");
+
+ VaadinPortletRequest request = createRequest();
+
+ assertThat(request, instanceOf(VaadinLiferayRequest.class));
+ }
+
+ @Test
+ public void webspherePortalRequestIsCreated() {
+ mockPortalInfo("websphere portal");
+
+ VaadinPortletRequest request = createRequest();
+
+ assertThat(request, instanceOf(VaadinWebSpherePortalRequest.class));
+ }
+
+ @Test
+ public void defaultPortletRequestIsCreated() {
+ mockPortalInfo("foobar");
+
+ VaadinPortletRequest request = createRequest();
+
+ assertThat(request, instanceOf(VaadinPortletRequest.class));
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/server/VaadinServiceTest.java b/server/src/test/java/com/vaadin/server/VaadinServiceTest.java
new file mode 100644
index 0000000000..bd3da6277a
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/VaadinServiceTest.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2000-2014 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.server;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpSessionBindingEvent;
+
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ *
+ * @author Vaadin Ltd
+ */
+public class VaadinServiceTest {
+
+ private class TestSessionDestroyListener implements SessionDestroyListener {
+
+ int callCount = 0;
+
+ @Override
+ public void sessionDestroy(SessionDestroyEvent event) {
+ callCount++;
+ }
+ }
+
+ private String createCriticalNotification(String caption, String message,
+ String details, String url) {
+ return VaadinService.createCriticalNotificationJSON(caption, message,
+ details, url);
+ }
+
+ @Test
+ public void testFireSessionDestroy() throws ServletException {
+ ServletConfig servletConfig = new MockServletConfig();
+ VaadinServlet servlet = new VaadinServlet();
+ servlet.init(servletConfig);
+ VaadinService service = servlet.getService();
+
+ TestSessionDestroyListener listener = new TestSessionDestroyListener();
+
+ service.addSessionDestroyListener(listener);
+
+ MockVaadinSession vaadinSession = new MockVaadinSession(service);
+ service.fireSessionDestroy(vaadinSession);
+ Assert.assertEquals(
+ "'fireSessionDestroy' method doesn't call 'close' for the session",
+ 1, vaadinSession.getCloseCount());
+
+ vaadinSession.valueUnbound(EasyMock
+ .createMock(HttpSessionBindingEvent.class));
+
+ Assert.assertEquals("'fireSessionDestroy' method may not call 'close' "
+ + "method for closing session", 1,
+ vaadinSession.getCloseCount());
+
+ Assert.assertEquals("SessionDestroyListeners not called exactly once",
+ 1, listener.callCount);
+ }
+
+ @Test
+ public void captionIsSetToACriticalNotification() {
+ String notification = createCriticalNotification("foobar", "message",
+ "details", "url");
+
+ assertThat(notification, containsString("\"caption\":\"foobar\""));
+ }
+
+ @Test
+ public void nullCaptionIsSetToACriticalNotification() {
+ String notification = createCriticalNotification(null, "message",
+ "details", "url");
+
+ assertThat(notification, containsString("\"caption\":null"));
+ }
+
+ @Test
+ public void messageWithDetailsIsSetToACriticalNotification() {
+ String notification = createCriticalNotification("caption", "foo",
+ "bar", "url");
+
+ assertThat(notification, containsString("\"details\":\"bar\""));
+ }
+
+ @Test
+ public void nullMessageSentAsNullInACriticalNotification() {
+ String notification = createCriticalNotification("caption", null,
+ "foobar", "url");
+
+ assertThat(notification, containsString("\"message\":null"));
+ }
+
+ @Test
+ public void nullMessageIsSetToACriticalNotification() {
+ String notification = createCriticalNotification("caption", null, null,
+ "url");
+
+ assertThat(notification, containsString("\"message\":null"));
+ }
+
+ @Test
+ public void messageSetToACriticalNotification() {
+ String notification = createCriticalNotification("caption", "foobar",
+ null, "url");
+
+ assertThat(notification, containsString("\"message\":\"foobar\""));
+ }
+
+ @Test
+ public void urlIsSetToACriticalNotification() {
+ String notification = createCriticalNotification("caption", "message",
+ "details", "foobar");
+
+ assertThat(notification, containsString("\"url\":\"foobar\""));
+ }
+
+ @Test
+ public void nullUrlIsSetToACriticalNotification() {
+ String notification = createCriticalNotification("caption", "message",
+ "details", null);
+
+ assertThat(notification, containsString("\"url\":null"));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/server/VaadinServletConfigurationTest.java b/server/src/test/java/com/vaadin/server/VaadinServletConfigurationTest.java
new file mode 100644
index 0000000000..65698d2c44
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/VaadinServletConfigurationTest.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2000-2014 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.server;
+
+import java.util.Properties;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.annotations.VaadinServletConfiguration;
+import com.vaadin.server.DeploymentConfiguration.LegacyProperyToStringMode;
+import com.vaadin.server.MockUIContainingServlet.ServletInUI;
+import com.vaadin.ui.UI;
+
+public class VaadinServletConfigurationTest {
+
+ @Test
+ public void testEnclosingUIClass() throws Exception {
+ ServletInUI servlet = new MockUIContainingServlet.ServletInUI();
+ servlet.init(new MockServletConfig());
+
+ Class<? extends UI> uiClass = new DefaultUIProvider()
+ .getUIClass(new UIClassSelectionEvent(new VaadinServletRequest(
+ EasyMock.createMock(HttpServletRequest.class), servlet
+ .getService())));
+ Assert.assertEquals(MockUIContainingServlet.class, uiClass);
+ }
+
+ @Test
+ public void testValuesFromAnnotation() throws ServletException {
+ TestServlet servlet = new TestServlet();
+ servlet.init(new MockServletConfig());
+ DeploymentConfiguration configuration = servlet.getService()
+ .getDeploymentConfiguration();
+
+ Assert.assertEquals(true, configuration.isProductionMode());
+ Assert.assertEquals(LegacyProperyToStringMode.DISABLED,
+ configuration.getLegacyPropertyToStringMode());
+ Assert.assertEquals(true, configuration.isCloseIdleSessions());
+ Assert.assertEquals(1234, configuration.getHeartbeatInterval());
+ Assert.assertEquals(4321, configuration.getResourceCacheTime());
+
+ Class<? extends UI> uiClass = new DefaultUIProvider()
+ .getUIClass(new UIClassSelectionEvent(new VaadinServletRequest(
+ EasyMock.createMock(HttpServletRequest.class), servlet
+ .getService())));
+ Assert.assertEquals(MockUIContainingServlet.class, uiClass);
+ }
+
+ @Test
+ public void testLegacyEnabledAnnotation() throws ServletException {
+ VaadinServlet servlet = new LegacyPropertyEnabledTestServlet();
+ servlet.init(new MockServletConfig());
+ DeploymentConfiguration configuration = servlet.getService()
+ .getDeploymentConfiguration();
+
+ Assert.assertEquals(LegacyProperyToStringMode.ENABLED,
+ configuration.getLegacyPropertyToStringMode());
+ }
+
+ @Test
+ public void testLegacyWarningAnnotation() throws ServletException {
+ VaadinServlet servlet = new LegacyPropertyWarningTestServlet();
+ servlet.init(new MockServletConfig());
+ DeploymentConfiguration configuration = servlet.getService()
+ .getDeploymentConfiguration();
+
+ Assert.assertEquals(LegacyProperyToStringMode.WARNING,
+ configuration.getLegacyPropertyToStringMode());
+ }
+
+ @Test
+ public void testValuesOverriddenForServlet() throws ServletException {
+ Properties servletInitParams = new Properties();
+ servletInitParams.setProperty("productionMode", "false");
+ servletInitParams.setProperty("heartbeatInterval", "1111");
+
+ TestServlet servlet = new TestServlet();
+ servlet.init(new MockServletConfig(servletInitParams));
+ DeploymentConfiguration configuration = servlet.getService()
+ .getDeploymentConfiguration();
+
+ // Values from servlet init params take precedence
+ Assert.assertEquals(1111, configuration.getHeartbeatInterval());
+ Assert.assertEquals(false, configuration.isProductionMode());
+
+ // Other params are as defined in the annotation
+ Assert.assertEquals(LegacyProperyToStringMode.DISABLED,
+ configuration.getLegacyPropertyToStringMode());
+ Assert.assertEquals(true, configuration.isCloseIdleSessions());
+ Assert.assertEquals(4321, configuration.getResourceCacheTime());
+
+ Class<? extends UI> uiClass = new DefaultUIProvider()
+ .getUIClass(new UIClassSelectionEvent(new VaadinServletRequest(
+ EasyMock.createMock(HttpServletRequest.class), servlet
+ .getService())));
+ Assert.assertEquals(MockUIContainingServlet.class, uiClass);
+ }
+}
+
+@VaadinServletConfiguration(productionMode = true, ui = MockUIContainingServlet.class, closeIdleSessions = true, heartbeatInterval = 1234, resourceCacheTime = 4321)
+class TestServlet extends VaadinServlet {
+
+}
+
+@VaadinServletConfiguration(productionMode = true, ui = MockUIContainingServlet.class, legacyPropertyToStringMode = LegacyProperyToStringMode.WARNING)
+class LegacyPropertyWarningTestServlet extends VaadinServlet {
+
+}
+
+@VaadinServletConfiguration(productionMode = true, ui = MockUIContainingServlet.class, legacyPropertyToStringMode = LegacyProperyToStringMode.ENABLED)
+class LegacyPropertyEnabledTestServlet extends VaadinServlet {
+
+}
diff --git a/server/src/test/java/com/vaadin/server/VaadinServletTest.java b/server/src/test/java/com/vaadin/server/VaadinServletTest.java
new file mode 100644
index 0000000000..566c4ce70a
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/VaadinServletTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2014 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.server;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class VaadinServletTest {
+
+ @Test
+ public void testGetLastPathParameter() {
+ Assert.assertEquals("",
+ VaadinServlet.getLastPathParameter("http://myhost.com"));
+ Assert.assertEquals(";a",
+ VaadinServlet.getLastPathParameter("http://myhost.com;a"));
+ Assert.assertEquals("",
+ VaadinServlet.getLastPathParameter("http://myhost.com/hello"));
+ Assert.assertEquals(";b=c", VaadinServlet
+ .getLastPathParameter("http://myhost.com/hello;b=c"));
+ Assert.assertEquals("",
+ VaadinServlet.getLastPathParameter("http://myhost.com/hello/"));
+ Assert.assertEquals("", VaadinServlet
+ .getLastPathParameter("http://myhost.com/hello;a/"));
+ Assert.assertEquals("", VaadinServlet
+ .getLastPathParameter("http://myhost.com/hello;a=1/"));
+ Assert.assertEquals(";b", VaadinServlet
+ .getLastPathParameter("http://myhost.com/hello/;b"));
+ Assert.assertEquals(";b=1", VaadinServlet
+ .getLastPathParameter("http://myhost.com/hello/;b=1"));
+ Assert.assertEquals(";b=1,c=2", VaadinServlet
+ .getLastPathParameter("http://myhost.com/hello/;b=1,c=2"));
+ Assert.assertEquals("", VaadinServlet
+ .getLastPathParameter("http://myhost.com/hello/;b=1,c=2/"));
+ Assert.assertEquals("", VaadinServlet
+ .getLastPathParameter("http://myhost.com/a;hello/;a/"));
+ Assert.assertEquals("", VaadinServlet
+ .getLastPathParameter("http://myhost.com/a;hello/;a=1/"));
+ Assert.assertEquals(";b", VaadinServlet
+ .getLastPathParameter("http://myhost.com/a;hello/;b"));
+ Assert.assertEquals(";b=1", VaadinServlet
+ .getLastPathParameter("http://myhost.com/a;hello/;b=1"));
+ Assert.assertEquals(";b=1,c=2", VaadinServlet
+ .getLastPathParameter("http://myhost.com/a;hello/;b=1,c=2"));
+ Assert.assertEquals("", VaadinServlet
+ .getLastPathParameter("http://myhost.com/a;hello/;b=1,c=2/"));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/server/VaadinSessionTest.java b/server/src/test/java/com/vaadin/server/VaadinSessionTest.java
new file mode 100644
index 0000000000..85c37d156c
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/VaadinSessionTest.java
@@ -0,0 +1,343 @@
+/*
+ * Copyright 2000-2014 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.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 java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpSessionBindingEvent;
+
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.server.ClientConnector.DetachEvent;
+import com.vaadin.server.ClientConnector.DetachListener;
+import com.vaadin.server.communication.UIInitHandler;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.UI;
+import com.vaadin.util.CurrentInstance;
+
+public class VaadinSessionTest implements Serializable {
+
+ private transient VaadinSession session;
+ private transient VaadinServlet mockServlet;
+ private transient VaadinServletService mockService;
+ private transient ServletConfig mockServletConfig;
+ private transient HttpSession mockHttpSession;
+ private transient WrappedSession mockWrappedSession;
+ private transient VaadinServletRequest vaadinRequest;
+ private transient UI ui;
+ private transient Lock httpSessionLock;
+
+ @Before
+ public void setup() throws Exception {
+ httpSessionLock = new ReentrantLock();
+ mockServletConfig = new MockServletConfig();
+ mockServlet = new VaadinServlet();
+ mockServlet.init(mockServletConfig);
+ mockService = mockServlet.getService();
+
+ mockHttpSession = EasyMock.createMock(HttpSession.class);
+ mockWrappedSession = new WrappedHttpSession(mockHttpSession) {
+ final ReentrantLock lock = new ReentrantLock();
+ {
+ lock.lock();
+ }
+
+ @Override
+ public Object getAttribute(String name) {
+ Object res;
+ try {
+ Thread.sleep(100); // for deadlock testing
+ org.junit.Assert.assertTrue("Deadlock detected",
+ httpSessionLock.tryLock(5, TimeUnit.SECONDS)); // simulates
+ // servlet
+ // container's
+ // session
+ // locking
+ String lockAttribute = mockService.getServiceName()
+ + ".lock";
+ if (lockAttribute.equals(name)) {
+ res = lock;
+ } else if ("com.vaadin.server.VaadinSession.Mock Servlet"
+ .equals(name)) {
+ res = session;
+ } else {
+ res = super.getAttribute(name);
+ }
+ httpSessionLock.unlock();
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ return res;
+ }
+ };
+
+ session = new VaadinSession(mockService);
+ mockService.storeSession(session, mockWrappedSession);
+
+ ui = new MockPageUI();
+ vaadinRequest = new VaadinServletRequest(
+ EasyMock.createMock(HttpServletRequest.class), mockService) {
+ @Override
+ public String getParameter(String name) {
+ if ("theme".equals(name) || "restartApplication".equals(name)
+ || "ignoreRestart".equals(name)
+ || "closeApplication".equals(name)) {
+ return null;
+ } else if (UIInitHandler.BROWSER_DETAILS_PARAMETER.equals(name)) {
+ return "1";
+ }
+ return super.getParameter(name);
+ }
+
+ @Override
+ public String getMethod() {
+ return "POST";
+ }
+
+ @Override
+ public WrappedSession getWrappedSession(boolean allowSessionCreation) {
+ return mockWrappedSession;
+ }
+
+ };
+
+ ui.doInit(vaadinRequest, session.getNextUIid(), null);
+
+ ui.setSession(session);
+ session.addUI(ui);
+
+ }
+
+ /**
+ * This reproduces #14452 situation with deadlock - see diagram
+ */
+ @Test
+ public void testInvalidationDeadlock() {
+
+ // this simulates servlet container's session invalidation from another
+ // thread
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ Thread.sleep(150); // delay selected so that VaadinSession
+ // will be already locked by the main
+ // thread
+ // when we get here
+ httpSessionLock.lock();// simulating servlet container's
+ // session lock
+ mockService.fireSessionDestroy(session);
+ httpSessionLock.unlock();
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }).start();
+
+ try {
+ mockService.findVaadinSession(vaadinRequest);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ @Test
+ public void threadLocalsAfterUnderlyingSessionTimeout()
+ throws InterruptedException {
+
+ final AtomicBoolean detachCalled = new AtomicBoolean(false);
+ ui.addDetachListener(new DetachListener() {
+ @Override
+ public void detach(DetachEvent event) {
+ detachCalled.set(true);
+ Assert.assertEquals(ui, UI.getCurrent());
+ Assert.assertEquals(ui.getPage(), Page.getCurrent());
+ Assert.assertEquals(session, VaadinSession.getCurrent());
+ Assert.assertEquals(mockService, VaadinService.getCurrent());
+ Assert.assertEquals(mockServlet, VaadinServlet.getCurrent());
+ }
+ });
+
+ session.valueUnbound(EasyMock.createMock(HttpSessionBindingEvent.class));
+ mockService.runPendingAccessTasks(session); // as soon as we changed
+ // session.accessSynchronously
+ // to session.access in
+ // VaadinService.fireSessionDestroy,
+ // we need to run the
+ // pending task ourselves
+ Assert.assertTrue(detachCalled.get());
+ }
+
+ @Test
+ public void threadLocalsAfterSessionDestroy() throws InterruptedException {
+ final AtomicBoolean detachCalled = new AtomicBoolean(false);
+ ui.addDetachListener(new DetachListener() {
+ @Override
+ public void detach(DetachEvent event) {
+ detachCalled.set(true);
+ Assert.assertEquals(ui, UI.getCurrent());
+ Assert.assertEquals(ui.getPage(), Page.getCurrent());
+ Assert.assertEquals(session, VaadinSession.getCurrent());
+ Assert.assertEquals(mockService, VaadinService.getCurrent());
+ Assert.assertEquals(mockServlet, VaadinServlet.getCurrent());
+ }
+ });
+ CurrentInstance.clearAll();
+ session.close();
+ mockService.cleanupSession(session);
+ mockService.runPendingAccessTasks(session); // as soon as we changed
+ // session.accessSynchronously
+ // to session.access in
+ // VaadinService.fireSessionDestroy,
+ // we need to run the
+ // pending task ourselves
+ Assert.assertTrue(detachCalled.get());
+ }
+
+ @Test
+ public void testValueUnbound() {
+ MockVaadinSession vaadinSession = new MockVaadinSession(mockService);
+
+ vaadinSession.valueUnbound(EasyMock
+ .createMock(HttpSessionBindingEvent.class));
+ org.junit.Assert.assertEquals(
+ "'valueUnbound' method doesn't call 'close' for the session",
+ 1, vaadinSession.getCloseCount());
+
+ vaadinSession.valueUnbound(EasyMock
+ .createMock(HttpSessionBindingEvent.class));
+
+ org.junit.Assert.assertEquals(
+ "'valueUnbound' method may not call 'close' "
+ + "method for closing session", 1,
+ vaadinSession.getCloseCount());
+ }
+
+ // Can't define as an anonymous class since it would have a reference to
+ // VaadinSessionTest.this which isn't serializable
+ private static class MockPageUI extends UI {
+ Page page = new Page(this, getState(false).pageState) {
+ @Override
+ public void init(VaadinRequest request) {
+ }
+ };
+
+ @Override
+ protected void init(VaadinRequest request) {
+ }
+
+ @Override
+ public Page getPage() {
+ return page;
+ }
+ }
+
+ private static class SerializationTestLabel extends Label {
+ private transient VaadinSession session = VaadinSession.getCurrent();
+
+ private void readObject(ObjectInputStream in) throws IOException,
+ ClassNotFoundException {
+ in.defaultReadObject();
+ session = VaadinSession.getCurrent();
+ }
+ }
+
+ @Test
+ public void threadLocalsWhenDeserializing() throws Exception {
+ VaadinSession.setCurrent(session);
+ session.lock();
+ SerializationTestLabel label = new SerializationTestLabel();
+ Assert.assertEquals("Session should be set when instance is created",
+ session, label.session);
+
+ ui.setContent(label);
+ int uiId = ui.getUIId();
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream out = new ObjectOutputStream(bos);
+ out.writeObject(session);
+ out.close();
+
+ session.unlock();
+
+ CurrentInstance.clearAll();
+
+ ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(
+ bos.toByteArray()));
+
+ VaadinSession deserializedSession = (VaadinSession) in.readObject();
+
+ Assert.assertNull(
+ "Current session shouldn't leak from deserialisation",
+ VaadinSession.getCurrent());
+
+ Assert.assertNotSame("Should get a new session", session,
+ deserializedSession);
+
+ // Restore http session and service instance so the session can be
+ // locked
+ deserializedSession.refreshTransients(mockWrappedSession, mockService);
+ deserializedSession.lock();
+
+ UI deserializedUi = deserializedSession.getUIById(uiId);
+ SerializationTestLabel deserializedLabel = (SerializationTestLabel) deserializedUi
+ .getContent();
+
+ Assert.assertEquals(
+ "Current session should be available in SerializationTestLabel.readObject",
+ deserializedSession, deserializedLabel.session);
+ deserializedSession.unlock();
+ }
+
+ @Test
+ public void lockedDuringSerialization() throws IOException {
+ final AtomicBoolean lockChecked = new AtomicBoolean(false);
+
+ ui.setContent(new Label() {
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ Assert.assertTrue(session.hasLock());
+ lockChecked.set(true);
+ out.defaultWriteObject();
+ }
+ });
+
+ session.unlock();
+ Assert.assertFalse(session.hasLock());
+
+ ObjectOutputStream out = new ObjectOutputStream(
+ new ByteArrayOutputStream());
+ out.writeObject(session);
+
+ Assert.assertFalse(session.hasLock());
+ Assert.assertTrue(lockChecked.get());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/server/VaadinWebSpherePortalRequestTest.java b/server/src/test/java/com/vaadin/server/VaadinWebSpherePortalRequestTest.java
new file mode 100644
index 0000000000..3a4c5c69be
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/VaadinWebSpherePortalRequestTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2014 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.server;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import com.vaadin.server.VaadinPortlet.VaadinWebSpherePortalRequest;
+
+public class VaadinWebSpherePortalRequestTest extends
+ VaadinHttpAndPortletRequestTestBase<VaadinWebSpherePortalRequest> {
+
+ @Override
+ protected VaadinWebSpherePortalRequest createSut() {
+
+ VaadinWebSpherePortalRequest request = new VaadinWebSpherePortalRequest(
+ portletRequest, vaadinPortletService);
+
+ // Although partial mocking can be considered a code smell,
+ // here it's actually quite useful to mock reflection calls.
+ VaadinWebSpherePortalRequest spy = spy(request);
+ doReturn(servletRequest).when(spy).getServletRequest(portletRequest);
+
+ return spy;
+ }
+}
diff --git a/server/src/test/java/com/vaadin/server/communication/AtmospherePushConnectionTest.java b/server/src/test/java/com/vaadin/server/communication/AtmospherePushConnectionTest.java
new file mode 100644
index 0000000000..f9e12ce75f
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/communication/AtmospherePushConnectionTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2000-2014 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.server.communication;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.atmosphere.cpr.AtmosphereResource;
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.server.communication.AtmospherePushConnection.State;
+import com.vaadin.ui.UI;
+
+/**
+ * @author Vaadin Ltd
+ */
+public class AtmospherePushConnectionTest {
+ @Test
+ public void testSerialization() throws Exception {
+
+ UI ui = EasyMock.createNiceMock(UI.class);
+ AtmosphereResource resource = EasyMock
+ .createNiceMock(AtmosphereResource.class);
+
+ AtmospherePushConnection connection = new AtmospherePushConnection(ui);
+ connection.connect(resource);
+
+ Assert.assertEquals(State.CONNECTED, connection.getState());
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ new ObjectOutputStream(baos).writeObject(connection);
+
+ connection = (AtmospherePushConnection) new ObjectInputStream(
+ new ByteArrayInputStream(baos.toByteArray())).readObject();
+
+ Assert.assertEquals(State.DISCONNECTED, connection.getState());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/server/communication/FileUploadHandlerTest.java b/server/src/test/java/com/vaadin/server/communication/FileUploadHandlerTest.java
new file mode 100644
index 0000000000..286163541e
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/communication/FileUploadHandlerTest.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2000-2014 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.server.communication;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import com.vaadin.server.ClientConnector;
+import com.vaadin.server.ServletPortletHelper;
+import com.vaadin.server.StreamVariable;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.VaadinResponse;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.ui.ConnectorTracker;
+import com.vaadin.ui.UI;
+
+public class FileUploadHandlerTest {
+
+ private FileUploadHandler handler;
+ @Mock private VaadinResponse response;
+ @Mock private StreamVariable streamVariable;
+ @Mock private ClientConnector clientConnector;
+ @Mock private VaadinRequest request;
+ @Mock private UI ui;
+ @Mock private ConnectorTracker connectorTracker;
+ @Mock private VaadinSession session;
+ @Mock private OutputStream responseOutput;
+
+ private int uiId = 123;
+ private final String connectorId = "connectorId";
+ private final String variableName = "name";
+ private final String expectedSecurityKey = "key";
+
+ @Before
+ public void setup() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ handler = new FileUploadHandler();
+
+ mockRequest();
+ mockConnectorTracker();
+ mockUi();
+
+ when(clientConnector.isConnectorEnabled()).thenReturn(true);
+ when(streamVariable.getOutputStream()).thenReturn(mock(OutputStream.class));
+ when(response.getOutputStream()).thenReturn(responseOutput);
+ }
+
+ private void mockConnectorTracker() {
+ when(connectorTracker.getSeckey(streamVariable)).thenReturn(expectedSecurityKey);
+ when(connectorTracker.getStreamVariable(connectorId, variableName)).thenReturn(streamVariable);
+ when(connectorTracker.getConnector(connectorId)).thenReturn(clientConnector);
+ }
+
+ private void mockRequest() throws IOException {
+ when(request.getPathInfo()).thenReturn("/" + ServletPortletHelper.UPLOAD_URL_PREFIX + uiId + "/"+ connectorId + "/" + variableName + "/" + expectedSecurityKey);
+ when(request.getInputStream()).thenReturn(createInputStream("foobar"));
+ when(request.getHeader("Content-Length")).thenReturn("6");
+ when(request.getContentType()).thenReturn("foobar");
+ }
+
+ private InputStream createInputStream(final String content) {
+ return new InputStream() {
+ int counter = 0;
+ byte[] msg = content.getBytes();
+
+ @Override
+ public int read() throws IOException {
+ if(counter > msg.length + 1) {
+ throw new AssertionError("-1 was ignored by FileUploadHandler.");
+ }
+
+ if(counter >= msg.length) {
+ counter++;
+ return -1;
+ }
+
+ return msg[counter++];
+ }
+ };
+ }
+
+ private void mockUi() {
+ when(ui.getConnectorTracker()).thenReturn(connectorTracker);
+ when(session.getUIById(uiId)).thenReturn(ui);
+ }
+
+ /**
+ * Tests whether we get infinite loop if InputStream is already read (#10096)
+ */
+ @Test(expected = IOException.class)
+ public void exceptionIsThrownOnUnexpectedEnd() throws IOException {
+ when(request.getInputStream()).thenReturn(createInputStream(""));
+ when(request.getHeader("Content-Length")).thenReturn("1");
+
+ handler.doHandleSimpleMultipartFileUpload(null, request, null, null,
+ null, null, null);
+ }
+
+ @Test
+ public void responseIsSentOnCorrectSecurityKey() throws IOException {
+ when(connectorTracker.getSeckey(streamVariable)).thenReturn(expectedSecurityKey);
+
+ handler.handleRequest(session, request, response);
+
+ verify(responseOutput).close();
+ }
+
+ @Test
+ public void responseIsNotSentOnIncorrectSecurityKey() throws IOException {
+ when(connectorTracker.getSeckey(streamVariable)).thenReturn("another key expected");
+
+ handler.handleRequest(session, request, response);
+
+ verifyZeroInteractions(responseOutput);
+ }
+
+ @Test
+ public void responseIsNotSentOnMissingSecurityKey() throws IOException {
+ when(connectorTracker.getSeckey(streamVariable)).thenReturn(null);
+
+ handler.handleRequest(session, request, response);
+
+ verifyZeroInteractions(responseOutput);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/server/communication/MetadataWriterTest.java b/server/src/test/java/com/vaadin/server/communication/MetadataWriterTest.java
new file mode 100644
index 0000000000..afae14007e
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/communication/MetadataWriterTest.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2000-2014 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.server.communication;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import com.vaadin.server.SystemMessages;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.server.WrappedSession;
+import com.vaadin.ui.UI;
+
+public class MetadataWriterTest {
+
+ private UI ui;
+ private VaadinSession session;
+ private StringWriter writer;
+ private SystemMessages messages;
+
+ @Before
+ public void setup() {
+ ui = Mockito.mock(UI.class);
+ session = Mockito.mock(VaadinSession.class);
+ Mockito.when(ui.getSession()).thenReturn(session);
+ writer = new StringWriter();
+ messages = Mockito.mock(SystemMessages.class);
+ }
+
+ private void disableSessionExpirationMessages(SystemMessages messages) {
+ when(messages.isSessionExpiredNotificationEnabled()).thenReturn(true);
+ when(messages.getSessionExpiredMessage()).thenReturn(null);
+ when(messages.getSessionExpiredCaption()).thenReturn(null);
+ }
+
+ @Test
+ public void writeAsyncTag() throws Exception {
+ new MetadataWriter().write(ui, writer, false, true, messages);
+ Assert.assertEquals("{\"async\":true}", writer.getBuffer().toString());
+ }
+
+ @Test
+ public void writeRepaintTag() throws Exception {
+ new MetadataWriter().write(ui, writer, true, false, messages);
+ Assert.assertEquals("{\"repaintAll\":true}", writer.getBuffer()
+ .toString());
+ }
+
+ @Test
+ public void writeRepaintAndAsyncTag() throws Exception {
+ new MetadataWriter().write(ui, writer, true, true, messages);
+ Assert.assertEquals("{\"repaintAll\":true, \"async\":true}", writer
+ .getBuffer().toString());
+ }
+
+ @Test
+ public void writeRedirectWithExpiredSession() throws Exception {
+ disableSessionExpirationMessages(messages);
+
+ new MetadataWriter().write(ui, writer, false, false, messages);
+ Assert.assertEquals("{}", writer.getBuffer().toString());
+ }
+
+ @Test
+ public void writeRedirectWithActiveSession() throws Exception {
+ WrappedSession wrappedSession = mock(WrappedSession.class);
+ when(session.getSession()).thenReturn(wrappedSession);
+
+ disableSessionExpirationMessages(messages);
+
+ new MetadataWriter().write(ui, writer, false, false, messages);
+ Assert.assertEquals(
+ "{\"timedRedirect\":{\"interval\":15,\"url\":\"\"}}", writer
+ .getBuffer().toString());
+ }
+
+ @Test
+ public void writeAsyncWithSystemMessages() throws IOException {
+ WrappedSession wrappedSession = mock(WrappedSession.class);
+ when(session.getSession()).thenReturn(wrappedSession);
+
+ disableSessionExpirationMessages(messages);
+
+ new MetadataWriter().write(ui, writer, false, true, messages);
+ Assert.assertEquals(
+ "{\"async\":true,\"timedRedirect\":{\"interval\":15,\"url\":\"\"}}",
+ writer.getBuffer().toString());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/CompileTransitionPropertyTest.java b/server/src/test/java/com/vaadin/tests/CompileTransitionPropertyTest.java
new file mode 100644
index 0000000000..337ce19a06
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/CompileTransitionPropertyTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2000-2014 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;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.junit.Test;
+
+import com.vaadin.sass.internal.ScssStylesheet;
+
+/*
+ * This test checks that the transition mixin in valo/bourbon is usable (#15484).
+ */
+public class CompileTransitionPropertyTest {
+
+ @Test
+ public void testCompilation() throws Exception {
+ ScssStylesheet ss = ScssStylesheet
+ .get(getClass().getResource("styles.scss").getFile());
+ ss.compile();
+ // extract the style rules for .my-label
+ String compiled = ss.printState();
+ Pattern pattern = Pattern.compile("(.my-label)(\\s)+(\\{)[^\\}]*");
+ Matcher matcher = pattern.matcher(compiled);
+ assertTrue("Could not find style rules for .my-label.", matcher.find());
+ String elementStyle = matcher.group();
+ elementStyle = elementStyle.replaceFirst("(.my-label)(\\s)+(\\{)(\\s)*",
+ "");
+ // Check that the correct rules are present
+ Pattern p1 = Pattern
+ .compile("transition-property(\\s*):(\\s*)transform(\\s*);");
+ Pattern p2 = Pattern.compile(
+ "-moz-transition-property(\\s*):(\\s*)-moz-transform(\\s*);");
+ Pattern p3 = Pattern.compile(
+ "-webkit-transition-property(\\s*):(\\s*)-webkit-transform(\\s*);");
+ assertTrue("The style 'transition-property: transform' is missing.",
+ p1.matcher(elementStyle).find());
+ assertTrue(
+ "The style '-moz-transition-property: -moz-transform' is missing.",
+ p2.matcher(elementStyle).find());
+ assertTrue(
+ "The style '-webkit-transition-property: -webkit-transform' is missing.",
+ p3.matcher(elementStyle).find());
+ // Check that there are no other styles for .my-label
+ String modifiedStyle = p1.matcher(elementStyle).replaceFirst("");
+ modifiedStyle = p2.matcher(modifiedStyle).replaceFirst("");
+ modifiedStyle = p3.matcher(modifiedStyle).replaceFirst("");
+ // Only whitespace should remain after removing the style rules
+ modifiedStyle = modifiedStyle.replaceAll("(\\s)", "");
+ assertTrue("Unexpected style rules for .my-label: " + modifiedStyle,
+ modifiedStyle.length() == 0);
+ }
+} \ No newline at end of file
diff --git a/server/src/test/java/com/vaadin/tests/VaadinClasses.java b/server/src/test/java/com/vaadin/tests/VaadinClasses.java
new file mode 100644
index 0000000000..b5933bbd10
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/VaadinClasses.java
@@ -0,0 +1,259 @@
+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 org.junit.Test;
+
+import com.vaadin.server.VaadinSession;
+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;
+
+@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 = VaadinSession.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())
+ && !c.isAnonymousClass() && !c.isMemberClass()
+ && !c.isLocalClass()) {
+ 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/src/test/java/com/vaadin/tests/components/draganddropwrapper/DragAndDropWrapperDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/components/draganddropwrapper/DragAndDropWrapperDeclarativeTest.java
new file mode 100644
index 0000000000..a590b3ec1f
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/components/draganddropwrapper/DragAndDropWrapperDeclarativeTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2000-2014 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.components.draganddropwrapper;
+
+import org.junit.Test;
+
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.DragAndDropWrapper;
+import com.vaadin.ui.DragAndDropWrapper.DragStartMode;
+import com.vaadin.ui.declarative.DesignContext;
+
+public class DragAndDropWrapperDeclarativeTest extends
+ DeclarativeTestBase<DragAndDropWrapper> {
+
+ @Test
+ public void testDefaultDnDWrapper() {
+ Button okButton = new Button("OK");
+ String input = "<vaadin-drag-and-drop-wrapper>"
+ + new DesignContext().createElement(okButton)
+ + "</vaadin-drag-and-drop-wrapper>";
+ DragAndDropWrapper wrapper = new DragAndDropWrapper(okButton);
+ testWrite(input, wrapper);
+ testRead(input, wrapper);
+ }
+
+ @Test
+ public void testNoDragImage() {
+ Button okButton = new Button("OK");
+ String input = "<vaadin-drag-and-drop-wrapper drag-start-mode='wrapper'>"
+ + new DesignContext().createElement(okButton)
+ + "</vaadin-drag-and-drop-wrapper>";
+ DragAndDropWrapper wrapper = new DragAndDropWrapper(okButton);
+ wrapper.setDragStartMode(DragStartMode.WRAPPER);
+ testWrite(input, wrapper);
+ testRead(input, wrapper);
+ }
+
+ @Test
+ public void testWithDragImage() {
+ Button dragImage = new Button("Cancel");
+ Button okButton = new Button("OK");
+ String input = "<vaadin-drag-and-drop-wrapper drag-start-mode='component_other'>"
+ + new DesignContext().createElement(okButton)
+ + new DesignContext().createElement(dragImage).attr(
+ ":drag-image", true)
+ + "</vaadin-drag-and-drop-wrapper>";
+ DragAndDropWrapper wrapper = new DragAndDropWrapper(okButton);
+ wrapper.setDragStartMode(DragStartMode.COMPONENT_OTHER);
+ wrapper.setDragImageComponent(dragImage);
+ testWrite(input, wrapper);
+ testRead(input, wrapper);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/components/menubar/MenuBarDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/components/menubar/MenuBarDeclarativeTest.java
new file mode 100644
index 0000000000..321d41152b
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/components/menubar/MenuBarDeclarativeTest.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2000-2014 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.components.menubar;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.server.ExternalResource;
+import com.vaadin.server.ThemeResource;
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.MenuBar;
+import com.vaadin.ui.MenuBar.MenuItem;
+
+/**
+ * Tests declarative support for menu bars.
+ *
+ * @since 7.4
+ * @author Vaadin Ltd
+ */
+public class MenuBarDeclarativeTest extends DeclarativeTestBase<MenuBar> {
+
+ @Test
+ // #16328
+ public void testReadWrite() throws IOException {
+ String design = "<vaadin-menu-bar auto-open tabindex=5>"
+ + "<menu checkable>Save</menu>"
+ + "<menu description='Open a file'>Open</menu>"
+ + "<menu disabled>Close</menu>"
+ + "<menu icon='http://foo.bar/ico.png'>Help</menu>"
+ + "<menu visible='false'>About</menu>"
+ + "<menu>Sub<menu>Item</menu></menu>"
+ + "<menu more>WTF?!</menu>" + "</vaadin-menu-bar>";
+ MenuBar bar = new MenuBar();
+ bar.setAutoOpen(true);
+ bar.setHtmlContentAllowed(true);
+ bar.setTabIndex(5);
+
+ bar.addItem("Save", null).setCheckable(true);
+ bar.addItem("Open", null).setDescription("Open a file");
+ bar.addItem("Close", null).setEnabled(false);
+ bar.addItem("Help", null).setIcon(
+ new ExternalResource("http://foo.bar/ico.png"));
+ bar.addItem("About", null).setVisible(false);
+
+ bar.addItem("Sub", null).addItem("Item", null);
+
+ bar.setMoreMenuItem(bar.new MenuItem("WTF?!", null, null));
+
+ testWrite(design, bar);
+ testRead(design, bar);
+ }
+
+ @Test
+ // #16328
+ public void testTicketSpec1() throws IOException {
+ String design = "<vaadin-menu-bar auto-open plain-text tabindex=5> "
+ + "<menu>File"
+ + "<menu>Save</menu>"
+ + "<menu icon=\"theme://../runo/icons/16/folder.png\">Open</menu>"
+ + "<menu separator />"
+ + "<menu disabled>Exit</menu>"
+ + "<menu visible='false'>Not for everybody</menu>"
+ + "</menu>"
+ + "<menu description=\"This contains many items in sub menus\">Other"
+ + "<menu style-name=\"fancy\">Sub"
+ + "<menu checkable checked>Option 1 - no <b>html</b></menu>"
+ + "<menu checkable>Option 2</menu>"
+ + "<menu checkable>Option 3</menu>" //
+ + "</menu>" //
+ + "</menu>" //
+ + "<menu more icon=\"theme://icon.png\">foo</menu>"
+ + "</vaadin-menu-bar>";
+ // for one reason or another, no component has a correct .equals
+ // implementation, which makes tests a bit annoying
+ MenuBar menuBar = new MenuBar();
+ menuBar.setHtmlContentAllowed(false);
+ menuBar.setTabIndex(5);
+ menuBar.setAutoOpen(true);
+ // File menu
+ MenuItem fileMenu = menuBar.addItem("File", null);
+ fileMenu.addItem("Save", null);
+ fileMenu.addItem("Open", new ThemeResource(
+ "../runo/icons/16/folder.png"), null);
+ fileMenu.addSeparator();
+ fileMenu.addItem("Exit", null).setEnabled(false);
+ fileMenu.addItem("Not for everybody", null).setVisible(false);
+ MenuItem otherMenu = menuBar.addItem("Other", null);
+ otherMenu.setDescription("This contains many items in sub menus");
+ MenuItem subMenu = otherMenu.addItem("Sub", null);
+ subMenu.setStyleName("fancy");
+ MenuItem option1 = subMenu.addItem("Option 1 - no <b>html</b>", null);
+ option1.setCheckable(true);
+ option1.setChecked(true);
+ subMenu.addItem("Option 2", null).setCheckable(true);
+ subMenu.addItem("Option 3", null).setCheckable(true);
+ menuBar.setMoreMenuItem(null);
+ MenuItem moreMenu = menuBar.getMoreMenuItem();
+ moreMenu.setIcon(new ThemeResource("icon.png"));
+ moreMenu.setText("foo");
+ testRead(design, menuBar);
+ testWrite(design, menuBar);
+ }
+
+ @Test
+ // #16328
+ public void testTicketSpec2() throws IOException {
+ String design = "<vaadin-menu-bar>"
+ + "<menu><b>File</b>"
+ + "<menu><font style=\"color: red\">Save</font></menu>"
+ + "<menu icon=\"theme://../runo/icons/16/folder.png\">Open</menu>"
+ + "<menu separator />" + "<menu disabled>Exit</menu>" //
+ + "</menu></vaadin-menu-bar>";
+ MenuBar menuBar = new MenuBar();
+ menuBar.setHtmlContentAllowed(true);
+ MenuItem fileMenu = menuBar.addItem("<b>File</b>", null);
+ fileMenu.addItem("<font style=\"color: red\">Save</font>", null);
+ fileMenu.addItem("Open", new ThemeResource(
+ "../runo/icons/16/folder.png"), null);
+ fileMenu.addSeparator();
+ fileMenu.addItem("Exit", null).setEnabled(false);
+ testRead(design, menuBar);
+ testWrite(design, menuBar);
+ }
+
+ @Override
+ public MenuBar testRead(String design, MenuBar expected) {
+ MenuBar result = super.testRead(design, expected);
+
+ List<MenuItem> expectedMenuItems = expected.getItems();
+ List<MenuItem> actualMenuItems = result.getItems();
+ Assert.assertEquals("Different amount of menu items",
+ expectedMenuItems.size(), actualMenuItems.size());
+
+ for (int i = 0; i < expectedMenuItems.size(); ++i) {
+ compareMenus(expectedMenuItems.get(i), actualMenuItems.get(i));
+ }
+
+ return result;
+ }
+
+ private void compareMenus(MenuItem expected, MenuItem actual) {
+ String baseError = "Error Comparing MenuItem " + expected.getText()
+ + ": ";
+ Assert.assertEquals(baseError + "Visibile", expected.isVisible(),
+ actual.isVisible());
+ Assert.assertEquals(baseError + "Checkable", expected.isCheckable(),
+ actual.isCheckable());
+ Assert.assertEquals(baseError + "Checked", expected.isChecked(),
+ actual.isChecked());
+ Assert.assertEquals(baseError + "Separator", expected.isSeparator(),
+ actual.isSeparator());
+ Assert.assertEquals(baseError + "Enabled", expected.isEnabled(),
+ actual.isEnabled());
+
+ Assert.assertEquals(baseError + "Text", expected.getText(),
+ actual.getText());
+ Assert.assertEquals(baseError + "Description",
+ expected.getDescription(), actual.getDescription());
+ Assert.assertEquals(baseError + "Style Name", expected.getStyleName(),
+ actual.getStyleName());
+
+ if (expected.getIcon() != null) {
+ Assert.assertNotNull(baseError + "Icon was null", actual.getIcon());
+ } else {
+ if (actual.getIcon() != null) {
+ Assert.fail(baseError + "Icon should've been null");
+ }
+ }
+
+ Assert.assertEquals(baseError + "Has Children", expected.hasChildren(),
+ actual.hasChildren());
+ if (expected.hasChildren()) {
+ List<MenuItem> children = expected.getChildren();
+ List<MenuItem> actualChildren = actual.getChildren();
+ Assert.assertEquals(baseError + "Child count", children.size(),
+ actualChildren.size());
+ for (int i = 0; i < children.size(); ++i) {
+ compareMenus(children.get(i), actualChildren.get(i));
+ }
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/bean/Address.java b/server/src/test/java/com/vaadin/tests/data/bean/Address.java
new file mode 100644
index 0000000000..15cdf34ae5
--- /dev/null
+++ b/server/src/test/java/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/src/test/java/com/vaadin/tests/data/bean/AnotherTestEnum.java b/server/src/test/java/com/vaadin/tests/data/bean/AnotherTestEnum.java
new file mode 100644
index 0000000000..fc8f22a947
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/bean/AnotherTestEnum.java
@@ -0,0 +1,16 @@
+package com.vaadin.tests.data.bean;
+
+public enum AnotherTestEnum {
+ ONE("ONE"), TWO("TWO");
+
+ private String id;
+
+ private AnotherTestEnum(String id) {
+ this.id = id;
+ }
+
+ @Override
+ public String toString() {
+ return id;
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/bean/BeanToValidate.java b/server/src/test/java/com/vaadin/tests/data/bean/BeanToValidate.java
new file mode 100644
index 0000000000..034609764f
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/bean/BeanToValidate.java
@@ -0,0 +1,69 @@
+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.Pattern;
+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;
+
+ @Pattern(regexp = "V*", message = "Must start with letter V")
+ @Size(min = 3, max = 6, message = "Must contain 3 - 6 letters")
+ private String nickname;
+
+ 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;
+ }
+
+ public String getNickname() {
+ return nickname;
+ }
+
+ public void setNickname(String nickname) {
+ this.nickname = nickname;
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/bean/BeanWithReadOnlyField.java b/server/src/test/java/com/vaadin/tests/data/bean/BeanWithReadOnlyField.java
new file mode 100644
index 0000000000..77f5613f86
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/bean/BeanWithReadOnlyField.java
@@ -0,0 +1,18 @@
+package com.vaadin.tests.data.bean;
+
+public class BeanWithReadOnlyField {
+ private String readOnlyField;
+ private String writableField;
+
+ public String getWritableField() {
+ return writableField;
+ }
+
+ public void setWritableField(String writableField) {
+ this.writableField = writableField;
+ }
+
+ public String getReadOnlyField() {
+ return readOnlyField;
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/bean/Country.java b/server/src/test/java/com/vaadin/tests/data/bean/Country.java
new file mode 100644
index 0000000000..afdf8dcfa1
--- /dev/null
+++ b/server/src/test/java/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/src/test/java/com/vaadin/tests/data/bean/Person.java b/server/src/test/java/com/vaadin/tests/data/bean/Person.java
new file mode 100644
index 0000000000..f7bad31d0e
--- /dev/null
+++ b/server/src/test/java/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/src/test/java/com/vaadin/tests/data/bean/PersonWithBeanValidationAnnotations.java b/server/src/test/java/com/vaadin/tests/data/bean/PersonWithBeanValidationAnnotations.java
new file mode 100644
index 0000000000..575730d946
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/bean/PersonWithBeanValidationAnnotations.java
@@ -0,0 +1,159 @@
+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.Pattern;
+import javax.validation.constraints.Size;
+
+public class PersonWithBeanValidationAnnotations {
+ @NotNull
+ @Size(min = 5, max = 20)
+ @Pattern(regexp = "A.*")
+ 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/src/test/java/com/vaadin/tests/data/bean/Sex.java b/server/src/test/java/com/vaadin/tests/data/bean/Sex.java
new file mode 100644
index 0000000000..a4e3f20a11
--- /dev/null
+++ b/server/src/test/java/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/src/test/java/com/vaadin/tests/data/bean/TestEnum.java b/server/src/test/java/com/vaadin/tests/data/bean/TestEnum.java
new file mode 100644
index 0000000000..bf6f721052
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/bean/TestEnum.java
@@ -0,0 +1,16 @@
+package com.vaadin.tests.data.bean;
+
+public enum TestEnum {
+ ONE("1"), TWO("2");
+
+ private String id;
+
+ private TestEnum(String id) {
+ this.id = id;
+ }
+
+ @Override
+ public String toString() {
+ return id;
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/converter/AnyEnumToStringConverterTest.java b/server/src/test/java/com/vaadin/tests/data/converter/AnyEnumToStringConverterTest.java
new file mode 100644
index 0000000000..83b4abad3f
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/converter/AnyEnumToStringConverterTest.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2000-2014 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 org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.data.util.converter.Converter;
+import com.vaadin.data.util.converter.ReverseConverter;
+import com.vaadin.tests.data.bean.AnotherTestEnum;
+import com.vaadin.tests.data.bean.TestEnum;
+import com.vaadin.ui.TextField;
+
+public class AnyEnumToStringConverterTest {
+
+ public class AnyEnumToStringConverter implements Converter<Enum, String> {
+
+ public AnyEnumToStringConverter() {
+ }
+
+ @Override
+ public String convertToModel(Enum value,
+ Class<? extends String> targetType, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ return value.toString();
+ }
+
+ @Override
+ public Enum convertToPresentation(String value,
+ Class<? extends Enum> targetType, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ if (value == null) {
+ return null;
+ }
+ for (Enum e : targetType.getEnumConstants()) {
+ if (e.toString().equals(value)) {
+ return e;
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public Class<String> getModelType() {
+ return String.class;
+ }
+
+ @Override
+ public Class<Enum> getPresentationType() {
+ return Enum.class;
+ }
+
+ }
+
+ private AnyEnumToStringConverter converter;
+
+ @Before
+ public void setup() {
+ converter = new AnyEnumToStringConverter();
+ }
+
+ @Test
+ public void nullConversion() {
+ Assert.assertEquals(null, converter.convertToModel(null, null, null));
+ }
+
+ @Test
+ public void enumToStringConversion() {
+ Assert.assertEquals(TestEnum.TWO.toString(),
+ converter.convertToModel(TestEnum.TWO, String.class, null));
+ Assert.assertEquals(AnotherTestEnum.TWO.toString(), converter
+ .convertToModel(AnotherTestEnum.TWO, String.class, null));
+ }
+
+ @Test
+ public void stringToEnumConversion() {
+ Assert.assertEquals(TestEnum.TWO, converter.convertToPresentation(
+ TestEnum.TWO.toString(), TestEnum.class, null));
+ Assert.assertEquals(AnotherTestEnum.TWO, converter
+ .convertToPresentation(AnotherTestEnum.TWO.toString(),
+ AnotherTestEnum.class, null));
+ }
+
+ @Test
+ public void stringToEnumWithField() {
+ TextField tf = new TextField();
+ tf.setConverter(new ReverseConverter(converter));
+ tf.setPropertyDataSource(new ObjectProperty(AnotherTestEnum.TWO));
+ Assert.assertEquals(AnotherTestEnum.TWO.toString(), tf.getValue());
+ tf.setValue(AnotherTestEnum.ONE.toString());
+ Assert.assertEquals(AnotherTestEnum.ONE.toString(), tf.getValue());
+ Assert.assertEquals(AnotherTestEnum.ONE, tf.getConvertedValue());
+ Assert.assertEquals(AnotherTestEnum.ONE, tf.getPropertyDataSource()
+ .getValue());
+
+ tf.setPropertyDataSource(new ObjectProperty(TestEnum.TWO));
+ Assert.assertEquals(TestEnum.TWO.toString(), tf.getValue());
+ tf.setValue(TestEnum.ONE.toString());
+ Assert.assertEquals(TestEnum.ONE.toString(), tf.getValue());
+ Assert.assertEquals(TestEnum.ONE, tf.getConvertedValue());
+ Assert.assertEquals(TestEnum.ONE, tf.getPropertyDataSource().getValue());
+
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/converter/ConverterFactoryTest.java b/server/src/test/java/com/vaadin/tests/data/converter/ConverterFactoryTest.java
new file mode 100644
index 0000000000..a61c0c9986
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/converter/ConverterFactoryTest.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2000-2014 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.data.util.converter.Converter;
+import com.vaadin.data.util.converter.DefaultConverterFactory;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.tests.util.AlwaysLockedVaadinSession;
+import com.vaadin.ui.TextField;
+
+public class ConverterFactoryTest extends TestCase {
+
+ public static class ConvertTo42 implements Converter<String, Integer> {
+
+ @Override
+ public Integer convertToModel(String value,
+ Class<? extends Integer> targetType, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ return 42;
+ }
+
+ @Override
+ public String convertToPresentation(Integer value,
+ Class<? extends String> targetType, 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() {
+ VaadinSession.setCurrent(null);
+ final VaadinSession appWithCustomIntegerConverter = new AlwaysLockedVaadinSession(
+ null);
+ appWithCustomIntegerConverter
+ .setConverterFactory(new ConverterFactory42());
+
+ TextField tf = new TextField("", "123") {
+ @Override
+ public VaadinSession getSession() {
+ return appWithCustomIntegerConverter;
+ }
+ };
+ tf.setConverter(Integer.class);
+ // The application converter always returns 42. Current application is
+ // null
+ assertEquals(42, tf.getConvertedValue());
+ }
+
+ public void testApplicationConverterFactoryForDetachedComponent() {
+ final VaadinSession appWithCustomIntegerConverter = new AlwaysLockedVaadinSession(
+ null);
+ appWithCustomIntegerConverter
+ .setConverterFactory(new ConverterFactory42());
+ VaadinSession.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 VaadinSession fieldAppWithCustomIntegerConverter = new AlwaysLockedVaadinSession(
+ null);
+ fieldAppWithCustomIntegerConverter
+ .setConverterFactory(new ConverterFactory42());
+ VaadinSession.setCurrent(new AlwaysLockedVaadinSession(null));
+
+ TextField tf = new TextField("", "123") {
+ @Override
+ public VaadinSession getSession() {
+ 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/src/test/java/com/vaadin/tests/data/converter/DateToLongConverterTest.java b/server/src/test/java/com/vaadin/tests/data/converter/DateToLongConverterTest.java
new file mode 100644
index 0000000000..d767430cc1
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/converter/DateToLongConverterTest.java
@@ -0,0 +1,21 @@
+package com.vaadin.tests.data.converter;
+
+import java.util.Date;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.util.converter.DateToLongConverter;
+
+public class DateToLongConverterTest extends TestCase {
+
+ DateToLongConverter converter = new DateToLongConverter();
+
+ public void testNullConversion() {
+ assertEquals(null, converter.convertToModel(null, Long.class, null));
+ }
+
+ public void testValueConversion() {
+ assertEquals(Long.valueOf(946677600000l),
+ converter.convertToModel(new Date(100, 0, 1), Long.class, null));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/converter/DateToSqlDateConverterTest.java b/server/src/test/java/com/vaadin/tests/data/converter/DateToSqlDateConverterTest.java
new file mode 100644
index 0000000000..46dca6d13e
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/converter/DateToSqlDateConverterTest.java
@@ -0,0 +1,25 @@
+package com.vaadin.tests.data.converter;
+
+import java.util.Date;
+import java.util.Locale;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.util.converter.DateToSqlDateConverter;
+
+public class DateToSqlDateConverterTest extends TestCase {
+
+ DateToSqlDateConverter converter = new DateToSqlDateConverter();
+
+ public void testNullConversion() {
+ assertEquals(null,
+ converter.convertToModel(null, java.sql.Date.class, null));
+ }
+
+ public void testValueConversion() {
+ Date testDate = new Date(100, 0, 1);
+ long time = testDate.getTime();
+ assertEquals(testDate, converter.convertToModel(
+ new java.sql.Date(time), java.sql.Date.class, Locale.ENGLISH));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/converter/DefaultConverterFactoryTest.java b/server/src/test/java/com/vaadin/tests/data/converter/DefaultConverterFactoryTest.java
new file mode 100644
index 0000000000..047ed8a79f
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/converter/DefaultConverterFactoryTest.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2000-2014 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.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Locale;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.util.converter.DefaultConverterFactory;
+
+public class DefaultConverterFactoryTest {
+
+ private DefaultConverterFactory factory = new DefaultConverterFactory();
+
+ @Test
+ public void stringToBigDecimal() {
+ assertConverter("14", new BigDecimal("14"));
+ }
+
+ @Test
+ public void stringToBigInteger() {
+ assertConverter("14", new BigInteger("14"));
+ }
+
+ @Test
+ public void stringToDouble() {
+ assertConverter("14", new Double("14"));
+ }
+
+ @Test
+ public void stringToFloat() {
+ assertConverter("14", new Float("14"));
+ }
+
+ @Test
+ public void stringToInteger() {
+ assertConverter("14", new Integer("14"));
+ }
+
+ @Test
+ public void stringToLong() {
+ assertConverter("14", new Long("14"));
+ }
+
+ @SuppressWarnings("deprecation")
+ @Test
+ public void stringToDate() {
+ assertConverter("Oct 12, 2014 12:00:00 AM", new Date(2014 - 1900,
+ 10 - 1, 12));
+ }
+
+ @Test
+ public void sqlDateToDate() {
+ long l = 1413071210000L;
+ assertConverter(new java.sql.Date(l), new java.util.Date(l));
+ }
+
+ @SuppressWarnings("deprecation")
+ @Test
+ public void longToDate() {
+ assertConverter(1413061200000L, new Date(2014 - 1900, 10 - 1, 12));
+ }
+
+ public enum Foo {
+ BAR, BAZ;
+ }
+
+ @Test
+ public void stringToEnum() {
+ assertConverter("Bar", Foo.BAR);
+ }
+
+ @Test
+ public void stringToShort() {
+ assertConverter("14", new Short("14"));
+ }
+
+ @Test
+ public void stringToByte() {
+ assertConverter("14", new Byte("14"));
+ }
+
+ private <T, U> void assertConverter(T t, U u) {
+ Class<T> tClass = (Class<T>) t.getClass();
+ Class<U> uClass = (Class<U>) u.getClass();
+
+ U tConvertedToU = factory.createConverter(tClass, uClass)
+ .convertToModel(t, uClass, Locale.ENGLISH);
+ Assert.assertEquals(
+ "Incorrect type of value converted from "
+ + tClass.getSimpleName() + " to "
+ + uClass.getSimpleName(), uClass,
+ tConvertedToU.getClass());
+ Assert.assertEquals(
+ "Incorrect conversion of " + t + " to "
+ + uClass.getSimpleName(), u, tConvertedToU);
+
+ T uConvertedToT = factory.createConverter(uClass, tClass)
+ .convertToModel(u, tClass, Locale.ENGLISH);
+ Assert.assertEquals(
+ "Incorrect type of value converted from "
+ + uClass.getSimpleName() + " to "
+ + tClass.getSimpleName(), tClass,
+ uConvertedToT.getClass());
+ Assert.assertEquals(
+ "Incorrect conversion of " + u + " to "
+ + tClass.getSimpleName(), t, uConvertedToT);
+
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/converter/SpecificEnumToStringConverterTest.java b/server/src/test/java/com/vaadin/tests/data/converter/SpecificEnumToStringConverterTest.java
new file mode 100644
index 0000000000..377998db1e
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/converter/SpecificEnumToStringConverterTest.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2000-2014 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 org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.data.util.converter.Converter;
+import com.vaadin.data.util.converter.ReverseConverter;
+import com.vaadin.tests.data.bean.AnotherTestEnum;
+import com.vaadin.tests.data.bean.TestEnum;
+import com.vaadin.ui.TextField;
+
+public class SpecificEnumToStringConverterTest {
+
+ public class SpecificEnumToStringConverter implements
+ Converter<Enum, String> {
+
+ private Class<? extends Enum> enumClass;
+
+ public SpecificEnumToStringConverter(Class<? extends Enum> enumClass) {
+ this.enumClass = enumClass;
+ }
+
+ @Override
+ public String convertToModel(Enum value,
+ Class<? extends String> targetType, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ return value.toString();
+ }
+
+ @Override
+ public Enum convertToPresentation(String value,
+ Class<? extends Enum> targetType, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ for (Enum e : enumClass.getEnumConstants()) {
+ if (e.toString().equals(value)) {
+ return e;
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public Class<String> getModelType() {
+ return String.class;
+ }
+
+ @Override
+ public Class<Enum> getPresentationType() {
+ return (Class<Enum>) enumClass;
+ }
+
+ }
+
+ SpecificEnumToStringConverter testEnumConverter;
+ SpecificEnumToStringConverter anotherTestEnumConverter;
+
+ @Before
+ public void setup() {
+ testEnumConverter = new SpecificEnumToStringConverter(TestEnum.class);
+ anotherTestEnumConverter = new SpecificEnumToStringConverter(
+ AnotherTestEnum.class);
+ }
+
+ @Test
+ public void nullConversion() {
+ Assert.assertEquals(null,
+ testEnumConverter.convertToModel(null, null, null));
+ }
+
+ @Test
+ public void enumToStringConversion() {
+ Assert.assertEquals(TestEnum.TWO.toString(), testEnumConverter
+ .convertToModel(TestEnum.TWO, String.class, null));
+ }
+
+ @Test
+ public void stringToEnumConversion() {
+ Assert.assertEquals(TestEnum.TWO, testEnumConverter
+ .convertToPresentation(TestEnum.TWO.toString(), TestEnum.class,
+ null));
+ }
+
+ @Test
+ public void stringToEnumWithField() {
+ TextField tf = new TextField();
+ tf.setConverter(new ReverseConverter(anotherTestEnumConverter));
+ tf.setPropertyDataSource(new ObjectProperty(AnotherTestEnum.TWO));
+ Assert.assertEquals(AnotherTestEnum.TWO.toString(), tf.getValue());
+ tf.setValue(AnotherTestEnum.ONE.toString());
+ Assert.assertEquals(AnotherTestEnum.ONE.toString(), tf.getValue());
+ Assert.assertEquals(AnotherTestEnum.ONE, tf.getConvertedValue());
+ Assert.assertEquals(AnotherTestEnum.ONE, tf.getPropertyDataSource()
+ .getValue());
+
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/converter/StringToBigDecimalConverterTest.java b/server/src/test/java/com/vaadin/tests/data/converter/StringToBigDecimalConverterTest.java
new file mode 100644
index 0000000000..06d407c9f4
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/converter/StringToBigDecimalConverterTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2000-2014 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.math.BigDecimal;
+import java.util.Locale;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.util.converter.StringToBigDecimalConverter;
+
+public class StringToBigDecimalConverterTest extends TestCase {
+
+ StringToBigDecimalConverter converter = new StringToBigDecimalConverter();
+
+ public void testNullConversion() {
+ assertEquals(null,
+ converter.convertToModel(null, BigDecimal.class, null));
+ }
+
+ public void testEmptyStringConversion() {
+ assertEquals(null, converter.convertToModel("", BigDecimal.class, null));
+ }
+
+ public void testValueParsing() {
+ BigDecimal converted = converter.convertToModel("10", BigDecimal.class,
+ null);
+ BigDecimal expected = new BigDecimal(10);
+ assertEquals(expected, converted);
+ }
+
+ public void testValueFormatting() {
+ BigDecimal bd = new BigDecimal(12.5);
+ String expected = "12,5";
+
+ String converted = converter.convertToPresentation(bd, String.class,
+ Locale.GERMAN);
+ assertEquals(expected, converted);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/converter/StringToBigIntegerConverterTest.java b/server/src/test/java/com/vaadin/tests/data/converter/StringToBigIntegerConverterTest.java
new file mode 100644
index 0000000000..057017790d
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/converter/StringToBigIntegerConverterTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2014 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.math.BigInteger;
+import java.util.Locale;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.util.converter.StringToBigIntegerConverter;
+
+public class StringToBigIntegerConverterTest extends TestCase {
+
+ StringToBigIntegerConverter converter = new StringToBigIntegerConverter();
+
+ public void testNullConversion() {
+ assertEquals("Null value was converted incorrectly", null,
+ converter.convertToModel(null, BigInteger.class, null));
+ }
+
+ public void testEmptyStringConversion() {
+ assertEquals("Empty value was converted incorrectly", null,
+ converter.convertToModel("", BigInteger.class, null));
+ }
+
+ public void testValueParsing() {
+ String bigInt = "1180591620717411303424"; // 2^70 > 2^63 - 1
+ BigInteger converted = converter.convertToModel(bigInt,
+ BigInteger.class, null);
+ BigInteger expected = new BigInteger(bigInt);
+ assertEquals("Value bigger than max long was converted incorrectly",
+ expected, converted);
+ }
+
+ public void testValueFormatting() {
+ BigInteger bd = new BigInteger("1000");
+ String expected = "1.000";
+
+ String converted = converter.convertToPresentation(bd, String.class,
+ Locale.GERMAN);
+ assertEquals("Value with specific locale was converted incorrectly",
+ expected, converted);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/converter/StringToBooleanConverterTest.java b/server/src/test/java/com/vaadin/tests/data/converter/StringToBooleanConverterTest.java
new file mode 100644
index 0000000000..6e81af97a3
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/converter/StringToBooleanConverterTest.java
@@ -0,0 +1,57 @@
+package com.vaadin.tests.data.converter;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.util.converter.StringToBooleanConverter;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+public class StringToBooleanConverterTest extends TestCase {
+
+ StringToBooleanConverter converter = new StringToBooleanConverter();
+ StringToBooleanConverter yesNoConverter = new StringToBooleanConverter("yes","no");
+ StringToBooleanConverter localeConverter = new StringToBooleanConverter() {
+ @Override
+ public String getFalseString(Locale locale) {
+ return SimpleDateFormat.getDateInstance(SimpleDateFormat.LONG,locale).format(new Date(3000000000000L));
+ }
+
+ @Override
+ public String getTrueString(Locale locale) {
+ return SimpleDateFormat.getDateInstance(SimpleDateFormat.LONG,locale).format(new Date(2000000000000L));
+ }
+ };
+
+ public void testNullConversion() {
+ assertEquals(null, converter.convertToModel(null, Boolean.class, null));
+ }
+
+ public void testEmptyStringConversion() {
+ assertEquals(null, converter.convertToModel("", Boolean.class, null));
+ }
+
+ public void testValueConversion() {
+ assertTrue(converter.convertToModel("true", Boolean.class, null));
+ assertFalse(converter.convertToModel("false", Boolean.class, null));
+ }
+
+ public void testYesNoValueConversion() {
+ assertTrue(yesNoConverter.convertToModel("yes", Boolean.class, null));
+ assertFalse(yesNoConverter.convertToModel("no", Boolean.class, null));
+
+ assertEquals("yes", yesNoConverter.convertToPresentation(true, String.class, null));
+ assertEquals("no", yesNoConverter.convertToPresentation(false, String.class, null));
+ }
+
+
+ public void testLocale() {
+ assertEquals("May 18, 2033", localeConverter.convertToPresentation(true, String.class, Locale.US));
+ assertEquals("January 24, 2065", localeConverter.convertToPresentation(false, String.class, Locale.US));
+
+ assertEquals("18. Mai 2033", localeConverter.convertToPresentation(true, String.class, Locale.GERMANY));
+ assertEquals("24. Januar 2065", localeConverter.convertToPresentation(false, String.class, Locale.GERMANY));
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/converter/StringToByteConverterTest.java b/server/src/test/java/com/vaadin/tests/data/converter/StringToByteConverterTest.java
new file mode 100644
index 0000000000..3859d03cc3
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/converter/StringToByteConverterTest.java
@@ -0,0 +1,69 @@
+package com.vaadin.tests.data.converter;
+
+import junit.framework.TestCase;
+
+import org.junit.Assert;
+
+import com.vaadin.data.util.converter.Converter;
+import com.vaadin.data.util.converter.Converter.ConversionException;
+import com.vaadin.data.util.converter.ReverseConverter;
+import com.vaadin.data.util.converter.StringToByteConverter;
+
+public class StringToByteConverterTest extends TestCase {
+
+ StringToByteConverter converter = new StringToByteConverter();
+ Converter<Byte, String> reverseConverter = new ReverseConverter<Byte, String>(
+ converter);
+
+ public void testNullConversion() {
+ assertEquals("Null value was converted incorrectly", null,
+ converter.convertToModel(null, Byte.class, null));
+ }
+
+ public void testReverseNullConversion() {
+ assertEquals("Null value reversely was converted incorrectly", null,
+ reverseConverter.convertToModel(null, String.class, null));
+ }
+
+ public void testEmptyStringConversion() {
+ assertEquals("Empty value was converted incorrectly", null,
+ converter.convertToModel("", Byte.class, null));
+ }
+
+ public void testValueConversion() {
+ assertEquals("Byte value was converted incorrectly",
+ Byte.valueOf((byte) 10),
+ converter.convertToModel("10", Byte.class, null));
+ }
+
+ public void testReverseValueConversion() {
+ assertEquals("Byte value reversely was converted incorrectly",
+ reverseConverter.convertToModel((byte) 10, String.class, null),
+ "10");
+ }
+
+ public void testExtremeByteValueConversion() {
+ byte b = converter.convertToModel("127", Byte.class, null);
+ Assert.assertEquals(Byte.MAX_VALUE, b);
+ b = converter.convertToModel("-128", Byte.class, null);
+ assertEquals("Min byte value was converted incorrectly",
+ Byte.MIN_VALUE, b);
+ }
+
+ public void testValueOutOfRange() {
+ Double[] values = new Double[] { Byte.MAX_VALUE * 2.0,
+ Byte.MIN_VALUE * 2.0, Long.MAX_VALUE * 2.0,
+ Long.MIN_VALUE * 2.0 };
+
+ boolean accepted = false;
+ for (Number value : values) {
+ try {
+ converter.convertToModel(String.format("%.0f", value),
+ Byte.class, null);
+ accepted = true;
+ } catch (ConversionException expected) {
+ }
+ }
+ assertFalse("Accepted value outside range of int", accepted);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/converter/StringToCollectionConverterTest.java b/server/src/test/java/com/vaadin/tests/data/converter/StringToCollectionConverterTest.java
new file mode 100644
index 0000000000..4f2dc1df81
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/converter/StringToCollectionConverterTest.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2000-2014 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.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import java.util.Vector;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.util.converter.StringToCollectionConverter;
+import com.vaadin.data.util.converter.StringToCollectionConverter.CollectionFactory;
+import com.vaadin.data.util.converter.StringToEnumConverter;
+import com.vaadin.data.util.converter.StringToIntegerConverter;
+
+/**
+ * Tests for {@link StringToCollectionConverter}.
+ *
+ * @author Vaadin Ltd
+ */
+public class StringToCollectionConverterTest {
+
+ @Test
+ public void convertToModel_defaultCtor() {
+ StringToCollectionConverter converter = new StringToCollectionConverter();
+ Collection<?> model = converter.convertToModel("a, b, c", List.class,
+ null);
+ Assert.assertTrue("Unexpected model class", model instanceof ArrayList);
+ Iterator<?> iterator = model.iterator();
+ Assert.assertEquals("Incorrect fist token", "a", iterator.next());
+ Assert.assertEquals("Incorrect second token", "b", iterator.next());
+ Assert.assertEquals("Incorrect third token", "c", iterator.next());
+ }
+
+ @Test
+ public void convertToModel_customDelimiter() {
+ StringToCollectionConverter converter = new StringToCollectionConverter(
+ "x");
+ Collection<?> model = converter.convertToModel("axbxc", List.class,
+ null);
+ Assert.assertTrue("Unexpected model class", model instanceof ArrayList);
+ Iterator<?> iterator = model.iterator();
+ Assert.assertEquals("Incorrect fist token", "a", iterator.next());
+ Assert.assertEquals("Incorrect second token", "b", iterator.next());
+ Assert.assertEquals("Incorrect third token", "c", iterator.next());
+ }
+
+ @Test
+ public void convertToModel_customConverter() {
+ StringToCollectionConverter converter = new StringToCollectionConverter(
+ ",", new StringToIntegerConverter(), Integer.class);
+ Collection<?> model = converter.convertToModel("6,2,5", List.class,
+ null);
+ Assert.assertTrue("Unexpected model class", model instanceof ArrayList);
+ Iterator<?> iterator = model.iterator();
+ Assert.assertEquals("Incorrect fist token", 6, iterator.next());
+ Assert.assertEquals("Incorrect second token", 2, iterator.next());
+ Assert.assertEquals("Incorrect third token", 5, iterator.next());
+ }
+
+ @Test
+ public void convertToModel_setAsCollection() {
+ StringToCollectionConverter converter = new StringToCollectionConverter(
+ " ", new StringToEnumConverter(), TestEnum.class);
+ Collection<?> model = converter
+ .convertToModel("Z X Y", Set.class, null);
+ Assert.assertTrue("Unexpected model class", model instanceof HashSet);
+ EnumSet<TestEnum> set = EnumSet.allOf(TestEnum.class);
+ set.removeAll(model);
+ Assert.assertTrue("Some values are not in resutling collection",
+ set.isEmpty());
+ }
+
+ @Test
+ public void convertToModel_customFactory() {
+ CollectionFactory factory = new CollectionFactory() {
+
+ @Override
+ public Collection<?> createCollection(
+ Class<? extends Collection> type) {
+ return new Vector();
+ }
+ };
+ StringToCollectionConverter converter = new StringToCollectionConverter(
+ ", ", null, String.class, factory);
+ Collection<?> model = converter.convertToModel("a, b, c",
+ Collection.class, null);
+ Assert.assertTrue("Unexpected model class", model instanceof Vector);
+ Iterator<?> iterator = model.iterator();
+ Assert.assertEquals("Incorrect fist token", "a", iterator.next());
+ Assert.assertEquals("Incorrect second token", "b", iterator.next());
+ Assert.assertEquals("Incorrect third token", "c", iterator.next());
+ }
+
+ @Test
+ public void convertToPresentation_default() {
+ StringToCollectionConverter converter = new StringToCollectionConverter();
+ String presentation = converter.convertToPresentation(
+ Arrays.asList("a", "b", "c"), String.class, null);
+
+ Assert.assertEquals("a, b, c", presentation);
+ }
+
+ @Test
+ public void convertToPresentation_customDelimiter() {
+ StringToCollectionConverter converter = new StringToCollectionConverter(
+ "x");
+ String presentation = converter.convertToPresentation(
+ Arrays.asList("a", "b", "c"), String.class, null);
+
+ Assert.assertEquals("axbxc", presentation);
+ }
+
+ @Test
+ public void convertToPresentation_customConverter() {
+ StringToCollectionConverter converter = new StringToCollectionConverter(
+ ",", new StringToEnumConverter(), TestEnum.class);
+ String presentation = converter.convertToPresentation(
+ Arrays.asList(TestEnum.Z, TestEnum.Y), String.class, null);
+
+ Assert.assertEquals("Z,Y", presentation);
+ }
+
+ @Test
+ public void convertToModel_singleItem() {
+ StringToCollectionConverter converter = new StringToCollectionConverter();
+ Collection<?> model = converter.convertToModel("a", List.class, null);
+ Iterator<?> iterator = model.iterator();
+ Assert.assertEquals("Incorrect fist token", "a", iterator.next());
+ Assert.assertFalse("More than one item detected after conversation",
+ iterator.hasNext());
+ }
+
+ @Test
+ public void convertToModel_null() {
+ StringToCollectionConverter converter = new StringToCollectionConverter();
+ Assert.assertNull(converter.convertToModel(null, ArrayList.class,
+ Locale.ENGLISH));
+ }
+
+ @Test
+ public void convertToPresentation_null() {
+ StringToCollectionConverter converter = new StringToCollectionConverter();
+ Assert.assertNull(converter.convertToPresentation(null, String.class,
+ Locale.ENGLISH));
+ }
+
+ public enum TestEnum {
+ X, Y, Z;
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/converter/StringToDateConverterTest.java b/server/src/test/java/com/vaadin/tests/data/converter/StringToDateConverterTest.java
new file mode 100644
index 0000000000..16008d89c2
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/converter/StringToDateConverterTest.java
@@ -0,0 +1,26 @@
+package com.vaadin.tests.data.converter;
+
+import java.util.Date;
+import java.util.Locale;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.util.converter.StringToDateConverter;
+
+public class StringToDateConverterTest extends TestCase {
+
+ StringToDateConverter converter = new StringToDateConverter();
+
+ public void testNullConversion() {
+ assertEquals(null, converter.convertToModel(null, Date.class, null));
+ }
+
+ public void testEmptyStringConversion() {
+ assertEquals(null, converter.convertToModel("", Date.class, null));
+ }
+
+ public void testValueConversion() {
+ assertEquals(new Date(100, 0, 1), converter.convertToModel(
+ "Jan 1, 2000 12:00:00 AM", Date.class, Locale.ENGLISH));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/converter/StringToDoubleConverterTest.java b/server/src/test/java/com/vaadin/tests/data/converter/StringToDoubleConverterTest.java
new file mode 100644
index 0000000000..7054587009
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/converter/StringToDoubleConverterTest.java
@@ -0,0 +1,22 @@
+package com.vaadin.tests.data.converter;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.util.converter.StringToDoubleConverter;
+
+public class StringToDoubleConverterTest extends TestCase {
+
+ StringToDoubleConverter converter = new StringToDoubleConverter();
+
+ public void testNullConversion() {
+ assertEquals(null, converter.convertToModel(null, Double.class, null));
+ }
+
+ public void testEmptyStringConversion() {
+ assertEquals(null, converter.convertToModel("", Double.class, null));
+ }
+
+ public void testValueConversion() {
+ assertEquals(10.0, converter.convertToModel("10", Double.class, null));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/converter/StringToEnumConverterTest.java b/server/src/test/java/com/vaadin/tests/data/converter/StringToEnumConverterTest.java
new file mode 100644
index 0000000000..6660ecc9d5
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/converter/StringToEnumConverterTest.java
@@ -0,0 +1,135 @@
+package com.vaadin.tests.data.converter;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.util.converter.Converter;
+import com.vaadin.data.util.converter.Converter.ConversionException;
+import com.vaadin.data.util.converter.ReverseConverter;
+import com.vaadin.data.util.converter.StringToEnumConverter;
+
+public class StringToEnumConverterTest {
+
+ public static enum FooEnum {
+ VALUE1, SOME_VALUE, FOO_BAR_BAZ, Bar, nonStandardCase, _HUGH;
+ }
+
+ public static enum EnumWithCustomToString {
+ ONE, TWO, THREE;
+
+ @Override
+ public String toString() {
+ return "case " + (ordinal() + 1);
+ }
+ }
+
+ public static enum EnumWithAmbigousToString {
+ FOO, FOOBAR, FOO_BAR;
+
+ @Override
+ public String toString() {
+ return name().replaceAll("_", "");
+ }
+ }
+
+ StringToEnumConverter converter = new StringToEnumConverter();
+ Converter<Enum, String> reverseConverter = new ReverseConverter<Enum, String>(
+ converter);
+
+ private String convertToString(Enum value) {
+ return converter.convertToPresentation(value, String.class, null);
+ }
+
+ public Enum convertToEnum(String string, Class<? extends Enum> type) {
+ return converter.convertToModel(string, type, null);
+ }
+
+ @Test
+ public void testEmptyStringConversion() {
+ Assert.assertEquals(null,
+ converter.convertToModel("", Enum.class, null));
+ }
+
+ @Test
+ public void testInvalidEnumClassConversion() {
+ try {
+ converter.convertToModel("Foo", Enum.class, null);
+ Assert.fail("No exception thrown");
+ } catch (ConversionException e) {
+ // OK
+ }
+ }
+
+ @Test
+ public void testNullConversion() {
+ Assert.assertEquals(null,
+ converter.convertToModel(null, Enum.class, null));
+ }
+
+ @Test
+ public void testReverseNullConversion() {
+ Assert.assertEquals(null,
+ reverseConverter.convertToModel(null, String.class, null));
+ }
+
+ @Test
+ public void testValueConversion() {
+ Assert.assertEquals(FooEnum.VALUE1,
+ converter.convertToModel("Value1", FooEnum.class, null));
+ Assert.assertEquals(FooEnum.SOME_VALUE,
+ converter.convertToModel("Some value", FooEnum.class, null));
+ Assert.assertEquals(FooEnum.FOO_BAR_BAZ,
+ converter.convertToModel("Foo bar baz", FooEnum.class, null));
+ Assert.assertEquals(FooEnum.Bar,
+ converter.convertToModel("Bar", FooEnum.class, null));
+ Assert.assertEquals(FooEnum.nonStandardCase, converter.convertToModel(
+ "Nonstandardcase", FooEnum.class, null));
+ Assert.assertEquals(FooEnum._HUGH,
+ converter.convertToModel("_hugh", FooEnum.class, null));
+ }
+
+ @Test
+ public void testReverseValueConversion() {
+ Assert.assertEquals("Value1", reverseConverter.convertToModel(
+ FooEnum.VALUE1, String.class, null));
+ Assert.assertEquals("Some value", reverseConverter.convertToModel(
+ FooEnum.SOME_VALUE, String.class, null));
+ Assert.assertEquals("Foo bar baz", reverseConverter.convertToModel(
+ FooEnum.FOO_BAR_BAZ, String.class, null));
+ Assert.assertEquals("Bar", reverseConverter.convertToModel(FooEnum.Bar,
+ String.class, null));
+ Assert.assertEquals("Nonstandardcase", reverseConverter.convertToModel(
+ FooEnum.nonStandardCase, String.class, null));
+ Assert.assertEquals("_hugh", reverseConverter.convertToModel(
+ FooEnum._HUGH, String.class, null));
+
+ }
+
+ @Test
+ public void preserveFormattingWithCustomToString() {
+ for (EnumWithCustomToString e : EnumWithCustomToString.values()) {
+ Assert.assertEquals(e.toString(), convertToString(e));
+ }
+ }
+
+ @Test
+ public void findEnumWithCustomToString() {
+ for (EnumWithCustomToString e : EnumWithCustomToString.values()) {
+ Assert.assertSame(e,
+ convertToEnum(e.toString(), EnumWithCustomToString.class));
+ Assert.assertSame(e,
+ convertToEnum(e.name(), EnumWithCustomToString.class));
+ }
+ }
+
+ @Test
+ public void unambigousValueInEnumWithAmbigous_succeed() {
+ Assert.assertSame(EnumWithAmbigousToString.FOO,
+ convertToEnum("foo", EnumWithAmbigousToString.class));
+ }
+
+ @Test(expected = ConversionException.class)
+ public void ambigousValue_throws() {
+ convertToEnum("foobar", EnumWithAmbigousToString.class);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/converter/StringToFloatConverterTest.java b/server/src/test/java/com/vaadin/tests/data/converter/StringToFloatConverterTest.java
new file mode 100644
index 0000000000..86319e641c
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/converter/StringToFloatConverterTest.java
@@ -0,0 +1,23 @@
+package com.vaadin.tests.data.converter;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.util.converter.StringToFloatConverter;
+
+public class StringToFloatConverterTest extends TestCase {
+
+ StringToFloatConverter converter = new StringToFloatConverter();
+
+ public void testNullConversion() {
+ assertEquals(null, converter.convertToModel(null, Float.class, null));
+ }
+
+ public void testEmptyStringConversion() {
+ assertEquals(null, converter.convertToModel("", Float.class, null));
+ }
+
+ public void testValueConversion() {
+ assertEquals(Float.valueOf(10),
+ converter.convertToModel("10", Float.class, null));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/converter/StringToIntegerConverterTest.java b/server/src/test/java/com/vaadin/tests/data/converter/StringToIntegerConverterTest.java
new file mode 100644
index 0000000000..0076f2c9d1
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/converter/StringToIntegerConverterTest.java
@@ -0,0 +1,41 @@
+package com.vaadin.tests.data.converter;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.util.converter.Converter.ConversionException;
+import com.vaadin.data.util.converter.StringToIntegerConverter;
+
+public class StringToIntegerConverterTest extends TestCase {
+
+ StringToIntegerConverter converter = new StringToIntegerConverter();
+
+ public void testNullConversion() {
+ assertEquals(null, converter.convertToModel(null, Integer.class, null));
+ }
+
+ public void testEmptyStringConversion() {
+ assertEquals(null, converter.convertToModel("", Integer.class, null));
+ }
+
+ public void testValueOutOfRange() {
+ Double[] values = new Double[] { Integer.MAX_VALUE * 2.0,
+ Integer.MIN_VALUE * 2.0, Long.MAX_VALUE * 2.0,
+ Long.MIN_VALUE * 2.0 };
+
+ boolean accepted = false;
+ for (Number value : values) {
+ try {
+ converter.convertToModel(String.format("%.0f", value),
+ Integer.class, null);
+ accepted = true;
+ } catch (ConversionException expected) {
+ }
+ }
+ assertFalse("Accepted value outside range of int", accepted);
+ }
+
+ public void testValueConversion() {
+ assertEquals(Integer.valueOf(10),
+ converter.convertToModel("10", Integer.class, null));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/converter/StringToLongConverterTest.java b/server/src/test/java/com/vaadin/tests/data/converter/StringToLongConverterTest.java
new file mode 100644
index 0000000000..989dbcbbf5
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/converter/StringToLongConverterTest.java
@@ -0,0 +1,69 @@
+package com.vaadin.tests.data.converter;
+
+import java.util.Locale;
+
+import junit.framework.TestCase;
+
+import org.junit.Assert;
+
+import com.vaadin.data.util.converter.Converter;
+import com.vaadin.data.util.converter.ReverseConverter;
+import com.vaadin.data.util.converter.StringToLongConverter;
+
+public class StringToLongConverterTest extends TestCase {
+
+ StringToLongConverter converter = new StringToLongConverter();
+ Converter<Long, String> reverseConverter = new ReverseConverter<Long, String>(
+ converter);
+
+ public void testNullConversion() {
+ assertEquals(null, converter.convertToModel(null, Long.class, null));
+ }
+
+ public void testReverseNullConversion() {
+ assertEquals(null,
+ reverseConverter.convertToModel(null, String.class, null));
+ }
+
+ public void testEmptyStringConversion() {
+ assertEquals(null, converter.convertToModel("", Long.class, null));
+ }
+
+ public void testValueConversion() {
+ assertEquals(Long.valueOf(10),
+ converter.convertToModel("10", Long.class, null));
+ }
+
+ public void testReverseValueConversion() {
+ assertEquals(reverseConverter.convertToModel(10L, String.class, null),
+ "10");
+ }
+
+ public void testExtremeLongValueConversion() {
+ long l = converter.convertToModel("9223372036854775807", Long.class,
+ null);
+ Assert.assertEquals(Long.MAX_VALUE, l);
+ l = converter.convertToModel("-9223372036854775808", Long.class, null);
+ assertEquals(Long.MIN_VALUE, l);
+ }
+
+ public void testExtremeReverseLongValueConversion() {
+ String str = reverseConverter.convertToModel(Long.MAX_VALUE,
+ String.class, Locale.ENGLISH);
+ Assert.assertEquals("9,223,372,036,854,775,807", str);
+ str = reverseConverter.convertToModel(Long.MIN_VALUE, String.class,
+ Locale.ENGLISH);
+ Assert.assertEquals("-9,223,372,036,854,775,808", str);
+ }
+
+ public void testOutOfBoundsValueConversion() {
+ // Long.MAX_VALUE+1 is converted to Long.MAX_VALUE
+ long l = converter.convertToModel("9223372036854775808", Long.class,
+ null);
+ Assert.assertEquals(Long.MAX_VALUE, l);
+ // Long.MIN_VALUE-1 is converted to Long.MIN_VALUE
+ l = converter.convertToModel("-9223372036854775809", Long.class, null);
+ assertEquals(Long.MIN_VALUE, l);
+
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/converter/StringToShortConverterTest.java b/server/src/test/java/com/vaadin/tests/data/converter/StringToShortConverterTest.java
new file mode 100644
index 0000000000..ab255bce80
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/converter/StringToShortConverterTest.java
@@ -0,0 +1,70 @@
+package com.vaadin.tests.data.converter;
+
+import junit.framework.TestCase;
+
+import org.junit.Assert;
+
+import com.vaadin.data.util.converter.Converter;
+import com.vaadin.data.util.converter.Converter.ConversionException;
+import com.vaadin.data.util.converter.ReverseConverter;
+import com.vaadin.data.util.converter.StringToShortConverter;
+
+public class StringToShortConverterTest extends TestCase {
+
+ StringToShortConverter converter = new StringToShortConverter();
+ Converter<Short, String> reverseConverter = new ReverseConverter<Short, String>(
+ converter);
+
+ public void testNullConversion() {
+ assertEquals("Null value was converted incorrectly", null,
+ converter.convertToModel(null, Short.class, null));
+ }
+
+ public void testReverseNullConversion() {
+ assertEquals("Null value reversely was converted incorrectly", null,
+ reverseConverter.convertToModel(null, String.class, null));
+ }
+
+ public void testEmptyStringConversion() {
+ assertEquals("Empty value was converted incorrectly", null,
+ converter.convertToModel("", Short.class, null));
+ }
+
+ public void testValueConversion() {
+ assertEquals("Short value was converted incorrectly",
+ Short.valueOf((short) 10),
+ converter.convertToModel("10", Short.class, null));
+ }
+
+ public void testReverseValueConversion() {
+ assertEquals(
+ "Short value reversely was converted incorrectly",
+ reverseConverter.convertToModel((short) 10, String.class, null),
+ "10");
+ }
+
+ public void testExtremeShortValueConversion() {
+ short b = converter.convertToModel("32767", Short.class, null);
+ Assert.assertEquals(Short.MAX_VALUE, b);
+ b = converter.convertToModel("-32768", Short.class, null);
+ assertEquals("Min short value was converted incorrectly",
+ Short.MIN_VALUE, b);
+ }
+
+ public void testValueOutOfRange() {
+ Double[] values = new Double[] { Integer.MAX_VALUE * 2.0,
+ Integer.MIN_VALUE * 2.0, Long.MAX_VALUE * 2.0,
+ Long.MIN_VALUE * 2.0 };
+
+ boolean accepted = false;
+ for (Number value : values) {
+ try {
+ converter.convertToModel(String.format("%.0f", value),
+ Short.class, null);
+ accepted = true;
+ } catch (ConversionException expected) {
+ }
+ }
+ assertFalse("Accepted value outside range of int", accepted);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/validator/BigDecimalRangeValidatorTest.java b/server/src/test/java/com/vaadin/tests/data/validator/BigDecimalRangeValidatorTest.java
new file mode 100644
index 0000000000..36f120151b
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/validator/BigDecimalRangeValidatorTest.java
@@ -0,0 +1,55 @@
+package com.vaadin.tests.data.validator;
+
+import java.math.BigDecimal;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.validator.BigDecimalRangeValidator;
+
+public class BigDecimalRangeValidatorTest extends TestCase {
+
+ private BigDecimalRangeValidator cleanValidator = new BigDecimalRangeValidator(
+ "no values", null, null);
+ private BigDecimalRangeValidator minValidator = new BigDecimalRangeValidator(
+ "no values", new BigDecimal(10.1), null);
+ private BigDecimalRangeValidator maxValidator = new BigDecimalRangeValidator(
+ "no values", null, new BigDecimal(100.1));
+ private BigDecimalRangeValidator minMaxValidator = new BigDecimalRangeValidator(
+ "no values", new BigDecimal(10.5), new BigDecimal(100.5));
+
+ public void testNullValue() {
+ assertTrue("Didn't accept null", cleanValidator.isValid(null));
+ assertTrue("Didn't accept null", minValidator.isValid(null));
+ assertTrue("Didn't accept null", maxValidator.isValid(null));
+ assertTrue("Didn't accept null", minMaxValidator.isValid(null));
+ }
+
+ public void testMinValue() {
+ assertTrue("Validator without ranges didn't accept value",
+ cleanValidator.isValid(new BigDecimal(-15.0)));
+ assertTrue("Didn't accept valid value",
+ minValidator.isValid(new BigDecimal(10.1)));
+ assertFalse("Accepted too small value",
+ minValidator.isValid(new BigDecimal(10.0)));
+ }
+
+ public void testMaxValue() {
+ assertTrue("Validator without ranges didn't accept value",
+ cleanValidator.isValid(new BigDecimal(1120.0)));
+ assertTrue("Didn't accept valid value",
+ maxValidator.isValid(new BigDecimal(15.0)));
+ assertFalse("Accepted too large value",
+ maxValidator.isValid(new BigDecimal(100.6)));
+ }
+
+ public void testMinMaxValue() {
+ assertTrue("Didn't accept valid value",
+ minMaxValidator.isValid(new BigDecimal(10.5)));
+ assertTrue("Didn't accept valid value",
+ minMaxValidator.isValid(new BigDecimal(100.5)));
+ assertFalse("Accepted too small value",
+ minMaxValidator.isValid(new BigDecimal(10.4)));
+ assertFalse("Accepted too large value",
+ minMaxValidator.isValid(new BigDecimal(100.6)));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/validator/BigIntegerRangeValidatorTest.java b/server/src/test/java/com/vaadin/tests/data/validator/BigIntegerRangeValidatorTest.java
new file mode 100644
index 0000000000..92fabbb02a
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/validator/BigIntegerRangeValidatorTest.java
@@ -0,0 +1,55 @@
+package com.vaadin.tests.data.validator;
+
+import java.math.BigInteger;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.validator.BigIntegerRangeValidator;
+
+public class BigIntegerRangeValidatorTest extends TestCase {
+
+ private BigIntegerRangeValidator cleanValidator = new BigIntegerRangeValidator(
+ "no values", null, null);
+ private BigIntegerRangeValidator minValidator = new BigIntegerRangeValidator(
+ "no values", BigInteger.valueOf(10), null);
+ private BigIntegerRangeValidator maxValidator = new BigIntegerRangeValidator(
+ "no values", null, BigInteger.valueOf(100));
+ private BigIntegerRangeValidator minMaxValidator = new BigIntegerRangeValidator(
+ "no values", BigInteger.valueOf(10), BigInteger.valueOf(100));
+
+ public void testNullValue() {
+ assertTrue("Didn't accept null", cleanValidator.isValid(null));
+ assertTrue("Didn't accept null", minValidator.isValid(null));
+ assertTrue("Didn't accept null", maxValidator.isValid(null));
+ assertTrue("Didn't accept null", minMaxValidator.isValid(null));
+ }
+
+ public void testMinValue() {
+ assertTrue("Validator without ranges didn't accept value",
+ cleanValidator.isValid(BigInteger.valueOf(-15)));
+ assertTrue("Didn't accept valid value",
+ minValidator.isValid(BigInteger.valueOf(15)));
+ assertFalse("Accepted too small value",
+ minValidator.isValid(BigInteger.valueOf(9)));
+ }
+
+ public void testMaxValue() {
+ assertTrue("Validator without ranges didn't accept value",
+ cleanValidator.isValid(BigInteger.valueOf(1120)));
+ assertTrue("Didn't accept valid value",
+ maxValidator.isValid(BigInteger.valueOf(15)));
+ assertFalse("Accepted too large value",
+ maxValidator.isValid(BigInteger.valueOf(120)));
+ }
+
+ public void testMinMaxValue() {
+ assertTrue("Didn't accept valid value",
+ minMaxValidator.isValid(BigInteger.valueOf(15)));
+ assertTrue("Didn't accept valid value",
+ minMaxValidator.isValid(BigInteger.valueOf(99)));
+ assertFalse("Accepted too small value",
+ minMaxValidator.isValid(BigInteger.valueOf(9)));
+ assertFalse("Accepted too large value",
+ minMaxValidator.isValid(BigInteger.valueOf(110)));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/validator/ByteRangeValidatorTest.java b/server/src/test/java/com/vaadin/tests/data/validator/ByteRangeValidatorTest.java
new file mode 100644
index 0000000000..03f35fe1bb
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/validator/ByteRangeValidatorTest.java
@@ -0,0 +1,50 @@
+package com.vaadin.tests.data.validator;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.validator.ByteRangeValidator;
+
+public class ByteRangeValidatorTest extends TestCase {
+
+ private ByteRangeValidator cleanValidator = new ByteRangeValidator(
+ "no values", null, null);
+ private ByteRangeValidator minValidator = new ByteRangeValidator(
+ "no values", (byte) 10, null);
+ private ByteRangeValidator maxValidator = new ByteRangeValidator(
+ "no values", null, (byte) 100);
+ private ByteRangeValidator minMaxValidator = new ByteRangeValidator(
+ "no values", (byte) 10, (byte) 100);
+
+ public void testNullValue() {
+ assertTrue("Didn't accept null", cleanValidator.isValid(null));
+ assertTrue("Didn't accept null", minValidator.isValid(null));
+ assertTrue("Didn't accept null", maxValidator.isValid(null));
+ assertTrue("Didn't accept null", minMaxValidator.isValid(null));
+ }
+
+ public void testMinValue() {
+ assertTrue("Validator without ranges didn't accept value",
+ cleanValidator.isValid((byte) -15));
+ assertTrue("Didn't accept valid value", minValidator.isValid((byte) 15));
+ assertFalse("Accepted too small value", minValidator.isValid((byte) 9));
+ }
+
+ public void testMaxValue() {
+ assertTrue("Validator without ranges didn't accept value",
+ cleanValidator.isValid((byte) 112));
+ assertTrue("Didn't accept valid value", maxValidator.isValid((byte) 15));
+ assertFalse("Accepted too large value",
+ maxValidator.isValid((byte) 120));
+ }
+
+ public void testMinMaxValue() {
+ assertTrue("Didn't accept valid value",
+ minMaxValidator.isValid((byte) 15));
+ assertTrue("Didn't accept valid value",
+ minMaxValidator.isValid((byte) 99));
+ assertFalse("Accepted too small value",
+ minMaxValidator.isValid((byte) 9));
+ assertFalse("Accepted too large value",
+ minMaxValidator.isValid((byte) 110));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/validator/CompositeValidatorTest.java b/server/src/test/java/com/vaadin/tests/data/validator/CompositeValidatorTest.java
new file mode 100644
index 0000000000..8199419b67
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/validator/CompositeValidatorTest.java
@@ -0,0 +1,116 @@
+package com.vaadin.tests.data.validator;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.Validator;
+import com.vaadin.data.validator.CompositeValidator;
+import com.vaadin.data.validator.CompositeValidator.CombinationMode;
+import com.vaadin.data.validator.EmailValidator;
+import com.vaadin.data.validator.RegexpValidator;
+
+public class CompositeValidatorTest extends TestCase {
+
+ CompositeValidator and = new CompositeValidator(CombinationMode.AND,
+ "One validator not valid");
+ CompositeValidator or = new CompositeValidator(CombinationMode.OR,
+ "No validators are valid");
+ EmailValidator email = new EmailValidator("Faulty email");
+ RegexpValidator regex = new RegexpValidator("@mail.com", false,
+ "Partial match validator error");
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ and.addValidator(email);
+ and.addValidator(regex);
+
+ or.addValidator(email);
+ or.addValidator(regex);
+ }
+
+ public void testCorrectValue() {
+ String testString = "user@mail.com";
+ assertTrue(email.isValid(testString));
+ assertTrue(regex.isValid(testString));
+ try {
+ // notNull.validate(null);
+ // fail("expected null to fail with an exception");
+ and.validate(testString);
+ } catch (Validator.InvalidValueException ex) {
+ // assertEquals("Null not accepted", ex.getMessage());
+ fail("And validator should be valid");
+ }
+ try {
+ or.validate(testString);
+ } catch (Validator.InvalidValueException ex) {
+ // assertEquals("Null not accepted", ex.getMessage());
+ fail("And validator should be valid");
+ }
+ }
+
+ public void testCorrectRegex() {
+
+ String testString = "@mail.com";
+ assertFalse(testString + " should not validate",
+ email.isValid(testString));
+ assertTrue(testString + "should validate", regex.isValid(testString));
+ try {
+ // notNull.validate(null);
+ and.validate(testString);
+ fail("expected and to fail with an exception");
+ } catch (Validator.InvalidValueException ex) {
+ assertEquals("Faulty email", ex.getMessage());
+ // fail("And validator should be valid");
+ }
+ try {
+ or.validate(testString);
+ } catch (Validator.InvalidValueException ex) {
+ // assertEquals("Null not accepted", ex.getMessage());
+ fail("Or validator should be valid");
+ }
+ }
+
+ public void testCorrectEmail() {
+
+ String testString = "user@gmail.com";
+
+ assertTrue(testString + " should validate", email.isValid(testString));
+ assertFalse(testString + " should not validate",
+ regex.isValid(testString));
+ try {
+ and.validate(testString);
+ fail("expected and to fail with an exception");
+ } catch (Validator.InvalidValueException ex) {
+ assertEquals("Partial match validator error", ex.getMessage());
+ }
+ try {
+ or.validate(testString);
+ } catch (Validator.InvalidValueException ex) {
+ fail("Or validator should be valid");
+ }
+ }
+
+ public void testBothFaulty() {
+
+ String testString = "gmail.com";
+
+ assertFalse(testString + " should not validate",
+ email.isValid(testString));
+ assertFalse(testString + " should not validate",
+ regex.isValid(testString));
+ try {
+ and.validate(testString);
+ fail("expected and to fail with an exception");
+ } catch (Validator.InvalidValueException ex) {
+ assertEquals("Faulty email", ex.getMessage());
+ }
+ try {
+ or.validate(testString);
+ fail("expected or to fail with an exception");
+ } catch (Validator.InvalidValueException ex) {
+ assertEquals("No validators are valid", ex.getMessage());
+ }
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/validator/DateRangeValidatorTest.java b/server/src/test/java/com/vaadin/tests/data/validator/DateRangeValidatorTest.java
new file mode 100644
index 0000000000..7bb3e20160
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/validator/DateRangeValidatorTest.java
@@ -0,0 +1,97 @@
+package com.vaadin.tests.data.validator;
+
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.validator.DateRangeValidator;
+import com.vaadin.shared.ui.datefield.Resolution;
+
+public class DateRangeValidatorTest extends TestCase {
+ Calendar startDate = new GregorianCalendar(TimeZone.getTimeZone("GMT"),
+ Locale.ENGLISH);
+ Calendar endDate = new GregorianCalendar(TimeZone.getTimeZone("GMT"),
+ Locale.ENGLISH);
+
+ private DateRangeValidator cleanValidator;
+ private DateRangeValidator minValidator;
+ private DateRangeValidator maxValidator;
+ private DateRangeValidator minMaxValidator;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ startDate.set(2000, Calendar.JANUARY, 1, 12, 0, 0);
+ endDate.set(2000, Calendar.FEBRUARY, 20, 12, 0, 0);
+
+ cleanValidator = new DateRangeValidator("Given date outside range",
+ null, null, Resolution.DAY);
+ minValidator = new DateRangeValidator("Given date before startDate",
+ startDate.getTime(), null, Resolution.DAY);
+ maxValidator = new DateRangeValidator("Given date after endDate", null,
+ endDate.getTime(), Resolution.DAY);
+ minMaxValidator = new DateRangeValidator("Given date outside range",
+ startDate.getTime(), endDate.getTime(), Resolution.DAY);
+ }
+
+ public void testNullValue() {
+ assertTrue("Didn't accept null", cleanValidator.isValid(null));
+ assertTrue("Didn't accept null", minValidator.isValid(null));
+ assertTrue("Didn't accept null", maxValidator.isValid(null));
+ assertTrue("Didn't accept null", minMaxValidator.isValid(null));
+ }
+
+ public void testMinValue() {
+ Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"),
+ Locale.ENGLISH);
+ cal.setTime(startDate.getTime());
+ cal.add(Calendar.SECOND, 1);
+
+ assertTrue("Validator without ranges didn't accept value",
+ cleanValidator.isValid(cal.getTime()));
+ assertTrue("Didn't accept valid value",
+ minValidator.isValid(cal.getTime()));
+
+ cal.add(Calendar.SECOND, -3);
+
+ assertFalse("Accepted too small value",
+ minValidator.isValid(cal.getTime()));
+ }
+
+ public void testMaxValue() {
+ Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"),
+ Locale.ENGLISH);
+ cal.setTime(endDate.getTime());
+ cal.add(Calendar.SECOND, -1);
+
+ assertTrue("Validator without ranges didn't accept value",
+ cleanValidator.isValid(cal.getTime()));
+ assertTrue("Didn't accept valid value",
+ maxValidator.isValid(cal.getTime()));
+
+ cal.add(Calendar.SECOND, 2);
+ assertFalse("Accepted too large value",
+ maxValidator.isValid(cal.getTime()));
+ }
+
+ public void testMinMaxValue() {
+ Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"),
+ Locale.ENGLISH);
+ cal.setTime(endDate.getTime());
+
+ assertTrue("Didn't accept valid value",
+ minMaxValidator.isValid(cal.getTime()));
+ cal.add(Calendar.SECOND, 1);
+ assertFalse("Accepted too large value",
+ minMaxValidator.isValid(cal.getTime()));
+ cal.setTime(startDate.getTime());
+ assertTrue("Didn't accept valid value",
+ minMaxValidator.isValid(cal.getTime()));
+ cal.add(Calendar.SECOND, -1);
+ assertFalse("Accepted too small value",
+ minMaxValidator.isValid(cal.getTime()));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/validator/DoubleRangeValidatorTest.java b/server/src/test/java/com/vaadin/tests/data/validator/DoubleRangeValidatorTest.java
new file mode 100644
index 0000000000..b096937bd2
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/validator/DoubleRangeValidatorTest.java
@@ -0,0 +1,45 @@
+package com.vaadin.tests.data.validator;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.validator.DoubleRangeValidator;
+
+public class DoubleRangeValidatorTest extends TestCase {
+
+ private DoubleRangeValidator cleanValidator = new DoubleRangeValidator(
+ "no values", null, null);
+ private DoubleRangeValidator minValidator = new DoubleRangeValidator(
+ "no values", 10.1, null);
+ private DoubleRangeValidator maxValidator = new DoubleRangeValidator(
+ "no values", null, 100.1);
+ private DoubleRangeValidator minMaxValidator = new DoubleRangeValidator(
+ "no values", 10.5, 100.5);
+
+ public void testNullValue() {
+ assertTrue("Didn't accept null", cleanValidator.isValid(null));
+ assertTrue("Didn't accept null", minValidator.isValid(null));
+ assertTrue("Didn't accept null", maxValidator.isValid(null));
+ assertTrue("Didn't accept null", minMaxValidator.isValid(null));
+ }
+
+ public void testMinValue() {
+ assertTrue("Validator without ranges didn't accept value",
+ cleanValidator.isValid(-15.0));
+ assertTrue("Didn't accept valid value", minValidator.isValid(10.1));
+ assertFalse("Accepted too small value", minValidator.isValid(10.0));
+ }
+
+ public void testMaxValue() {
+ assertTrue("Validator without ranges didn't accept value",
+ cleanValidator.isValid(1120.0));
+ assertTrue("Didn't accept valid value", maxValidator.isValid(15.0));
+ assertFalse("Accepted too large value", maxValidator.isValid(100.6));
+ }
+
+ public void testMinMaxValue() {
+ assertTrue("Didn't accept valid value", minMaxValidator.isValid(10.5));
+ assertTrue("Didn't accept valid value", minMaxValidator.isValid(100.5));
+ assertFalse("Accepted too small value", minMaxValidator.isValid(10.4));
+ assertFalse("Accepted too large value", minMaxValidator.isValid(100.6));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/validator/EmailValidatorTest.java b/server/src/test/java/com/vaadin/tests/data/validator/EmailValidatorTest.java
new file mode 100644
index 0000000000..19fe9e6580
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/validator/EmailValidatorTest.java
@@ -0,0 +1,26 @@
+package com.vaadin.tests.data.validator;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.validator.EmailValidator;
+
+public class EmailValidatorTest extends TestCase {
+
+ private EmailValidator validator = new EmailValidator("Error");
+
+ public void testEmailValidatorWithNull() {
+ assertTrue(validator.isValid(null));
+ }
+
+ public void testEmailValidatorWithEmptyString() {
+ assertTrue(validator.isValid(""));
+ }
+
+ public void testEmailValidatorWithFaultyString() {
+ assertFalse(validator.isValid("not.an.email"));
+ }
+
+ public void testEmailValidatorWithOkEmail() {
+ assertTrue(validator.isValid("my.name@email.com"));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/validator/FloatRangeValidatorTest.java b/server/src/test/java/com/vaadin/tests/data/validator/FloatRangeValidatorTest.java
new file mode 100644
index 0000000000..c5a07be43f
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/validator/FloatRangeValidatorTest.java
@@ -0,0 +1,45 @@
+package com.vaadin.tests.data.validator;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.validator.FloatRangeValidator;
+
+public class FloatRangeValidatorTest extends TestCase {
+
+ private FloatRangeValidator cleanValidator = new FloatRangeValidator(
+ "no values", null, null);
+ private FloatRangeValidator minValidator = new FloatRangeValidator(
+ "no values", 10.1f, null);
+ private FloatRangeValidator maxValidator = new FloatRangeValidator(
+ "no values", null, 100.1f);
+ private FloatRangeValidator minMaxValidator = new FloatRangeValidator(
+ "no values", 10.5f, 100.5f);
+
+ public void testNullValue() {
+ assertTrue("Didn't accept null", cleanValidator.isValid(null));
+ assertTrue("Didn't accept null", minValidator.isValid(null));
+ assertTrue("Didn't accept null", maxValidator.isValid(null));
+ assertTrue("Didn't accept null", minMaxValidator.isValid(null));
+ }
+
+ public void testMinValue() {
+ assertTrue("Validator without ranges didn't accept value",
+ cleanValidator.isValid(-15.0f));
+ assertTrue("Didn't accept valid value", minValidator.isValid(10.1f));
+ assertFalse("Accepted too small value", minValidator.isValid(10.0f));
+ }
+
+ public void testMaxValue() {
+ assertTrue("Validator without ranges didn't accept value",
+ cleanValidator.isValid(1120.0f));
+ assertTrue("Didn't accept valid value", maxValidator.isValid(15.0f));
+ assertFalse("Accepted too large value", maxValidator.isValid(100.6f));
+ }
+
+ public void testMinMaxValue() {
+ assertTrue("Didn't accept valid value", minMaxValidator.isValid(10.5f));
+ assertTrue("Didn't accept valid value", minMaxValidator.isValid(100.5f));
+ assertFalse("Accepted too small value", minMaxValidator.isValid(10.4f));
+ assertFalse("Accepted too large value", minMaxValidator.isValid(100.6f));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/validator/IntegerRangeValidatorTest.java b/server/src/test/java/com/vaadin/tests/data/validator/IntegerRangeValidatorTest.java
new file mode 100644
index 0000000000..5e64d0107e
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/validator/IntegerRangeValidatorTest.java
@@ -0,0 +1,45 @@
+package com.vaadin.tests.data.validator;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.validator.IntegerRangeValidator;
+
+public class IntegerRangeValidatorTest extends TestCase {
+
+ private IntegerRangeValidator cleanValidator = new IntegerRangeValidator(
+ "no values", null, null);
+ private IntegerRangeValidator minValidator = new IntegerRangeValidator(
+ "no values", 10, null);
+ private IntegerRangeValidator maxValidator = new IntegerRangeValidator(
+ "no values", null, 100);
+ private IntegerRangeValidator minMaxValidator = new IntegerRangeValidator(
+ "no values", 10, 100);
+
+ public void testNullValue() {
+ assertTrue("Didn't accept null", cleanValidator.isValid(null));
+ assertTrue("Didn't accept null", minValidator.isValid(null));
+ assertTrue("Didn't accept null", maxValidator.isValid(null));
+ assertTrue("Didn't accept null", minMaxValidator.isValid(null));
+ }
+
+ public void testMinValue() {
+ assertTrue("Validator without ranges didn't accept value",
+ cleanValidator.isValid(-15));
+ assertTrue("Didn't accept valid value", minValidator.isValid(15));
+ assertFalse("Accepted too small value", minValidator.isValid(9));
+ }
+
+ public void testMaxValue() {
+ assertTrue("Validator without ranges didn't accept value",
+ cleanValidator.isValid(1120));
+ assertTrue("Didn't accept valid value", maxValidator.isValid(15));
+ assertFalse("Accepted too large value", maxValidator.isValid(120));
+ }
+
+ public void testMinMaxValue() {
+ assertTrue("Didn't accept valid value", minMaxValidator.isValid(15));
+ assertTrue("Didn't accept valid value", minMaxValidator.isValid(99));
+ assertFalse("Accepted too small value", minMaxValidator.isValid(9));
+ assertFalse("Accepted too large value", minMaxValidator.isValid(110));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/validator/LongRangeValidatorTest.java b/server/src/test/java/com/vaadin/tests/data/validator/LongRangeValidatorTest.java
new file mode 100644
index 0000000000..440e9c3fd2
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/validator/LongRangeValidatorTest.java
@@ -0,0 +1,45 @@
+package com.vaadin.tests.data.validator;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.validator.LongRangeValidator;
+
+public class LongRangeValidatorTest extends TestCase {
+
+ private LongRangeValidator cleanValidator = new LongRangeValidator(
+ "no values", null, null);
+ private LongRangeValidator minValidator = new LongRangeValidator(
+ "no values", 10l, null);
+ private LongRangeValidator maxValidator = new LongRangeValidator(
+ "no values", null, 100l);
+ private LongRangeValidator minMaxValidator = new LongRangeValidator(
+ "no values", 10l, 100l);
+
+ public void testNullValue() {
+ assertTrue("Didn't accept null", cleanValidator.isValid(null));
+ assertTrue("Didn't accept null", minValidator.isValid(null));
+ assertTrue("Didn't accept null", maxValidator.isValid(null));
+ assertTrue("Didn't accept null", minMaxValidator.isValid(null));
+ }
+
+ public void testMinValue() {
+ assertTrue("Validator without ranges didn't accept value",
+ cleanValidator.isValid(-15l));
+ assertTrue("Didn't accept valid value", minValidator.isValid(15l));
+ assertFalse("Accepted too small value", minValidator.isValid(9l));
+ }
+
+ public void testMaxValue() {
+ assertTrue("Validator without ranges didn't accept value",
+ cleanValidator.isValid(1120l));
+ assertTrue("Didn't accept valid value", maxValidator.isValid(15l));
+ assertFalse("Accepted too large value", maxValidator.isValid(120l));
+ }
+
+ public void testMinMaxValue() {
+ assertTrue("Didn't accept valid value", minMaxValidator.isValid(15l));
+ assertTrue("Didn't accept valid value", minMaxValidator.isValid(99l));
+ assertFalse("Accepted too small value", minMaxValidator.isValid(9l));
+ assertFalse("Accepted too large value", minMaxValidator.isValid(110l));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/validator/NullValidatorTest.java b/server/src/test/java/com/vaadin/tests/data/validator/NullValidatorTest.java
new file mode 100644
index 0000000000..1e08ea7e2c
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/validator/NullValidatorTest.java
@@ -0,0 +1,40 @@
+package com.vaadin.tests.data.validator;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.Validator;
+import com.vaadin.data.validator.NullValidator;
+
+public class NullValidatorTest extends TestCase {
+
+ NullValidator notNull = new NullValidator("Null not accepted", false);
+ NullValidator onlyNull = new NullValidator("Only null accepted", true);
+
+ public void testNullValue() {
+ try {
+ notNull.validate(null);
+ fail("expected null to fail with an exception");
+ } catch (Validator.InvalidValueException ex) {
+ assertEquals("Null not accepted", ex.getMessage());
+ }
+ try {
+ onlyNull.validate(null);
+ } catch (Validator.InvalidValueException ex) {
+ fail("onlyNull should not throw exception for null");
+ }
+ }
+
+ public void testNonNullValue() {
+ try {
+ onlyNull.validate("Not a null value");
+ fail("expected onlyNull validator to fail with an exception");
+ } catch (Validator.InvalidValueException ex) {
+ assertEquals("Only null accepted", ex.getMessage());
+ }
+ try {
+ notNull.validate("Not a null value");
+ } catch (Validator.InvalidValueException ex) {
+ fail("notNull should not throw exception for \"Not a null value\"");
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/validator/RegexpValidatorTest.java b/server/src/test/java/com/vaadin/tests/data/validator/RegexpValidatorTest.java
new file mode 100644
index 0000000000..2a62d23059
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/validator/RegexpValidatorTest.java
@@ -0,0 +1,44 @@
+package com.vaadin.tests.data.validator;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.validator.RegexpValidator;
+
+public class RegexpValidatorTest extends TestCase {
+
+ private RegexpValidator completeValidator = new RegexpValidator("pattern",
+ true, "Complete match validator error");
+ private RegexpValidator partialValidator = new RegexpValidator("pattern",
+ false, "Partial match validator error");
+
+ public void testRegexpValidatorWithNull() {
+ assertTrue(completeValidator.isValid(null));
+ assertTrue(partialValidator.isValid(null));
+ }
+
+ public void testRegexpValidatorWithEmptyString() {
+ assertTrue(completeValidator.isValid(""));
+ assertTrue(partialValidator.isValid(""));
+ }
+
+ public void testCompleteRegexpValidatorWithFaultyString() {
+ assertFalse(completeValidator.isValid("mismatch"));
+ assertFalse(completeValidator.isValid("pattern2"));
+ assertFalse(completeValidator.isValid("1pattern"));
+ }
+
+ public void testCompleteRegexpValidatorWithOkString() {
+ assertTrue(completeValidator.isValid("pattern"));
+ }
+
+ public void testPartialRegexpValidatorWithFaultyString() {
+ assertFalse(partialValidator.isValid("mismatch"));
+ }
+
+ public void testPartialRegexpValidatorWithOkString() {
+ assertTrue(partialValidator.isValid("pattern"));
+ assertTrue(partialValidator.isValid("1pattern"));
+ assertTrue(partialValidator.isValid("pattern2"));
+ assertTrue(partialValidator.isValid("1pattern2"));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/validator/ShortRangeValidatorTest.java b/server/src/test/java/com/vaadin/tests/data/validator/ShortRangeValidatorTest.java
new file mode 100644
index 0000000000..69d22eb91e
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/validator/ShortRangeValidatorTest.java
@@ -0,0 +1,52 @@
+package com.vaadin.tests.data.validator;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.validator.ShortRangeValidator;
+
+public class ShortRangeValidatorTest extends TestCase {
+
+ private ShortRangeValidator cleanValidator = new ShortRangeValidator(
+ "no values", null, null);
+ private ShortRangeValidator minValidator = new ShortRangeValidator(
+ "no values", (short) 10, null);
+ private ShortRangeValidator maxValidator = new ShortRangeValidator(
+ "no values", null, (short) 100);
+ private ShortRangeValidator minMaxValidator = new ShortRangeValidator(
+ "no values", (short) 10, (short) 100);
+
+ public void testNullValue() {
+ assertTrue("Didn't accept null", cleanValidator.isValid(null));
+ assertTrue("Didn't accept null", minValidator.isValid(null));
+ assertTrue("Didn't accept null", maxValidator.isValid(null));
+ assertTrue("Didn't accept null", minMaxValidator.isValid(null));
+ }
+
+ public void testMinValue() {
+ assertTrue("Validator without ranges didn't accept value",
+ cleanValidator.isValid((short) -15));
+ assertTrue("Didn't accept valid value",
+ minValidator.isValid((short) 15));
+ assertFalse("Accepted too small value", minValidator.isValid((short) 9));
+ }
+
+ public void testMaxValue() {
+ assertTrue("Validator without ranges didn't accept value",
+ cleanValidator.isValid((short) 1120));
+ assertTrue("Didn't accept valid value",
+ maxValidator.isValid((short) 15));
+ assertFalse("Accepted too large value",
+ maxValidator.isValid((short) 120));
+ }
+
+ public void testMinMaxValue() {
+ assertTrue("Didn't accept valid value",
+ minMaxValidator.isValid((short) 15));
+ assertTrue("Didn't accept valid value",
+ minMaxValidator.isValid((short) 99));
+ assertFalse("Accepted too small value",
+ minMaxValidator.isValid((short) 9));
+ assertFalse("Accepted too large value",
+ minMaxValidator.isValid((short) 110));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/data/validator/StringLengthValidatorTest.java b/server/src/test/java/com/vaadin/tests/data/validator/StringLengthValidatorTest.java
new file mode 100644
index 0000000000..5f12367f09
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/data/validator/StringLengthValidatorTest.java
@@ -0,0 +1,65 @@
+package com.vaadin.tests.data.validator;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.validator.StringLengthValidator;
+
+public class StringLengthValidatorTest extends TestCase {
+
+ private StringLengthValidator validator = new StringLengthValidator("Error");
+ private StringLengthValidator validatorNoNull = new StringLengthValidator(
+ "Error", 1, 5, false);
+ private StringLengthValidator validatorMinValue = new StringLengthValidator(
+ "Error", 5, null, true);
+ private StringLengthValidator validatorMaxValue = new StringLengthValidator(
+ "Error", null, 15, true);
+
+ public void testValidatorWithNull() {
+ assertTrue("Didn't accept null", validator.isValid(null));
+ assertTrue("Didn't accept null", validatorMinValue.isValid(null));
+ }
+
+ public void testValidatorNotAcceptingNull() {
+ assertFalse("Accepted null", validatorNoNull.isValid(null));
+ }
+
+ public void testEmptyString() {
+ assertTrue("Didn't accept empty String", validator.isValid(""));
+ assertTrue("Didn't accept empty String", validatorMaxValue.isValid(""));
+ assertFalse("Accepted empty string even though has lower bound of 1",
+ validatorNoNull.isValid(""));
+ assertFalse("Accepted empty string even though has lower bound of 5",
+ validatorMinValue.isValid(""));
+ }
+
+ public void testTooLongString() {
+ assertFalse("Too long string was accepted",
+ validatorNoNull.isValid("This string is too long"));
+ assertFalse("Too long string was accepted",
+ validatorMaxValue.isValid("This string is too long"));
+ }
+
+ public void testNoUpperBound() {
+ assertTrue(
+ "String not accepted even though no upper bound",
+ validatorMinValue
+ .isValid("This is a really long string to test that no upper bound exists"));
+ }
+
+ public void testNoLowerBound() {
+ assertTrue("Didn't accept short string", validatorMaxValue.isValid(""));
+ assertTrue("Didn't accept short string", validatorMaxValue.isValid("1"));
+ }
+
+ public void testStringLengthValidatorWithOkStringLength() {
+ assertTrue("Didn't accept string of correct length",
+ validatorNoNull.isValid("OK!"));
+ assertTrue("Didn't accept string of correct length",
+ validatorMaxValue.isValid("OK!"));
+ }
+
+ public void testTooShortStringLength() {
+ assertFalse("Accepted a string that was too short.",
+ validatorMinValue.isValid("shot"));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/AbstractComponentSetResponsiveTest.java b/server/src/test/java/com/vaadin/tests/design/AbstractComponentSetResponsiveTest.java
new file mode 100644
index 0000000000..175a03cd78
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/AbstractComponentSetResponsiveTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2014 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.design;
+
+import org.junit.Test;
+
+import com.vaadin.shared.ui.label.ContentMode;
+import com.vaadin.ui.Label;
+
+public class AbstractComponentSetResponsiveTest extends
+ DeclarativeTestBase<Label> {
+
+ @Test
+ public void testResponsiveFlag() {
+ Label label = new Label();
+ label.setContentMode(ContentMode.HTML);
+ label.setResponsive(true);
+ String design = "<vaadin-label responsive />";
+ testWrite(design, label);
+ testRead(design, label);
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/ComponentFactoryTest.java b/server/src/test/java/com/vaadin/tests/design/ComponentFactoryTest.java
new file mode 100644
index 0000000000..472c079e42
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/ComponentFactoryTest.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2000-2014 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.design;
+
+import java.io.ByteArrayInputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.vaadin.ui.AbstractComponent;
+import com.vaadin.ui.TextField;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.ui.Component;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.declarative.Design;
+import com.vaadin.ui.declarative.Design.ComponentFactory;
+import com.vaadin.ui.declarative.DesignContext;
+import com.vaadin.ui.declarative.DesignException;
+
+public class ComponentFactoryTest {
+
+ private static final ComponentFactory defaultFactory = Design
+ .getComponentFactory();
+
+ private static final ThreadLocal<ComponentFactory> currentComponentFactory = new ThreadLocal<ComponentFactory>();
+
+ // Set static component factory that delegate to a thread local factory
+ static {
+ Design.setComponentFactory(new ComponentFactory() {
+ @Override
+ public Component createComponent(String fullyQualifiedClassName,
+ DesignContext context) {
+ ComponentFactory componentFactory = currentComponentFactory
+ .get();
+ if (componentFactory == null) {
+ componentFactory = defaultFactory;
+ }
+ return componentFactory.createComponent(
+ fullyQualifiedClassName, context);
+ }
+ });
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testSetNullComponentFactory() {
+ Design.setComponentFactory(null);
+ }
+
+ @Test
+ public void testComponentFactoryLogging() {
+ final List<String> messages = new ArrayList<String>();
+ currentComponentFactory.set(new ComponentFactory() {
+ @Override
+ public Component createComponent(String fullyQualifiedClassName,
+ DesignContext context) {
+ messages.add("Requested class " + fullyQualifiedClassName);
+ return defaultFactory.createComponent(fullyQualifiedClassName,
+ context);
+ }
+ });
+
+ Design.read(new ByteArrayInputStream("<vaadin-label />".getBytes()));
+
+ Assert.assertEquals("There should be one message logged", 1,
+ messages.size());
+ Assert.assertEquals(
+ "Requested class " + Label.class.getCanonicalName(),
+ messages.get(0));
+ }
+
+ @Test(expected = DesignException.class)
+ public void testComponentFactoryReturningNull() {
+ currentComponentFactory.set(new ComponentFactory() {
+ @Override
+ public Component createComponent(String fullyQualifiedClassName,
+ DesignContext context) {
+ return null;
+ }
+ });
+
+ Design.read(new ByteArrayInputStream("<vaadin-label />".getBytes()));
+ }
+
+ @Test(expected = DesignException.class)
+ public void testComponentFactoryThrowingStuff() {
+ currentComponentFactory.set(new ComponentFactory() {
+ @Override
+ public Component createComponent(String fullyQualifiedClassName,
+ DesignContext context) {
+ // Will throw because class is not found
+ return defaultFactory.createComponent("foobar."
+ + fullyQualifiedClassName, context);
+ }
+ });
+
+ Design.read(new ByteArrayInputStream("<vaadin-label />".getBytes()));
+ }
+
+ @Test
+ public void testGetDefaultInstanceUsesComponentFactory() {
+ final List<String> classes = new ArrayList<String>();
+ currentComponentFactory.set(new ComponentFactory() {
+ @Override
+ public Component createComponent(String fullyQualifiedClassName,
+ DesignContext context) {
+ classes.add(fullyQualifiedClassName);
+ return defaultFactory.createComponent(fullyQualifiedClassName,
+ context);
+ }
+ });
+
+ DesignContext designContext = new DesignContext();
+ designContext.getDefaultInstance(new DefaultInstanceTestComponent());
+
+ Assert.assertEquals("There should be one class requests", 1,
+ classes.size());
+ Assert.assertEquals(
+ "First class should be DefaultInstanceTestComponent",
+ DefaultInstanceTestComponent.class.getName(), classes.get(0));
+ }
+
+ @After
+ public void cleanup() {
+ currentComponentFactory.remove();
+ }
+
+ public static class DefaultInstanceTestComponent extends AbstractComponent {
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/ComponentMapperTest.java b/server/src/test/java/com/vaadin/tests/design/ComponentMapperTest.java
new file mode 100644
index 0000000000..c6e8c15109
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/ComponentMapperTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2000-2014 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.design;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.ui.Component;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.declarative.Design;
+import com.vaadin.ui.declarative.Design.ComponentFactory;
+import com.vaadin.ui.declarative.Design.ComponentMapper;
+import com.vaadin.ui.declarative.DesignContext;
+
+public class ComponentMapperTest {
+ private static final ComponentMapper defaultMapper = Design
+ .getComponentMapper();
+
+ private static final ThreadLocal<ComponentMapper> currentMapper = new ThreadLocal<ComponentMapper>();
+
+ static {
+ Design.setComponentMapper(new ComponentMapper() {
+ @Override
+ public Component tagToComponent(String tag,
+ ComponentFactory componentFactory, DesignContext context) {
+ return getActualMapper().tagToComponent(tag, componentFactory,
+ context);
+ }
+
+ @Override
+ public String componentToTag(Component component,
+ DesignContext context) {
+ return getActualMapper().componentToTag(component, context);
+ }
+
+ private ComponentMapper getActualMapper() {
+ ComponentMapper mapper = currentMapper.get();
+ if (mapper == null) {
+ mapper = defaultMapper;
+ }
+ return mapper;
+ }
+ });
+ }
+
+ private final class CustomComponentMapper extends
+ Design.DefaultComponentMapper {
+ @Override
+ public Component tagToComponent(String tag,
+ ComponentFactory componentFactory, DesignContext context) {
+ if (tag.startsWith("custom-")) {
+ ComponentWithCustomTagName component = (ComponentWithCustomTagName) componentFactory
+ .createComponent(
+ ComponentWithCustomTagName.class.getName(),
+ context);
+ component.tagName = tag;
+ return component;
+ } else {
+ return super.tagToComponent(tag, componentFactory, context);
+ }
+ }
+
+ @Override
+ public String componentToTag(Component component, DesignContext context) {
+ if (component instanceof ComponentWithCustomTagName) {
+ ComponentWithCustomTagName withCustomTagName = (ComponentWithCustomTagName) component;
+ return withCustomTagName.tagName;
+ } else {
+ return super.componentToTag(component, context);
+ }
+ }
+ }
+
+ public static class ComponentWithCustomTagName extends Label {
+ private String tagName;
+ }
+
+ @Test
+ public void testCustomComponentMapperRead() {
+ currentMapper.set(new CustomComponentMapper());
+
+ Component component = Design.read(new ByteArrayInputStream(
+ "<custom-foobar />".getBytes()));
+
+ Assert.assertTrue("<custom-foobar> should resolve "
+ + ComponentWithCustomTagName.class.getSimpleName(),
+ component instanceof ComponentWithCustomTagName);
+ Assert.assertEquals("custom-foobar",
+ ((ComponentWithCustomTagName) component).tagName);
+ }
+
+ @Test
+ public void testCustomComponentMapperWrite() throws IOException {
+ currentMapper.set(new CustomComponentMapper());
+
+ ComponentWithCustomTagName component = new ComponentWithCustomTagName();
+ component.tagName = "custom-special";
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ Design.write(component, bos);
+ String writtenDesign = new String(bos.toByteArray());
+
+ Assert.assertTrue(
+ "Written design should contain \"<custom-special\", but instead got "
+ + writtenDesign,
+ writtenDesign.contains("<custom-special"));
+ }
+
+ public void cleanup() {
+ currentMapper.remove();
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/DeclarativeTestBase.java b/server/src/test/java/com/vaadin/tests/design/DeclarativeTestBase.java
new file mode 100644
index 0000000000..7e8b5c7767
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/DeclarativeTestBase.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2000-2014 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.design;
+
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Assert;
+
+import com.vaadin.shared.Connector;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.Flash;
+
+public abstract class DeclarativeTestBase<T extends Component> extends
+ DeclarativeTestBaseBase<T> {
+
+ private static boolean debug = false;
+
+ private final Map<Class<?>, EqualsAsserter<?>> comparators = new HashMap<Class<?>, EqualsAsserter<?>>();
+ private static EqualsAsserter standardEqualsComparator = new EqualsAsserter<Object>() {
+
+ @Override
+ public void assertObjectEquals(Object o1, Object o2) {
+ Assert.assertEquals(o1, o2);
+ }
+ };
+
+ public class IntrospectorEqualsAsserter<T> implements EqualsAsserter<T> {
+
+ private Class<T> c;
+
+ public IntrospectorEqualsAsserter(Class<T> c) {
+ this.c = c;
+ }
+
+ @Override
+ public void assertObjectEquals(T o1, T o2) {
+ try {
+ BeanInfo bi = Introspector.getBeanInfo(c);
+ for (PropertyDescriptor pd : bi.getPropertyDescriptors()) {
+ Method readMethod = pd.getReadMethod();
+ Method writeMethod = pd.getWriteMethod();
+ if (readMethod == null || writeMethod == null) {
+ continue;
+ }
+ // Needed to access public properties inherited from a
+ // nonpublic superclass, see #17425
+ readMethod.setAccessible(true);
+ writeMethod.setAccessible(true);
+ if (Connector.class.isAssignableFrom(c)
+ && readMethod.getName().equals("getParent")) {
+ // Hack to break cycles in the connector hierarchy
+ continue;
+ }
+ try {
+ c.getDeclaredMethod(readMethod.getName());
+ } catch (Exception e) {
+ // Not declared in this class, will be tested by parent
+ // class tester
+ if (debug) {
+ System.out.println("Skipped " + c.getSimpleName()
+ + "." + readMethod.getName());
+ }
+ continue;
+ }
+
+ if (debug) {
+ System.out.println("Testing " + c.getSimpleName() + "."
+ + readMethod.getName());
+ }
+ Object v1 = readMethod.invoke(o1);
+ Object v2 = readMethod.invoke(o2);
+ assertEquals(pd.getDisplayName(), v1, v2);
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ {
+ comparators.put(Flash.class, new IntrospectorEqualsAsserter<Flash>(
+ Flash.class) {
+ @Override
+ public void assertObjectEquals(Flash o1, Flash o2) {
+ super.assertObjectEquals(o1, o2);
+ assertEquals("parameterNames", o1.getParameterNames(),
+ o2.getParameterNames());
+ for (String name : o1.getParameterNames()) {
+ assertEquals("Parameter " + name, o1.getParameter(name),
+ o2.getParameter(name));
+ }
+ }
+ });
+ }
+
+ @Override
+ protected EqualsAsserter getComparator(Class c) {
+ com.vaadin.tests.design.DeclarativeTestBaseBase.EqualsAsserter<?> comp = comparators
+ .get(c);
+ if (comp == null) {
+ if (c.isEnum()) {
+ return standardEqualsComparator;
+ }
+ if (debug) {
+ System.out.println("No comparator found for " + c.getName()
+ + ". Using introspector.");
+ }
+ return new IntrospectorEqualsAsserter<T>(c);
+ }
+ return comp;
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/DeclarativeTestBaseBase.java b/server/src/test/java/com/vaadin/tests/design/DeclarativeTestBaseBase.java
new file mode 100644
index 0000000000..a7ff7174b2
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/DeclarativeTestBaseBase.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright 2000-2014 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.design;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.logging.Handler;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Attribute;
+import org.jsoup.nodes.BooleanAttribute;
+import org.jsoup.nodes.Element;
+import org.jsoup.nodes.Node;
+import org.jsoup.nodes.TextNode;
+import org.junit.Assert;
+
+import com.vaadin.ui.AbstractComponent;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.declarative.Design;
+import com.vaadin.ui.declarative.DesignContext;
+import com.vaadin.ui.declarative.ShouldWriteDataDelegate;
+
+public abstract class DeclarativeTestBaseBase<T extends Component> {
+ private static final class AlwaysWriteDelegate implements
+ ShouldWriteDataDelegate {
+ private static final long serialVersionUID = -6345914431997793599L;
+
+ @Override
+ public boolean shouldWriteData(Component component) {
+ return true;
+ }
+ }
+
+ public static final ShouldWriteDataDelegate ALWAYS_WRITE_DATA = new AlwaysWriteDelegate();
+
+ public interface EqualsAsserter<TT> {
+ public void assertObjectEquals(TT o1, TT o2);
+ }
+
+ protected T read(String design) {
+ try {
+ return (T) Design.read(new ByteArrayInputStream(design
+ .getBytes("UTF-8")));
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ protected String write(T object, boolean writeData) {
+ try {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+
+ DesignContext dc = new DesignContext();
+ if (writeData) {
+ dc.setShouldWriteDataDelegate(DeclarativeTestBaseBase.ALWAYS_WRITE_DATA);
+ }
+ dc.setRootComponent(object);
+ Design.write(dc, outputStream);
+ return outputStream.toString("UTF-8");
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ protected void assertEquals(Object o1, Object o2) {
+ assertEquals("", o1, o2);
+ }
+
+ protected void assertEquals(String message, Object o1, Object o2) {
+ if (o1 == null) {
+ Assert.assertEquals(message, null, o2);
+ return;
+ }
+ if (o2 == null) {
+ Assert.assertEquals(message, null, o1);
+ return;
+ }
+
+ if (!(o1 instanceof Collection && o2 instanceof Collection)) {
+ Assert.assertEquals(o1.getClass(), o2.getClass());
+ }
+
+ if (o1 instanceof Object[]) {
+ Object[] a1 = ((Object[]) o1);
+ Object[] a2 = ((Object[]) o2);
+ Assert.assertEquals(message + ": array length", a1.length,
+ a2.length);
+ for (int i = 0; i < a1.length; i++) {
+ assertEquals(message + ": element " + i, a1[i], a2[i]);
+ }
+ return;
+ }
+
+ List<EqualsAsserter<Object>> comparators = getComparators(o1);
+ if (!comparators.isEmpty()) {
+ for (EqualsAsserter<Object> ec : comparators) {
+ ec.assertObjectEquals(o1, o2);
+ }
+ } else {
+ Assert.assertEquals(message, o1, o2);
+ }
+ }
+
+ private List<EqualsAsserter<Object>> getComparators(Object o1) {
+ List<EqualsAsserter<Object>> result = new ArrayList<EqualsAsserter<Object>>();
+ getComparators(o1.getClass(), result);
+ return result;
+ }
+
+ private void getComparators(Class<?> c, List<EqualsAsserter<Object>> result) {
+ if (c == null || !isVaadin(c)) {
+ return;
+ }
+ EqualsAsserter<Object> comparator = (EqualsAsserter<Object>) getComparator(c);
+ if (c.getSuperclass() != Object.class) {
+ getComparators(c.getSuperclass(), result);
+ }
+ for (Class<?> i : c.getInterfaces()) {
+ getComparators(i, result);
+ }
+
+ if (!result.contains(comparator)) {
+ result.add(comparator);
+ }
+ }
+
+ protected abstract <TT> EqualsAsserter<TT> getComparator(Class<TT> c);
+
+ private boolean isVaadin(Class<?> c) {
+ return c.getPackage() != null
+ && c.getPackage().getName().startsWith("com.vaadin");
+
+ }
+
+ public static class TestLogHandler {
+ final List<String> messages = new ArrayList<String>();
+ Handler handler = new Handler() {
+ @Override
+ public void publish(LogRecord record) {
+ messages.add(record.getMessage());
+ }
+
+ @Override
+ public void flush() {
+ }
+
+ @Override
+ public void close() throws SecurityException {
+
+ }
+ };
+
+ public TestLogHandler() {
+ Logger.getLogger(AbstractComponent.class.getName()).getParent()
+ .addHandler(handler);
+ }
+
+ public String getMessages() {
+ if (messages.isEmpty()) {
+ return "";
+ }
+
+ String r = "";
+ for (String message : messages) {
+ r += message + "\n";
+ }
+ return r;
+ }
+
+ }
+
+ public T testRead(String design, T expected) {
+ TestLogHandler l = new TestLogHandler();
+ T read = read(design);
+ assertEquals(expected, read);
+ Assert.assertEquals("", l.getMessages());
+ return read;
+ }
+
+ public void testWrite(String design, T expected) {
+ TestLogHandler l = new TestLogHandler();
+ testWrite(design, expected, false);
+ Assert.assertEquals("", l.getMessages());
+ }
+
+ public void testWrite(String design, T expected, boolean writeData) {
+ String written = write(expected, writeData);
+
+ Element producedElem = Jsoup.parse(written).body().child(0);
+ Element comparableElem = Jsoup.parse(design).body().child(0);
+
+ String produced = elementToHtml(producedElem);
+ String comparable = elementToHtml(comparableElem);
+
+ Assert.assertEquals(comparable, produced);
+ }
+
+ protected Element createElement(Component c) {
+ return new DesignContext().createElement(c);
+ }
+
+ private String elementToHtml(Element producedElem) {
+ StringBuilder stringBuilder = new StringBuilder();
+ elementToHtml(producedElem, stringBuilder);
+ return stringBuilder.toString();
+ }
+
+ /**
+ * Produce predictable html (attributes in alphabetical order), always
+ * include close tags
+ */
+ private String elementToHtml(Element producedElem, StringBuilder sb) {
+ HashSet<String> booleanAttributes = new HashSet<String>();
+ ArrayList<String> names = new ArrayList<String>();
+ for (Attribute a : producedElem.attributes().asList()) {
+ names.add(a.getKey());
+ if (a instanceof BooleanAttribute) {
+ booleanAttributes.add(a.getKey());
+ }
+ }
+ Collections.sort(names);
+
+ sb.append("<" + producedElem.tagName() + "");
+ for (String attrName : names) {
+ sb.append(" ").append(attrName);
+ if (!booleanAttributes.contains(attrName)) {
+ sb.append("=").append("\'").append(producedElem.attr(attrName))
+ .append("\'");
+ }
+ }
+ sb.append(">");
+ for (Node child : producedElem.childNodes()) {
+ if (child instanceof Element) {
+ elementToHtml((Element) child, sb);
+ } else if (child instanceof TextNode) {
+ String text = ((TextNode) child).text();
+ sb.append(text.trim());
+ }
+ }
+ sb.append("</").append(producedElem.tagName()).append(">");
+ return sb.toString();
+ }
+
+ protected String stripOptionTags(String design) {
+ return design.replaceAll("[ \n]*<option(.*)</option>[ \n]*", "");
+
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/DesignContextLocalIdTest.java b/server/src/test/java/com/vaadin/tests/design/DesignContextLocalIdTest.java
new file mode 100644
index 0000000000..d488b9fc08
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/DesignContextLocalIdTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2000-2014 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.design;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.FileNotFoundException;
+
+import org.jsoup.nodes.Element;
+import org.junit.Test;
+
+import com.vaadin.ui.AbsoluteLayout;
+import com.vaadin.ui.Accordion;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.ComponentContainer;
+import com.vaadin.ui.CssLayout;
+import com.vaadin.ui.CustomLayout;
+import com.vaadin.ui.GridLayout;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.HorizontalSplitPanel;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Panel;
+import com.vaadin.ui.SingleComponentContainer;
+import com.vaadin.ui.TabSheet;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.VerticalSplitPanel;
+import com.vaadin.ui.Window;
+import com.vaadin.ui.declarative.Design;
+import com.vaadin.ui.declarative.DesignContext;
+
+/**
+ * Tests that setting local id via DesignContext works as intended.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class DesignContextLocalIdTest {
+
+ @Test
+ public void testSetLocalId() throws FileNotFoundException {
+ DesignContext ctx = Design.read(
+ getClass().getResourceAsStream("local-ids.html"),
+ new VerticalLayout());
+ TextField tf = (TextField) ctx.getComponentByLocalId("foo");
+ Button b = (Button) ctx.getComponentByLocalId("bar");
+ // A duplicate id should be handled by removing the id from the old
+ // component.
+ ctx.setComponentLocalId(b, "foo");
+ assertEquals("Found the wrong component by local id.",
+ ctx.getComponentByLocalId("foo").getClass(), Button.class);
+ assertEquals("Found the wrong component by local id.",
+ ctx.getComponentByLocalId("bar"), null);
+ // Set an id also for the text field.
+ ctx.setComponentLocalId(tf, "bar");
+ assertEquals("Found the wrong component by local id.",
+ ctx.getComponentByLocalId("foo").getClass(), Button.class);
+ assertEquals("Found the wrong component by local id.",
+ ctx.getComponentByLocalId("bar").getClass(), TextField.class);
+ }
+
+ @Test
+ public void testWriteLocalId() {
+ DesignContext ctx = new DesignContext();
+
+ Button b = new Button();
+ ctx.setComponentLocalId(b, "button-id");
+
+ assertEquals("button-id", ctx.createElement(b).attr("_id"));
+ }
+
+ @Test
+ public void testWriteChildLocalIds() throws Exception {
+ DesignContext ctx = new DesignContext();
+
+ ComponentContainer[] ctrs = { new AbsoluteLayout(), new CssLayout(),
+ new GridLayout(1, 1), new CustomLayout(),
+ new HorizontalLayout(), new VerticalLayout(), new Accordion(),
+ new HorizontalSplitPanel(), new TabSheet(),
+ new VerticalSplitPanel() };
+
+ Button b = new Button();
+ ctx.setComponentLocalId(b, "button-id");
+
+ for (ComponentContainer ctr : ctrs) {
+ ctr.addComponent(b);
+ Element e = ctx.createElement(ctr);
+ assertEquals(
+ "Unexpected child local id for "
+ + ctr.getClass().getSimpleName(),
+ "button-id",
+ e.getElementsByTag("vaadin-button").first().attr("_id"));
+ }
+
+ SingleComponentContainer[] sctrs = { new Window(), new Panel() };
+
+ for (SingleComponentContainer ctr : sctrs) {
+ ctr.setContent(b);
+ Element e = ctx.createElement(ctr);
+ assertEquals(
+ "Unexpected child local id for "
+ + ctr.getClass().getSimpleName(),
+ "button-id",
+ e.getElementsByTag("vaadin-button").first().attr("_id"));
+ }
+ }
+
+ @Test
+ public void testGetLocalId() {
+ DesignContext ctx = new DesignContext();
+ Label label = new Label();
+ ctx.setComponentLocalId(label, "my-local-id");
+ ctx.setRootComponent(label);
+ assertEquals("my-local-id", ctx.getComponentLocalId(label));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/DesignFormatterTest.java b/server/src/test/java/com/vaadin/tests/design/DesignFormatterTest.java
new file mode 100644
index 0000000000..e2a91000c1
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/DesignFormatterTest.java
@@ -0,0 +1,377 @@
+/*
+ * Copyright 2000-2014 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.design;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.TimeZone;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.util.converter.Converter.ConversionException;
+import com.vaadin.event.ShortcutAction;
+import com.vaadin.event.ShortcutAction.KeyCode;
+import com.vaadin.event.ShortcutAction.ModifierKey;
+import com.vaadin.server.ExternalResource;
+import com.vaadin.server.FileResource;
+import com.vaadin.server.FontAwesome;
+import com.vaadin.server.FontIcon;
+import com.vaadin.server.GenericFontIcon;
+import com.vaadin.server.Resource;
+import com.vaadin.server.ThemeResource;
+import com.vaadin.shared.ApplicationConstants;
+import com.vaadin.shared.util.SharedUtil;
+import com.vaadin.ui.declarative.DesignFormatter;
+
+/**
+ * Various tests related to formatter.
+ *
+ * @since 7.4
+ * @author Vaadin Ltd
+ */
+public class DesignFormatterTest {
+
+ private DesignFormatter formatter;
+
+ @Before
+ public void setUp() {
+ // initialise with default classes
+ formatter = new DesignFormatter();
+ }
+
+ @Test
+ public void testSupportedClasses() {
+
+ for (Class<?> type : new Class<?>[] { boolean.class, char.class,
+ byte.class, short.class, int.class, long.class, float.class,
+ double.class, Boolean.class, Character.class, Byte.class,
+ Short.class, Integer.class, Long.class, Float.class,
+ Double.class, BigDecimal.class, String.class,
+ ShortcutAction.class, Date.class, FileResource.class,
+ ExternalResource.class, ThemeResource.class, Resource.class,
+ TimeZone.class }) {
+ assertTrue("not supported " + type.getSimpleName(),
+ formatter.canConvert(type));
+ }
+ }
+
+ @Test
+ public void testBoolean() {
+ assertEquals("", formatter.format(true));
+ assertEquals("false", formatter.format(false));
+
+ assertEquals(true, formatter.parse("true", boolean.class));
+ assertEquals(true, formatter.parse("foobar", boolean.class));
+ assertEquals(true, formatter.parse("", boolean.class));
+ assertEquals(false, formatter.parse("false", boolean.class));
+
+ assertEquals(true, formatter.parse("true", Boolean.class));
+ assertEquals(true, formatter.parse("foobar", Boolean.class));
+ assertEquals(true, formatter.parse("", Boolean.class));
+ assertEquals(false, formatter.parse("false", Boolean.class));
+ }
+
+ @Test
+ public void testIntegral() {
+ byte b = 123;
+ assertEquals("123", formatter.format(b));
+ assertEquals(b, (byte) formatter.parse("123", byte.class));
+ assertEquals((Byte) b, formatter.parse("123", Byte.class));
+
+ b = -123;
+ assertEquals("-123", formatter.format(b));
+ assertEquals(b, (byte) formatter.parse("-123", byte.class));
+ assertEquals((Byte) b, formatter.parse("-123", Byte.class));
+
+ short s = 12345;
+ assertEquals("12345", formatter.format(s));
+ assertEquals(s, (short) formatter.parse("12345", short.class));
+ assertEquals((Short) s, formatter.parse("12345", Short.class));
+
+ s = -12345;
+ assertEquals("-12345", formatter.format(s));
+ assertEquals(s, (short) formatter.parse("-12345", short.class));
+ assertEquals((Short) s, formatter.parse("-12345", Short.class));
+
+ int i = 123456789;
+ assertEquals("123456789", formatter.format(i));
+ assertEquals(i, (int) formatter.parse("123456789", int.class));
+ assertEquals((Integer) i, formatter.parse("123456789", Integer.class));
+
+ i = -123456789;
+ assertEquals("-123456789", formatter.format(i));
+ assertEquals(i, (int) formatter.parse("-123456789", int.class));
+ assertEquals((Integer) i, formatter.parse("-123456789", Integer.class));
+
+ long l = 123456789123456789L;
+ assertEquals("123456789123456789", formatter.format(l));
+ assertEquals(l,
+ (long) formatter.parse("123456789123456789", long.class));
+ assertEquals((Long) l,
+ formatter.parse("123456789123456789", Long.class));
+
+ l = -123456789123456789L;
+ assertEquals("-123456789123456789", formatter.format(l));
+ assertEquals(l,
+ (long) formatter.parse("-123456789123456789", long.class));
+ assertEquals((Long) l,
+ formatter.parse("-123456789123456789", Long.class));
+ }
+
+ @Test
+ public void testFloatingPoint() {
+ float f = 123.4567f;
+ assertEquals("123.457", formatter.format(f));
+
+ float f1 = formatter.parse("123.4567", float.class);
+ assertEquals(f, f1, 1e-4);
+ Float f2 = formatter.parse("123.4567", Float.class);
+ assertEquals(f, f2, 1e-4);
+
+ double d = 123456789.123456789;
+ assertEquals("123456789.123", formatter.format(d));
+ assertEquals(d, formatter.parse("123456789.123456789", double.class),
+ 1e-9);
+ assertEquals(d, formatter.parse("123456789.123456789", Double.class),
+ 1e-9);
+
+ }
+
+ @Test
+ public void testBigDecimal() {
+ BigDecimal bd = new BigDecimal("123456789123456789.123456789123456789");
+ assertEquals("123456789123456789.123", formatter.format(bd));
+ assertEquals(bd, formatter.parse(
+ "123456789123456789.123456789123456789", BigDecimal.class));
+ }
+
+ @Test
+ public void testChar() {
+ char c = '\uABCD';
+ assertEquals("\uABCD", formatter.format(c));
+ assertEquals(c, (char) formatter.parse("\uABCD", char.class));
+ assertEquals((Character) c, formatter.parse("\uABCD", Character.class));
+
+ c = 'y';
+ assertEquals(c, (char) formatter.parse("yes", char.class));
+ }
+
+ @Test
+ public void testString() {
+
+ for (String s : new String[] { "", "foobar", "\uABCD", "驯鹿" }) {
+ assertEquals(s, formatter.format(s));
+ assertEquals(s, formatter.parse(s, String.class));
+ }
+ }
+
+ @Test
+ public void testDate() throws Exception {
+ Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2012-02-17");
+ String formatted = formatter.format(date);
+ Date result = formatter.parse(formatted, Date.class);
+
+ // writing will always give full date string
+ assertEquals("2012-02-17 00:00:00+0200", formatted);
+ assertEquals(date, result);
+
+ // try short date as well
+ result = formatter.parse("2012-02-17", Date.class);
+ assertEquals(date, result);
+ }
+
+ @Test
+ public void testShortcutActions() {
+ ShortcutAction action = new ShortcutAction("&^d");
+ String formatted = formatter.format(action);
+ // note the space here - it separates key combination from caption
+ assertEquals("ctrl-alt-d d", formatted);
+
+ ShortcutAction result = formatter
+ .parse(formatted, ShortcutAction.class);
+ assertTrue(equals(action, result));
+ }
+
+ @Test
+ public void testShortcutActionNoCaption() {
+ ShortcutAction action = new ShortcutAction(null, KeyCode.D, new int[] {
+ ModifierKey.ALT, ModifierKey.CTRL });
+ String formatted = formatter.format(action);
+ assertEquals("ctrl-alt-d", formatted);
+
+ ShortcutAction result = formatter
+ .parse(formatted, ShortcutAction.class);
+ assertTrue(equals(action, result));
+ }
+
+ @Test
+ public void testInvalidShortcutAction() {
+ assertInvalidShortcut("-");
+ assertInvalidShortcut("foo");
+ assertInvalidShortcut("atl-ctrl");
+ assertInvalidShortcut("-a");
+ }
+
+ protected void assertInvalidShortcut(String shortcut) {
+ try {
+ formatter.parse(shortcut, ShortcutAction.class);
+ Assert.fail("Invalid shortcut '" + shortcut + "' should throw");
+ } catch (ConversionException e) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testTimeZone() {
+ TimeZone zone = TimeZone.getTimeZone("GMT+2");
+ String formatted = formatter.format(zone);
+ assertEquals("GMT+02:00", formatted);
+ TimeZone result = formatter.parse(formatted, TimeZone.class);
+ assertEquals(zone, result);
+ // try shorthand notation as well
+ result = formatter.parse("GMT+2", TimeZone.class);
+ assertEquals(zone, result);
+ }
+
+ @Test
+ public void testExternalResource() {
+ String url = "://example.com/my%20icon.png?a=b";
+
+ for (String scheme : new String[] { "http", "https", "ftp", "ftps" }) {
+ Resource resource = formatter.parse(scheme + url, Resource.class);
+
+ assertTrue(scheme + " url should be parsed as ExternalResource",
+ resource instanceof ExternalResource);
+ assertEquals("parsed ExternalResource", scheme + url,
+ ((ExternalResource) resource).getURL());
+
+ String formatted = formatter.format(new ExternalResource(scheme
+ + url));
+
+ assertEquals("formatted ExternalResource", scheme + url, formatted);
+ }
+ }
+
+ @Test
+ public void testResourceFormat() {
+ String httpUrl = "http://example.com/icon.png";
+ String httpsUrl = "https://example.com/icon.png";
+ String themePath = "icons/icon.png";
+ String fontAwesomeUrl = "fonticon://FontAwesome/f0f9";
+ String someOtherFontUrl = "fonticon://SomeOther/F0F9";
+ String fileSystemPath = "c:\\app\\resources\\icon.png";
+
+ assertEquals(httpUrl, formatter.format(new ExternalResource(httpUrl)));
+ assertEquals(httpsUrl, formatter.format(new ExternalResource(httpsUrl)));
+ assertEquals(ApplicationConstants.THEME_PROTOCOL_PREFIX + themePath,
+ formatter.format(new ThemeResource(themePath)));
+
+ assertEquals(fontAwesomeUrl, formatter.format(FontAwesome.AMBULANCE));
+ assertEquals(someOtherFontUrl.toLowerCase(),
+ formatter.format(new GenericFontIcon("SomeOther", 0xf0f9))
+ .toLowerCase());
+
+ assertEquals(fileSystemPath,
+ formatter.format(new FileResource(new File(fileSystemPath))));
+ }
+
+ @Test(expected = ConversionException.class)
+ public void testResourceParseException() {
+ String someRandomResourceUrl = "random://url";
+ formatter.parse(someRandomResourceUrl, Resource.class);
+ }
+
+ @Test(expected = ConversionException.class)
+ public void testResourceFormatException() {
+ formatter.format(new Resource() { // must use unknown resource type
+ @Override
+ public String getMIMEType() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ });
+ }
+
+ @Test
+ public void testResourceParse() {
+ String httpUrl = "http://example.com/icon.png";
+ String httpsUrl = "https://example.com/icon.png";
+ String themePath = "icons/icon.png";
+ String fontAwesomeUrl = "fonticon://FontAwesome/f0f9";
+ String someOtherFont = "fonticon://SomeOther/F0F9";
+ String fontAwesomeUrlOld = "font://AMBULANCE";
+ String fileSystemPath = "c:\\app\\resources\\icon.png";
+
+ assertEquals(new ExternalResource(httpUrl).getURL(),
+ formatter.parse(httpUrl, ExternalResource.class).getURL());
+ assertEquals(new ExternalResource(httpsUrl).getURL(),
+ formatter.parse(httpsUrl, ExternalResource.class).getURL());
+ assertEquals(
+ new ThemeResource(themePath),
+ formatter.parse(ApplicationConstants.THEME_PROTOCOL_PREFIX
+ + themePath, ThemeResource.class));
+ assertEquals(FontAwesome.AMBULANCE,
+ formatter.parse(fontAwesomeUrlOld, FontAwesome.class));
+ assertEquals(FontAwesome.AMBULANCE,
+ formatter.parse(fontAwesomeUrl, FontAwesome.class));
+ assertEquals(new GenericFontIcon("SomeOther", 0xF0F9),
+ formatter.parse(someOtherFont, FontIcon.class));
+
+ assertEquals(
+ new FileResource(new File(fileSystemPath)).getSourceFile(),
+ formatter.parse(fileSystemPath, FileResource.class)
+ .getSourceFile());
+
+ }
+
+ /**
+ * A static method to allow comparison two different actions.
+ *
+ * @param act
+ * One action to compare.
+ * @param other
+ * Second action to compare.
+ * @return <b>true</b> when both actions are the same (caption, icon, and
+ * key combination).
+ */
+ public static final boolean equals(ShortcutAction act, ShortcutAction other) {
+ if (SharedUtil.equals(other.getCaption(), act.getCaption())
+ && SharedUtil.equals(other.getIcon(), act.getIcon())
+ && act.getKeyCode() == other.getKeyCode()
+ && act.getModifiers().length == other.getModifiers().length) {
+ HashSet<Integer> thisSet = new HashSet<Integer>(
+ act.getModifiers().length);
+ // this is a bit tricky comparison, but there is no nice way of
+ // making int[] into a Set
+ for (int mod : act.getModifiers()) {
+ thisSet.add(mod);
+ }
+ for (int mod : other.getModifiers()) {
+ thisSet.remove(mod);
+ }
+ return thisSet.isEmpty();
+ }
+ return false;
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/DesignReadInConstructor.java b/server/src/test/java/com/vaadin/tests/design/DesignReadInConstructor.java
new file mode 100644
index 0000000000..6eccaf6a2c
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/DesignReadInConstructor.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2014 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.design;
+
+import com.vaadin.ui.CssLayout;
+import com.vaadin.ui.declarative.Design;
+
+public class DesignReadInConstructor extends CssLayout {
+
+ public DesignReadInConstructor() {
+ Design.read(
+ getClass().getResourceAsStream("DesignReadInConstructor.html"),
+ this);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/DesignReadInConstructorTest.java b/server/src/test/java/com/vaadin/tests/design/DesignReadInConstructorTest.java
new file mode 100644
index 0000000000..539595762d
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/DesignReadInConstructorTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2000-2014 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.design;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Attribute;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.junit.Assert;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import com.vaadin.ui.declarative.Design;
+
+public class DesignReadInConstructorTest {
+
+ @Test
+ public void useDesignReadInConstructor() {
+ DesignReadInConstructor dric = new DesignReadInConstructor();
+ Assert.assertEquals(3, dric.getComponentCount());
+ }
+
+ @Test
+ @Ignore("Can't currently work. There is no way to write a custom component which manually reads its design in the constructor")
+ public void readAndWriteDesignReadInConstructor() throws IOException {
+ DesignReadInConstructor dric = new DesignReadInConstructor();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Design.write(dric, baos);
+ Document doc = Jsoup.parse(baos.toString("UTF-8"));
+
+ Document d = Jsoup.parse(
+ getClass().getResourceAsStream("DesignReadInConstructor.html"),
+ "UTF-8", "");
+ assertJsoupTreeEquals(d.body().child(0), doc.body().child(0));
+ }
+
+ private void assertJsoupTreeEquals(Element expected, Element actual) {
+ Assert.assertEquals(expected.tagName(), actual.tagName());
+
+ Set<String> keys = new HashSet<String>();
+
+ for (Attribute attr : expected.attributes().asList()) {
+ keys.add(attr.getKey());
+ }
+ for (Attribute attr : actual.attributes().asList()) {
+ keys.add(attr.getKey());
+ }
+ for (String attributeKey : keys) {
+ Assert.assertEquals(expected.attr(attributeKey),
+ actual.attr(attributeKey));
+ }
+
+ Assert.assertEquals(expected.children().size(), actual.children()
+ .size());
+ for (int i = 0; i < expected.children().size(); i++) {
+ assertJsoupTreeEquals(expected.child(i), actual.child(i));
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/DesignTest.java b/server/src/test/java/com/vaadin/tests/design/DesignTest.java
new file mode 100644
index 0000000000..cf19aecb87
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/DesignTest.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2000-2014 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.design;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Iterator;
+
+import org.junit.Assert;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.HasComponents;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Panel;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.declarative.Design;
+import com.vaadin.ui.declarative.DesignContext;
+import com.vaadin.ui.declarative.DesignException;
+
+public class DesignTest {
+
+ @Test
+ public void readStream() throws FileNotFoundException {
+ Component root = Design.read(getClass()
+ .getResourceAsStream("verticallayout-two-children.html"));
+ VerticalLayout rootLayout = (VerticalLayout) root;
+ Assert.assertEquals(VerticalLayout.class, root.getClass());
+
+ Assert.assertEquals(2, rootLayout.getComponentCount());
+ Assert.assertEquals(TextField.class,
+ rootLayout.getComponent(0).getClass());
+ Assert.assertEquals(Button.class,
+ rootLayout.getComponent(1).getClass());
+ }
+
+ @Test(expected = DesignException.class)
+ @Ignore("Feature needs to be fixed")
+ public void readWithIncorrectRoot() throws FileNotFoundException {
+ Design.read(
+ getClass().getResourceAsStream("verticallayout-one-child.html"),
+ new Panel());
+ }
+
+ public static class MyVerticalLayout extends VerticalLayout {
+
+ }
+
+ @Test
+ public void readWithSubClassRoot() throws FileNotFoundException {
+ Design.read(
+ getClass().getResourceAsStream("verticallayout-one-child.html"),
+ new MyVerticalLayout());
+ }
+
+ @Test
+ public void writeComponentToStream() throws IOException {
+ HorizontalLayout root = new HorizontalLayout(new Button("OK"),
+ new Button("Cancel"));
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Design.write(root, baos);
+ Component newRoot = Design
+ .read(new ByteArrayInputStream(baos.toByteArray()));
+
+ assertHierarchyEquals(root, newRoot);
+ }
+
+ @Test
+ public void writeDesignContextToStream() throws IOException {
+ DesignContext dc = Design.read(getClass()
+ .getResourceAsStream("verticallayout-two-children.html"), null);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Design.write(dc, baos);
+ Component newRoot = Design
+ .read(new ByteArrayInputStream(baos.toByteArray()));
+
+ assertHierarchyEquals(dc.getRootComponent(), newRoot);
+ }
+
+ @Test(expected = DesignException.class)
+ public void testDuplicateIds() throws FileNotFoundException {
+ Design.read(getClass().getResourceAsStream("duplicate-ids.html"));
+ }
+
+ @Test(expected = DesignException.class)
+ public void testDuplicateLocalIds() throws FileNotFoundException {
+ Design.read(getClass().getResourceAsStream("duplicate-local-ids.html"));
+ }
+
+ private void assertHierarchyEquals(Component expected, Component actual) {
+ if (expected.getClass() != actual.getClass()) {
+ throw new AssertionError(
+ "Component classes do not match. Expected: "
+ + expected.getClass().getName() + ", was: "
+ + actual.getClass().getName());
+ }
+
+ if (expected instanceof HasComponents) {
+ HasComponents expectedHC = (HasComponents) expected;
+ HasComponents actualHC = (HasComponents) actual;
+ Iterator<Component> eI = expectedHC.iterator();
+ Iterator<Component> aI = actualHC.iterator();
+
+ while (eI.hasNext()) {
+ assertHierarchyEquals(eI.next(), aI.next());
+ }
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/EmbeddedsTest.java b/server/src/test/java/com/vaadin/tests/design/EmbeddedsTest.java
new file mode 100644
index 0000000000..4c9e323948
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/EmbeddedsTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2000-2014 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.design;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import org.junit.Test;
+
+import com.vaadin.server.ExternalResource;
+import com.vaadin.shared.util.SharedUtil;
+import com.vaadin.ui.AbstractEmbedded;
+import com.vaadin.ui.BrowserFrame;
+import com.vaadin.ui.Embedded;
+import com.vaadin.ui.Flash;
+import com.vaadin.ui.Image;
+import com.vaadin.ui.declarative.Design;
+
+/**
+ * Tests declarative support for implementations of {@link AbstractEmbedded} and
+ * {@link Embedded}.
+ *
+ * @since 7.4
+ * @author Vaadin Ltd
+ */
+public class EmbeddedsTest {
+
+ public static final boolean equals(ExternalResource obj,
+ ExternalResource other) {
+ return SharedUtil.equals(obj.getURL(), other.getURL())
+ && SharedUtil.equals(obj.getMIMEType(), other.getMIMEType());
+ }
+
+ @Test
+ public void testAbstractEmbeddedsToFromDesign() throws Exception {
+ for (AbstractEmbedded ae : new AbstractEmbedded[] { new Image(),
+ new Flash(), new BrowserFrame() }) {
+ ae.setSource(new ExternalResource("http://www.example.org"));
+ ae.setAlternateText("some alternate text");
+ ae.setCaption("some <b>caption</b>");
+ ae.setCaptionAsHtml(true);
+ ae.setDescription("some description");
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ Design.write(ae, bos);
+ AbstractEmbedded result = (AbstractEmbedded) Design
+ .read(new ByteArrayInputStream(bos.toByteArray()));
+ assertTrue(equals((ExternalResource) ae.getSource(),
+ (ExternalResource) result.getSource()));
+ assertEquals(ae.getAlternateText(), result.getAlternateText());
+ assertEquals(ae.getCaption(), result.getCaption());
+ assertEquals(ae.isCaptionAsHtml(), result.isCaptionAsHtml());
+ assertEquals(ae.getDescription(), result.getDescription());
+ }
+ }
+
+ @Test
+ public void testFlashToFromDesign() throws Exception {
+ Flash ae = new Flash();
+ ae.setSource(new ExternalResource("http://www.example.org"));
+ ae.setAlternateText("some alternate text");
+ ae.setCaption("some <b>caption</b>");
+ ae.setCaptionAsHtml(true);
+ ae.setDescription("some description");
+ ae.setCodebase("codebase");
+ ae.setArchive("archive");
+ ae.setCodetype("codetype");
+ ae.setParameter("foo", "bar");
+ ae.setParameter("something", "else");
+ ae.setStandby("foobar");
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ Design.write(ae, bos);
+ Flash result = (Flash) Design.read(new ByteArrayInputStream(bos
+ .toByteArray()));
+ assertTrue(equals((ExternalResource) ae.getSource(),
+ (ExternalResource) result.getSource()));
+ assertEquals(ae.getAlternateText(), result.getAlternateText());
+ assertEquals(ae.getCaption(), result.getCaption());
+ assertEquals(ae.isCaptionAsHtml(), result.isCaptionAsHtml());
+ assertEquals(ae.getDescription(), result.getDescription());
+ assertEquals(ae.getCodebase(), result.getCodebase());
+ assertEquals(ae.getArchive(), result.getArchive());
+ assertEquals(ae.getCodetype(), result.getCodetype());
+ assertEquals(ae.getParameter("foo"), result.getParameter("foo"));
+ assertEquals(ae.getParameter("something"),
+ result.getParameter("something"));
+ assertEquals(ae.getStandby(), result.getStandby());
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/FieldNameWhichConflictsWithGettersTest.java b/server/src/test/java/com/vaadin/tests/design/FieldNameWhichConflictsWithGettersTest.java
new file mode 100644
index 0000000000..8c8d7b78b1
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/FieldNameWhichConflictsWithGettersTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2000-2014 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.design;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.annotations.DesignRoot;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.declarative.Design;
+import com.vaadin.ui.declarative.DesignContext;
+
+public class FieldNameWhichConflictsWithGettersTest {
+
+ @DesignRoot("MyVerticalLayout.html")
+ public static class MyVerticalLayout extends VerticalLayout {
+ private Label caption;
+ private TextField description;
+
+ public MyVerticalLayout() {
+ Design.read(this);
+ }
+ }
+
+ @Test
+ public void readWithConflictingFields() {
+ MyVerticalLayout v = new MyVerticalLayout();
+ Assert.assertNotNull(v.caption);
+ Assert.assertNotNull(v.description);
+ }
+
+ @Test
+ public void writeWithConflictingFields() throws IOException {
+ VerticalLayout v = new VerticalLayout();
+ Label l = new Label();
+ l.setId("caption");
+ TextField tf = new TextField();
+ v.addComponents(l, tf);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ DesignContext context = new DesignContext();
+ context.setComponentLocalId(tf, "description");
+ context.setRootComponent(v);
+
+ Design.write(context, baos);
+ String str = baos.toString("UTF-8");
+
+ Document doc = Jsoup.parse(str);
+ Element body = doc.body();
+ Element captionElement = body.getElementById("caption");
+ Assert.assertNotNull(captionElement);
+ Assert.assertEquals("vaadin-label", captionElement.tagName());
+
+ Element descriptionElement = captionElement.nextElementSibling();
+ Assert.assertNotNull(descriptionElement);
+ Assert.assertEquals("vaadin-text-field", descriptionElement.tagName());
+ Assert.assertEquals("description", descriptionElement.attr("_id"));
+
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/InvalidLayoutTemplate.java b/server/src/test/java/com/vaadin/tests/design/InvalidLayoutTemplate.java
new file mode 100644
index 0000000000..8a2dec5a35
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/InvalidLayoutTemplate.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2000-2014 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.design;
+
+import com.vaadin.ui.Button;
+import com.vaadin.ui.NativeButton;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.VerticalLayout;
+
+/**
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class InvalidLayoutTemplate extends VerticalLayout {
+ private NativeButton firstButton;
+ private NativeButton secondButton;
+ private NativeButton yetanotherbutton; // generated based on caption
+ private Button clickme; // generated based on caption
+ private TextField shouldNotBeMapped;
+
+ public NativeButton getFirstButton() {
+ return firstButton;
+ }
+
+ public NativeButton getSecondButton() {
+ return secondButton;
+ }
+
+ public NativeButton getYetanotherbutton() {
+ return yetanotherbutton;
+ }
+
+ public Button getClickme() {
+ return clickme;
+ }
+
+ public TextField getShouldNotBeMapped() {
+ return shouldNotBeMapped;
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/InvalidTagNames.java b/server/src/test/java/com/vaadin/tests/design/InvalidTagNames.java
new file mode 100644
index 0000000000..9f405f4e56
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/InvalidTagNames.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2000-2014 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.design;
+
+import java.io.ByteArrayInputStream;
+import java.io.UnsupportedEncodingException;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.declarative.Design;
+import com.vaadin.ui.declarative.DesignException;
+
+public class InvalidTagNames {
+
+ @Test(expected = DesignException.class)
+ public void tagWithoutDash() {
+ readDesign("<vbutton>foo</vbutton>");
+ }
+
+ @Test
+ public void emptyTag() {
+ // JSoup parses empty tags into text nodes
+ Component c = readDesign("<>foo</>");
+ Assert.assertNull(c);
+ }
+
+ @Test(expected = DesignException.class)
+ public void onlyPrefix() {
+ readDesign("<vaadin->foo</vaadin->");
+ }
+
+ @Test
+ public void onlyClass() {
+ // JSoup will refuse to parse tags starting with - and convert them into
+ // text nodes instead
+ Component c = readDesign("<-v>foo</-v>");
+ Assert.assertNull(c);
+ }
+
+ @Test(expected = DesignException.class)
+ public void unknownClass() {
+ readDesign("<vaadin-unknownbutton>foo</vaadin-unknownbutton>");
+ }
+
+ @Test(expected = DesignException.class)
+ public void unknownTag() {
+ readDesign("<x-button></x-button>");
+ }
+
+ // @Test(expected = DesignException.class)
+ // This is a side effect of not actively checking for invalid input. Will be
+ // parsed currently as <vaadin-button> (this should not be considered API)
+ public void tagEndsInDash() {
+ Component c = readDesign("<vaadin-button-></vaadin-button->");
+ Assert.assertTrue(c.getClass() == Button.class);
+ }
+
+ // @Test(expected = DesignException.class)
+ // This is a side effect of not actively checking for invalid input. Will be
+ // parsed currently as <vaadin-button> (this should not be considered API)
+ public void tagEndsInTwoDashes() {
+ Component c = readDesign("<vaadin-button--></vaadin-button-->");
+ Assert.assertTrue(c.getClass() == Button.class);
+ }
+
+ // @Test(expected = DesignException.class)
+ // This is a side effect of not actively checking for invalid input. Will be
+ // parsed currently as <vaadin-button> (this should not be considered API)
+ public void tagWithTwoDashes() {
+ Component c = readDesign("<vaadin--button></vaadin--button>");
+ Assert.assertTrue(c.getClass() == Button.class);
+ }
+
+ @Test(expected = DesignException.class)
+ public void specialCharacters() {
+ readDesign("<vaadin-button-&!#></vaadin-button-&!#>");
+ }
+
+ private Component readDesign(String string) {
+ try {
+ return Design.read(new ByteArrayInputStream(string
+ .getBytes("UTF-8")));
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/LayoutTemplate.java b/server/src/test/java/com/vaadin/tests/design/LayoutTemplate.java
new file mode 100644
index 0000000000..fdfddf5c08
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/LayoutTemplate.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2000-2014 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.design;
+
+import com.vaadin.ui.Button;
+import com.vaadin.ui.NativeButton;
+import com.vaadin.ui.VerticalLayout;
+
+/**
+ * Template to be populated in the tests
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class LayoutTemplate extends VerticalLayout {
+ private NativeButton firstButton; // assigned based on local id
+ private NativeButton secondButton; // assigned based on id
+ private NativeButton yetanotherbutton; // assigned based on caption
+ private Button clickme; // assigned based on caption
+
+ public NativeButton getFirstButton() {
+ return firstButton;
+ }
+
+ public NativeButton getSecondButton() {
+ return secondButton;
+ }
+
+ public NativeButton getYetanotherbutton() {
+ return yetanotherbutton;
+ }
+
+ public Button getClickme() {
+ return clickme;
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/LocaleTest.java b/server/src/test/java/com/vaadin/tests/design/LocaleTest.java
new file mode 100644
index 0000000000..6cb288db23
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/LocaleTest.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2000-2014 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.design;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.util.Locale;
+
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.DocumentType;
+import org.jsoup.nodes.Element;
+import org.jsoup.nodes.Node;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.declarative.Design;
+import com.vaadin.ui.declarative.DesignContext;
+
+/**
+ * Tests the handling of the locale property in parsing and html generation.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class LocaleTest {
+ DesignContext ctx;
+
+ @Before
+ public void setUp() {
+ ctx = new DesignContext();
+ }
+
+ /*
+ * Checks that when the html corresponding to a component hierarchy is
+ * constructed, the result only contains locale attributes for a component
+ * if its locale differs from that of its parent.
+ */
+ @Test
+ public void testHtmlGeneration() {
+ // create a component hierarchy
+ VerticalLayout vLayout = new VerticalLayout();
+ vLayout.setLocale(Locale.US);
+ HorizontalLayout hLayout = new HorizontalLayout();
+ hLayout.setLocale(Locale.ITALY);
+ vLayout.addComponent(hLayout);
+ Button b1 = new Button();
+ b1.setLocale(Locale.ITALY);
+ Button b2 = new Button();
+ b2.setLocale(Locale.US);
+ hLayout.addComponent(b1);
+ hLayout.addComponent(b2);
+ HorizontalLayout hlayout2 = new HorizontalLayout();
+ hlayout2.setLocale(Locale.US);
+ vLayout.addComponent(hlayout2);
+ Label l = new Label();
+ l.setLocale(Locale.US);
+ hlayout2.addComponent(l);
+ Label l2 = new Label();
+ l2.setLocale(Locale.CANADA);
+ hlayout2.addComponent(l2);
+ ctx.setRootComponent(vLayout);
+ // create the html tree corresponding to the component hierarchy
+ Document doc = componentToDoc(ctx);
+ // check the created html
+ Element body = doc.body();
+ Element evLayout = body.child(0);
+ assertEquals("Wrong locale information.", "en_US",
+ evLayout.attr("locale"));
+ Element ehLayout = evLayout.child(0);
+ assertEquals("Wrong locale information.", "it_IT",
+ ehLayout.attr("locale"));
+ Element eb1 = ehLayout.child(0);
+ assertTrue(
+ "The element should not have a locale specification, found locale "
+ + eb1.attr("locale"), "".equals(eb1.attr("locale")));
+ Element eb2 = ehLayout.child(1);
+ assertEquals("Wrong locale information.", "en_US", eb2.attr("locale"));
+ Element ehLayout2 = evLayout.child(1);
+ assertTrue(
+ "The element should not have a locale specification, found locale "
+ + ehLayout2.attr("locale"),
+ "".equals(ehLayout2.attr("locale")));
+ Element el1 = ehLayout2.child(0);
+ assertTrue(
+ "The element should not have a locale specification, found locale "
+ + el1.attr("locale"), "".equals(el1.attr("locale")));
+ Element el2 = ehLayout2.child(1);
+ assertEquals("Wrong locale information.", "en_CA", el2.attr("locale"));
+ }
+
+ private Document componentToDoc(DesignContext dc) {
+ // Create the html tree skeleton.
+ Document doc = new Document("");
+ DocumentType docType = new DocumentType("html", "", "", "");
+ doc.appendChild(docType);
+ Element html = doc.createElement("html");
+ doc.appendChild(html);
+ html.appendChild(doc.createElement("head"));
+ Element body = doc.createElement("body");
+ html.appendChild(body);
+ dc.writePackageMappings(doc);
+
+ // Append the design under <body> in the html tree. createNode
+ // creates the entire component hierarchy rooted at the
+ // given root node.
+ Component root = dc.getRootComponent();
+ Node rootNode = dc.createElement(root);
+ body.appendChild(rootNode);
+ return doc;
+
+ }
+
+ /*
+ * Checks that the locale of a component is set when the html element
+ * corresponding to the component specifies a locale.
+ */
+ @Test
+ public void testParsing() {
+ // create an html document
+ Document doc = new Document("");
+ DocumentType docType = new DocumentType("html", "", "", "");
+ doc.appendChild(docType);
+ Element html = doc.createElement("html");
+ doc.appendChild(html);
+ html.appendChild(doc.createElement("head"));
+ Element body = doc.createElement("body");
+ html.appendChild(body);
+ Element evLayout = doc.createElement("vaadin-vertical-layout");
+ evLayout.attr("locale", "en_US");
+ body.appendChild(evLayout);
+ Element ehLayout = doc.createElement("vaadin-horizontal-layout");
+ evLayout.appendChild(ehLayout);
+ Element eb1 = doc.createElement("vaadin-button");
+ eb1.attr("locale", "en_US");
+ ehLayout.appendChild(eb1);
+ Element eb2 = doc.createElement("vaadin-button");
+ eb2.attr("locale", "en_GB");
+ ehLayout.appendChild(eb2);
+ Element eb3 = doc.createElement("vaadin-button");
+ ehLayout.appendChild(eb3);
+
+ // parse the created document and check the constructed component
+ // hierarchy
+ String string = doc.html();
+ VerticalLayout vLayout = (VerticalLayout) Design
+ .read(new ByteArrayInputStream(string.getBytes()));
+ assertEquals("Wrong locale.", new Locale("en", "US"),
+ vLayout.getLocale());
+ HorizontalLayout hLayout = (HorizontalLayout) vLayout.getComponent(0);
+ assertEquals("The element should have the same locale as its parent.",
+ vLayout.getLocale(), hLayout.getLocale());
+ Button b1 = (Button) hLayout.getComponent(0);
+ assertEquals("Wrong locale.", new Locale("en", "US"), b1.getLocale());
+ Button b2 = (Button) hLayout.getComponent(1);
+ assertEquals("Wrong locale.", new Locale("en", "GB"), b2.getLocale());
+ Button b3 = (Button) hLayout.getComponent(2);
+ assertEquals(
+ "The component should have the same locale as its parent.",
+ hLayout.getLocale(), b3.getLocale());
+ }
+} \ No newline at end of file
diff --git a/server/src/test/java/com/vaadin/tests/design/ParseAllSupportedComponentsTest.java b/server/src/test/java/com/vaadin/tests/design/ParseAllSupportedComponentsTest.java
new file mode 100644
index 0000000000..54902c29fe
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/ParseAllSupportedComponentsTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2000-2014 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.design;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.io.FileNotFoundException;
+
+import org.junit.Test;
+
+import com.vaadin.ui.declarative.Design;
+import com.vaadin.ui.declarative.DesignContext;
+
+/**
+ * Just top level test case that contains all synchronizable components
+ *
+ * @author Vaadin Ltd
+ */
+public class ParseAllSupportedComponentsTest {
+
+ @Test
+ public void allComponentsAreParsed() throws FileNotFoundException {
+ DesignContext ctx = Design.read(
+ getClass().getResourceAsStream("all-components.html"), null);
+
+ assertThat(ctx, is(not(nullValue())));
+ assertThat(ctx.getRootComponent(), is(not(nullValue())));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/ParseLayoutTest.java b/server/src/test/java/com/vaadin/tests/design/ParseLayoutTest.java
new file mode 100644
index 0000000000..784c986e1c
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/ParseLayoutTest.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright 2000-2014 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.design;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.nodes.Node;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.ui.Component;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.TextArea;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.declarative.Design;
+import com.vaadin.ui.declarative.DesignContext;
+import com.vaadin.ui.declarative.DesignException;
+
+/**
+ * A test for checking that parsing a layout preserves the IDs and the mapping
+ * from prefixes to package names (for example
+ * <meta name=”package-mapping” content=”my:com.addon.mypackage” />)
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class ParseLayoutTest {
+ // The context is used for accessing the created component hierarchy.
+ private DesignContext ctx;
+
+ @Before
+ public void setUp() throws Exception {
+ ctx = Design.read(getClass().getResourceAsStream("testFile.html"),
+ null);
+ }
+
+ @Test
+ public void buttonWithIdIsParsed() {
+ Component button = ctx.getComponentByLocalId("firstButton");
+
+ assertThat(ctx.getComponentByCaption("Native click me"), is(button));
+ assertThat(button.getCaption(), is("Native click me"));
+ }
+
+ @Test
+ public void buttonWithIdAndLocalIdIsParsed() {
+ Component button = ctx.getComponentById("secondButton");
+
+ assertThat(ctx.getComponentByCaption("Another button"), is(button));
+ assertThat(ctx.getComponentByLocalId("localID"), is(button));
+ assertThat(button.getCaption(), is("Another button"));
+ }
+
+ @Test
+ public void buttonWithoutIdsIsParsed() {
+ assertThat(ctx.getComponentByCaption("Yet another button"),
+ is(not(nullValue())));
+ }
+
+ @Test
+ public void serializationPreservesProperties() throws IOException {
+ ByteArrayOutputStream out = serializeDesign(ctx);
+ ctx = deSerializeDesign(out);
+
+ assertButtonProperties();
+ }
+
+ @Test
+ public void serializationPreservesHierarchy() throws IOException {
+ ByteArrayOutputStream out = serializeDesign(ctx);
+ ctx = deSerializeDesign(out);
+
+ assertComponentHierarchy();
+ }
+
+ @Test
+ public void designIsSerializedWithCorrectPrefixesAndPackageNames()
+ throws IOException {
+ ByteArrayOutputStream out = serializeDesign(ctx);
+
+ // Check the mapping from prefixes to package names using the html tree
+ String[] expectedPrefixes = { "my" };
+ String[] expectedPackageNames = { "com.addon.mypackage" };
+ int index = 0;
+
+ Document doc = Jsoup.parse(out.toString("UTF-8"));
+ Element head = doc.head();
+ for (Node child : head.childNodes()) {
+ if ("meta".equals(child.nodeName())) {
+ String name = child.attributes().get("name");
+ if ("package-mapping".equals(name)) {
+ String content = child.attributes().get("content");
+ String[] parts = content.split(":");
+ assertEquals("Unexpected prefix.", expectedPrefixes[index],
+ parts[0]);
+ assertEquals("Unexpected package name.",
+ expectedPackageNames[index], parts[1]);
+ index++;
+ }
+ }
+ }
+ assertEquals("Unexpected number of prefix - package name pairs.", 1,
+ index);
+ }
+
+ private DesignContext deSerializeDesign(ByteArrayOutputStream out) {
+ ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+ return Design.read(in, null);
+ }
+
+ private ByteArrayOutputStream serializeDesign(DesignContext context)
+ throws IOException {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ Design.write(context, out);
+
+ return out;
+ }
+
+ private void assertButtonProperties() {
+ buttonWithIdAndLocalIdIsParsed();
+ buttonWithIdIsParsed();
+ buttonWithoutIdsIsParsed();
+ }
+
+ @Test
+ public void fieldsAreBoundToATemplate() throws IOException {
+ LayoutTemplate template = new LayoutTemplate();
+ InputStream htmlFile = getClass().getResourceAsStream("testFile.html");
+ Design.read(htmlFile, template);
+ assertNotNull(template.getFirstButton());
+ assertNotNull(template.getSecondButton());
+ assertNotNull(template.getYetanotherbutton());
+ assertNotNull(template.getClickme());
+ assertEquals("Native click me", template.getFirstButton().getCaption());
+ }
+
+ @Test(expected = DesignException.class)
+ public void fieldsCannotBeBoundToAnInvalidTemplate() throws IOException {
+ InvalidLayoutTemplate template = new InvalidLayoutTemplate();
+ InputStream htmlFile = getClass().getResourceAsStream("testFile.html");
+
+ Design.read(htmlFile, template);
+ }
+
+ @Test
+ public void rootHasCorrectComponents() {
+ Component root = ctx.getRootComponent();
+
+ VerticalLayout vlayout = (VerticalLayout) root;
+
+ assertThat(vlayout.getComponentCount(), is(3));
+ }
+
+ @Test
+ public void rootChildHasCorrectComponents() {
+ Component root = ctx.getRootComponent();
+ VerticalLayout vlayout = (VerticalLayout) root;
+ HorizontalLayout hlayout = (HorizontalLayout) vlayout.getComponent(0);
+
+ assertThat(hlayout.getComponentCount(), is(5));
+ assertThat(hlayout.getComponent(0).getCaption(), is("FooBar"));
+ assertThat(hlayout.getComponent(1).getCaption(), is("Native click me"));
+ assertThat(hlayout.getComponent(2).getCaption(), is("Another button"));
+ assertThat(hlayout.getComponent(3).getCaption(),
+ is("Yet another button"));
+ assertThat(hlayout.getComponent(4).getCaption(), is("Click me"));
+ assertThat(hlayout.getComponent(4).getWidth(), is(150f));
+
+ // Check the remaining two components of the vertical layout
+ assertTextField(vlayout);
+ assertTextArea(vlayout);
+ }
+
+ private void assertComponentHierarchy() {
+ rootHasCorrectComponents();
+ rootChildHasCorrectComponents();
+ }
+
+ private void assertTextField(VerticalLayout vlayout) {
+ TextField tf = (TextField) vlayout.getComponent(1);
+
+ assertThat(tf.getCaption(), is("Text input"));
+ }
+
+ private void assertTextArea(VerticalLayout layout) {
+ TextArea ta = (TextArea) layout.getComponent(2);
+
+ assertThat(ta.getCaption(), is("Text area"));
+ assertThat(ta.getWidth(), is(300f));
+ assertThat(ta.getHeight(), is(200f));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/ParseLegacyPrefixTest.java b/server/src/test/java/com/vaadin/tests/design/ParseLegacyPrefixTest.java
new file mode 100644
index 0000000000..76e15aae17
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/ParseLegacyPrefixTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2000-2014 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.design;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.io.FileNotFoundException;
+
+import org.junit.Test;
+
+import com.vaadin.ui.declarative.Design;
+import com.vaadin.ui.declarative.DesignContext;
+
+/**
+ * Test reading a design with all components using the legacy prefix.
+ */
+public class ParseLegacyPrefixTest {
+
+ @Test
+ public void allComponentsAreParsed() throws FileNotFoundException {
+ DesignContext ctx = Design.read(
+ getClass().getResourceAsStream("all-components-legacy.html"),
+ null);
+
+ assertThat(ctx, is(not(nullValue())));
+ assertThat(ctx.getRootComponent(), is(not(nullValue())));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/ParseMixedLegacyAndNewPrefixTest.java b/server/src/test/java/com/vaadin/tests/design/ParseMixedLegacyAndNewPrefixTest.java
new file mode 100644
index 0000000000..2996cb23c1
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/ParseMixedLegacyAndNewPrefixTest.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2000-2014 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.design;
+
+import java.io.ByteArrayInputStream;
+
+import org.junit.Test;
+
+import com.vaadin.ui.declarative.Design;
+
+/**
+ * Parse mixed content with legacy and new prefixes (not a required feature but
+ * works).
+ */
+public class ParseMixedLegacyAndNewPrefixTest {
+ @Test
+ public void parseMixedContent() {
+ Design.read(new ByteArrayInputStream(
+ "<v-vertical-layout><vaadin-label /></v-vertical-layout>"
+ .getBytes()));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/WriteLegacyDesignTest.java b/server/src/test/java/com/vaadin/tests/design/WriteLegacyDesignTest.java
new file mode 100644
index 0000000000..facb5e9862
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/WriteLegacyDesignTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2000-2014 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.design;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.nodes.Node;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.server.Constants;
+import com.vaadin.server.DefaultDeploymentConfiguration;
+import com.vaadin.server.DeploymentConfiguration;
+import com.vaadin.server.VaadinService;
+import com.vaadin.server.VaadinServletService;
+import com.vaadin.ui.declarative.Design;
+import com.vaadin.ui.declarative.DesignContext;
+import com.vaadin.util.CurrentInstance;
+
+/**
+ * Parse and write a legacy design (using the "v-" prefix).
+ */
+public class WriteLegacyDesignTest {
+
+ // The context is used for accessing the created component hierarchy.
+ private DesignContext ctx;
+
+ @Before
+ public void setUp() throws Exception {
+ Properties properties = new Properties();
+ properties.put(Constants.SERVLET_PARAMETER_LEGACY_DESIGN_PREFIX,
+ "true");
+ final DeploymentConfiguration configuration = new DefaultDeploymentConfiguration(
+ WriteLegacyDesignTest.class, properties);
+
+ VaadinService service = new VaadinServletService(null, configuration);
+
+ CurrentInstance.set(VaadinService.class, service);
+
+ ctx = Design.read(
+ getClass().getResourceAsStream("testFile-legacy.html"), null);
+ }
+
+ @After
+ public void tearDown() {
+ CurrentInstance.set(VaadinService.class, null);
+ }
+
+ private ByteArrayOutputStream serializeDesign(DesignContext context)
+ throws IOException {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ Design.write(context, out);
+
+ return out;
+ }
+
+ @Test
+ public void designIsSerializedWithCorrectPrefixesAndPackageNames()
+ throws IOException {
+ ByteArrayOutputStream out = serializeDesign(ctx);
+
+ Document doc = Jsoup.parse(out.toString("UTF-8"));
+ for (Node child : doc.body().childNodes()) {
+ checkNode(child);
+ }
+ }
+
+ private void checkNode(Node node) {
+ if (node instanceof Element) {
+ assertTrue("Wrong design element prefix",
+ node.nodeName().startsWith("v-"));
+ for (Node child : node.childNodes()) {
+ checkNode(child);
+ }
+ }
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/designroot/DesignRootTest.java b/server/src/test/java/com/vaadin/tests/design/designroot/DesignRootTest.java
new file mode 100644
index 0000000000..682da30344
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/designroot/DesignRootTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2000-2014 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.design.designroot;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class DesignRootTest {
+ @Test
+ public void designAnnotationWithoutFilename() {
+ DesignWithEmptyAnnotation d = new DesignWithEmptyAnnotation();
+ Assert.assertNotNull(d.ok);
+ Assert.assertNotNull(d.CaNCEL);
+ Assert.assertEquals("original", d.preInitializedField.getValue());
+ }
+
+ @Test
+ public void designAnnotationWithFilename() {
+ DesignWithAnnotation d = new DesignWithAnnotation();
+ Assert.assertNotNull(d.ok);
+ Assert.assertNotNull(d.cancel);
+ Assert.assertEquals("original", d.preInitializedField.getValue());
+ }
+
+ @Test
+ public void extendedDesignAnnotationWithoutFilename() {
+ DesignWithEmptyAnnotation d = new ExtendedDesignWithEmptyAnnotation();
+ Assert.assertNotNull(d.ok);
+ Assert.assertNotNull(d.CaNCEL);
+ Assert.assertEquals("original", d.preInitializedField.getValue());
+ }
+
+ @Test
+ public void extendedDesignAnnotationWithFilename() {
+ DesignWithAnnotation d = new ExtendedDesignWithAnnotation();
+ Assert.assertNotNull(d.ok);
+ Assert.assertNotNull(d.cancel);
+ Assert.assertEquals("original", d.preInitializedField.getValue());
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/designroot/DesignWithAnnotation.java b/server/src/test/java/com/vaadin/tests/design/designroot/DesignWithAnnotation.java
new file mode 100644
index 0000000000..ef9de9dcb0
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/designroot/DesignWithAnnotation.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2014 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.design.designroot;
+
+import com.vaadin.annotations.DesignRoot;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.declarative.Design;
+
+@DesignRoot("DesignWithEmptyAnnotation.html")
+public class DesignWithAnnotation extends VerticalLayout {
+
+ public Button ok;
+ public Button cancel;
+ public Label preInitializedField = new Label("original");
+
+ public DesignWithAnnotation() {
+ Design.read(this);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/designroot/DesignWithEmptyAnnotation.java b/server/src/test/java/com/vaadin/tests/design/designroot/DesignWithEmptyAnnotation.java
new file mode 100644
index 0000000000..55fd571ee2
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/designroot/DesignWithEmptyAnnotation.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2014 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.design.designroot;
+
+import com.vaadin.annotations.DesignRoot;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.declarative.Design;
+
+@DesignRoot
+public class DesignWithEmptyAnnotation extends VerticalLayout {
+
+ protected Button ok;
+ protected Button CaNCEL;
+ protected Label preInitializedField = new Label("original");
+
+ public DesignWithEmptyAnnotation() {
+ Design.read(this);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/designroot/ExtendedDesignWithAnnotation.java b/server/src/test/java/com/vaadin/tests/design/designroot/ExtendedDesignWithAnnotation.java
new file mode 100644
index 0000000000..d47b4540df
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/designroot/ExtendedDesignWithAnnotation.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2014 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.design.designroot;
+
+import com.vaadin.ui.TextField;
+
+public class ExtendedDesignWithAnnotation extends DesignWithAnnotation {
+ private TextField customField = new TextField();
+
+ public ExtendedDesignWithAnnotation() {
+ customField.setInputPrompt("Something");
+ addComponent(customField);
+
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/designroot/ExtendedDesignWithEmptyAnnotation.java b/server/src/test/java/com/vaadin/tests/design/designroot/ExtendedDesignWithEmptyAnnotation.java
new file mode 100644
index 0000000000..ea513f6d3e
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/designroot/ExtendedDesignWithEmptyAnnotation.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2000-2014 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.design.designroot;
+
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.Notification;
+import com.vaadin.ui.TextField;
+
+public class ExtendedDesignWithEmptyAnnotation extends
+ DesignWithEmptyAnnotation {
+
+ private TextField customField = new TextField();
+
+ public ExtendedDesignWithEmptyAnnotation() {
+ super();
+ customField.setInputPrompt("Something");
+ addComponent(customField);
+
+ ok.addClickListener(new ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ Notification.show("OK");
+ }
+ });
+
+ CaNCEL.addClickListener(new ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ Notification.show("cancel");
+ }
+ });
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/designroot/ExtendedDesignWithEmptyAnnotationUI.java b/server/src/test/java/com/vaadin/tests/design/designroot/ExtendedDesignWithEmptyAnnotationUI.java
new file mode 100644
index 0000000000..1d0e8de4eb
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/designroot/ExtendedDesignWithEmptyAnnotationUI.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2000-2014 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.design.designroot;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.ui.UI;
+
+public class ExtendedDesignWithEmptyAnnotationUI extends UI {
+
+ @Override
+ protected void init(VaadinRequest request) {
+ setContent(new ExtendedDesignWithEmptyAnnotation());
+
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/nested/MyChildDesign.java b/server/src/test/java/com/vaadin/tests/design/nested/MyChildDesign.java
new file mode 100644
index 0000000000..3b0d80c32c
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/nested/MyChildDesign.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2014 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.design.nested;
+
+import com.vaadin.annotations.DesignRoot;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.declarative.Design;
+
+/**
+ * Child design component
+ *
+ * @author Vaadin Ltd
+ */
+@DesignRoot("mychilddesign.html")
+public class MyChildDesign extends HorizontalLayout {
+ public Label childLabel;
+ public MyChildDesignCustomComponent childCustomComponent;
+
+ public MyChildDesign() {
+ Design.read(this);
+ childLabel.setDescription("added in constructor");
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/nested/MyChildDesignCustomComponent.java b/server/src/test/java/com/vaadin/tests/design/nested/MyChildDesignCustomComponent.java
new file mode 100644
index 0000000000..8402224cf9
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/nested/MyChildDesignCustomComponent.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2000-2014 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.design.nested;
+
+import com.vaadin.ui.Button;
+
+public class MyChildDesignCustomComponent extends Button {
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/nested/MyDesignRoot.java b/server/src/test/java/com/vaadin/tests/design/nested/MyDesignRoot.java
new file mode 100644
index 0000000000..abde002ef8
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/nested/MyDesignRoot.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2000-2014 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.design.nested;
+
+import com.vaadin.annotations.DesignRoot;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.declarative.Design;
+
+/**
+ * Root design component
+ *
+ * @author Vaadin Ltd
+ */
+@DesignRoot("mydesignroot.html")
+public class MyDesignRoot extends VerticalLayout {
+ // should be assigned automatically
+ public MyExtendedChildDesign childDesign;
+
+ public MyDesignRoot() {
+ Design.read(this);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/nested/MyExtendedChildDesign.java b/server/src/test/java/com/vaadin/tests/design/nested/MyExtendedChildDesign.java
new file mode 100644
index 0000000000..579fdfb869
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/nested/MyExtendedChildDesign.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2000-2014 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.design.nested;
+
+public class MyExtendedChildDesign extends MyChildDesign {
+ public MyExtendedChildDesign() {
+ super();
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/nested/NestedCustomLayoutsTest.java b/server/src/test/java/com/vaadin/tests/design/nested/NestedCustomLayoutsTest.java
new file mode 100644
index 0000000000..beaa9519cb
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/nested/NestedCustomLayoutsTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2000-2014 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.design.nested;
+
+import com.vaadin.tests.design.nested.customlayouts.*;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.declarative.Design;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.junit.Test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.greaterThan;
+
+/**
+ * Test case for nested custom layouts. The children of the custom layouts must
+ * not be rendered.
+ *
+ * @author Vaadin Ltd
+ */
+public class NestedCustomLayoutsTest {
+
+ private static String PACKAGE_MAPPING = "com_vaadin_tests_design_nested_customlayouts:com.vaadin.tests.design.nested.customlayouts";
+
+ @Test
+ public void testNestedLayouts() throws IOException {
+ VerticalLayout rootLayout = createRootLayout();
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ Design.write(rootLayout, out);
+ Document doc = Jsoup.parse(out.toString("UTF-8"));
+
+ assertThat(doc.head().child(0).attr("name"), is("package-mapping"));
+ assertThat(doc.head().child(0).attr("content"), is(PACKAGE_MAPPING));
+ assertChildrenCount(doc);
+ }
+
+ private VerticalLayout createRootLayout() {
+ VerticalLayout rootLayout = new VerticalLayout();
+ rootLayout.addComponent(new CustomAbsoluteLayout());
+ rootLayout.addComponent(new CustomAccordion());
+ rootLayout.addComponent(new CustomCssLayout());
+ rootLayout.addComponent(new CustomFormLayout());
+ rootLayout.addComponent(new CustomGridLayout());
+ rootLayout.addComponent(new CustomHorizontalLayout());
+ rootLayout.addComponent(new CustomHorizontalSplitPanel());
+ rootLayout.addComponent(new CustomPanel());
+ rootLayout.addComponent(new CustomTabSheet());
+ rootLayout.addComponent(new CustomVerticalLayout());
+ rootLayout.addComponent(new CustomVerticalSplitPanel());
+
+ return rootLayout;
+ }
+
+ private void assertChildrenCount(Document doc) {
+ Element rootNode = doc.body().child(0);
+ assertThat(rootNode.children().size(), greaterThan(0));
+
+ for (Element child : rootNode.children()) {
+ // make sure that the nested custom layouts do not render children
+ assertThat(child.children().size(), is(0));
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/nested/ReadNestedTemplatesTest.java b/server/src/test/java/com/vaadin/tests/design/nested/ReadNestedTemplatesTest.java
new file mode 100644
index 0000000000..dc95306cd3
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/nested/ReadNestedTemplatesTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2000-2014 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.design.nested;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.core.IsNot.not;
+import static org.junit.Assert.*;
+
+/**
+ * Test case for reading nested templates
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class ReadNestedTemplatesTest {
+
+ private MyDesignRoot root;
+
+ @Before
+ public void setUp() {
+ root = new MyDesignRoot();
+ }
+
+ @Test
+ public void rootContainsOneChild() {
+ assertThat(root.getComponentCount(), is(1));
+ assertThat(root.iterator().next(),
+ instanceOf(MyExtendedChildDesign.class));
+ }
+
+ @Test
+ public void rootContainsTwoGrandChildren() {
+ assertThat(root.childDesign.getComponentCount(), is(2));
+ }
+
+ @Test
+ public void childComponentIsNotNull() {
+ assertThat(root.childDesign, is(not(nullValue())));
+ }
+
+ @Test
+ public void childLabelIsNotNull() {
+ assertThat(root.childDesign.childLabel, is(not(nullValue())));
+ assertThat(root.childDesign.childLabel.getValue(), is("test content"));
+ }
+
+ @Test
+ public void childCustomComponentsIsNotNull() {
+ assertThat(root.childDesign.childCustomComponent, is(not(nullValue())));
+ assertThat(root.childDesign.childCustomComponent.getCaption(),
+ is("custom content"));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/nested/WriteNestedTemplatesTest.java b/server/src/test/java/com/vaadin/tests/design/nested/WriteNestedTemplatesTest.java
new file mode 100644
index 0000000000..5c78802472
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/nested/WriteNestedTemplatesTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2000-2014 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.design.nested;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import org.jsoup.nodes.Attributes;
+import org.jsoup.nodes.Element;
+import org.jsoup.parser.Tag;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.ui.declarative.DesignContext;
+
+/**
+ *
+ * Test case for writing nested templates
+ *
+ * @author Vaadin Ltd
+ */
+public class WriteNestedTemplatesTest {
+
+ private MyDesignRoot root;
+ private Element design;
+
+ @Before
+ public void setUp() {
+ root = new MyDesignRoot();
+ design = createDesign();
+ }
+
+ private Element createDesign() {
+ Element design = new Element(Tag.valueOf("vaadin-vertical-layout"), "",
+ new Attributes());
+
+ DesignContext designContext = new DesignContext();
+ designContext.setRootComponent(root);
+ root.writeDesign(design, designContext);
+
+ return design;
+ }
+
+ @Test
+ public void testChildRendered() {
+ assertEquals("Root layout must have one child", 1, design.children()
+ .size());
+ assertEquals("com_vaadin_tests_design_nested-my-extended-child-design",
+ design.child(0).tagName());
+ }
+
+ @Test
+ public void rootCaptionIsWritten() {
+ assertTrue(design.hasAttr("caption"));
+ assertThat(design.attr("caption"), is("root caption"));
+ }
+
+ @Test
+ public void childCaptionIsWritten() {
+ assertTrue(design.child(0).hasAttr("caption"));
+ assertThat(design.child(0).attr("caption"), is("child caption"));
+ }
+
+ // The default caption is read from child template
+ @Test
+ public void defaultCaptionIsNotOverwritten() {
+ root.childDesign.setCaption("Default caption for child design");
+ design = createDesign();
+
+ assertFalse(design.child(0).hasAttr("caption"));
+ }
+
+ @Test
+ public void childDesignChildrenIsNotWrittenInRootTemplate() {
+ assertThat(design.child(0).children().size(), is(0));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomAbsoluteLayout.java b/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomAbsoluteLayout.java
new file mode 100644
index 0000000000..8eef3b07a6
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomAbsoluteLayout.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2014 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.design.nested.customlayouts;
+
+import com.vaadin.ui.AbsoluteLayout;
+import com.vaadin.ui.Label;
+
+/**
+ * @author Vaadin Ltd
+ */
+public class CustomAbsoluteLayout extends AbsoluteLayout {
+ public CustomAbsoluteLayout() {
+ this.addComponent(new Label());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomAccordion.java b/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomAccordion.java
new file mode 100644
index 0000000000..93606f296c
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomAccordion.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2014 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.design.nested.customlayouts;
+
+import com.vaadin.ui.Accordion;
+import com.vaadin.ui.Label;
+
+/**
+ * @author Vaadin Ltd
+ */
+public class CustomAccordion extends Accordion {
+ public CustomAccordion() {
+ addComponent(new Label());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomCssLayout.java b/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomCssLayout.java
new file mode 100644
index 0000000000..b2aaa2c015
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomCssLayout.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2014 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.design.nested.customlayouts;
+
+import com.vaadin.ui.CssLayout;
+import com.vaadin.ui.Label;
+
+/**
+ * @author Vaadin Ltd
+ */
+public class CustomCssLayout extends CssLayout {
+ public CustomCssLayout() {
+ this.addComponent(new Label());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomFormLayout.java b/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomFormLayout.java
new file mode 100644
index 0000000000..66ac083c0d
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomFormLayout.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2014 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.design.nested.customlayouts;
+
+import com.vaadin.ui.FormLayout;
+import com.vaadin.ui.Label;
+
+/**
+ * @author Vaadin Ltd
+ */
+public class CustomFormLayout extends FormLayout {
+ public CustomFormLayout() {
+ this.addComponent(new Label());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomGridLayout.java b/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomGridLayout.java
new file mode 100644
index 0000000000..1059ea0e14
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomGridLayout.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2014 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.design.nested.customlayouts;
+
+import com.vaadin.ui.GridLayout;
+import com.vaadin.ui.Label;
+
+/**
+ * @author Vaadin Ltd
+ */
+public class CustomGridLayout extends GridLayout {
+ public CustomGridLayout() {
+ this.addComponent(new Label());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomHorizontalLayout.java b/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomHorizontalLayout.java
new file mode 100644
index 0000000000..482a9feb95
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomHorizontalLayout.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2014 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.design.nested.customlayouts;
+
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Label;
+
+/**
+ * @author Vaadin Ltd
+ */
+public class CustomHorizontalLayout extends HorizontalLayout {
+ public CustomHorizontalLayout() {
+ this.addComponent(new Label());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomHorizontalSplitPanel.java b/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomHorizontalSplitPanel.java
new file mode 100644
index 0000000000..21c8745796
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomHorizontalSplitPanel.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2014 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.design.nested.customlayouts;
+
+import com.vaadin.ui.HorizontalSplitPanel;
+import com.vaadin.ui.Label;
+
+/**
+ * @author Vaadin Ltd
+ */
+public class CustomHorizontalSplitPanel extends HorizontalSplitPanel {
+ public CustomHorizontalSplitPanel() {
+ addComponent(new Label());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomPanel.java b/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomPanel.java
new file mode 100644
index 0000000000..5841fbcfee
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomPanel.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2014 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.design.nested.customlayouts;
+
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Panel;
+
+/**
+ * @author Vaadin Ltd
+ */
+public class CustomPanel extends Panel {
+ public CustomPanel() {
+ setContent(new Label());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomTabSheet.java b/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomTabSheet.java
new file mode 100644
index 0000000000..128de7de1f
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomTabSheet.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2014 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.design.nested.customlayouts;
+
+import com.vaadin.ui.Label;
+import com.vaadin.ui.TabSheet;
+
+/**
+ * @author Vaadin Ltd
+ */
+public class CustomTabSheet extends TabSheet {
+ public CustomTabSheet() {
+ addComponent(new Label());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomVerticalLayout.java b/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomVerticalLayout.java
new file mode 100644
index 0000000000..3bc8fba7de
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomVerticalLayout.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2014 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.design.nested.customlayouts;
+
+import com.vaadin.ui.Label;
+import com.vaadin.ui.VerticalLayout;
+
+/**
+ * @author Vaadin Ltd
+ */
+public class CustomVerticalLayout extends VerticalLayout {
+ public CustomVerticalLayout() {
+ this.addComponent(new Label());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomVerticalSplitPanel.java b/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomVerticalSplitPanel.java
new file mode 100644
index 0000000000..486d71ea75
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/design/nested/customlayouts/CustomVerticalSplitPanel.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2014 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.design.nested.customlayouts;
+
+import com.vaadin.ui.Label;
+import com.vaadin.ui.VerticalSplitPanel;
+
+/**
+ * @author Vaadin Ltd
+ */
+public class CustomVerticalSplitPanel extends VerticalSplitPanel {
+ public CustomVerticalSplitPanel() {
+ addComponent(new Label());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/event/EventRouterTest.java b/server/src/test/java/com/vaadin/tests/event/EventRouterTest.java
new file mode 100644
index 0000000000..aeb460c49e
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/event/EventRouterTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2000-2014 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.event;
+
+import java.lang.reflect.Method;
+
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.event.EventRouter;
+import com.vaadin.server.ErrorEvent;
+import com.vaadin.server.ErrorHandler;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.Component.Listener;
+import com.vaadin.util.ReflectTools;
+
+/**
+ * Test EventRouter and related error handling.
+ */
+public class EventRouterTest {
+
+ private static final Method COMPONENT_EVENT_METHOD = ReflectTools
+ .findMethod(Component.Listener.class, "componentEvent",
+ Component.Event.class);
+
+ private EventRouter router;
+ private Component component;
+ private ErrorHandler errorHandler;
+ private Listener listener;
+
+ @Before
+ public void createMocks() {
+ router = new EventRouter();
+ component = EasyMock.createNiceMock(Component.class);
+ errorHandler = EasyMock.createMock(ErrorHandler.class);
+ listener = EasyMock.createMock(Component.Listener.class);
+ router.addListener(Component.Event.class, listener,
+ COMPONENT_EVENT_METHOD);
+ }
+
+ @Test
+ public void fireEvent_noException_eventReceived() {
+ listener.componentEvent(EasyMock.<Component.Event> anyObject());
+
+ EasyMock.replay(component, listener, errorHandler);
+ router.fireEvent(new Component.Event(component), errorHandler);
+ EasyMock.verify(listener, errorHandler);
+ }
+
+ @Test
+ public void fireEvent_exceptionFromListenerAndNoHandler_exceptionPropagated() {
+ listener.componentEvent(EasyMock.<Component.Event> anyObject());
+ EasyMock.expectLastCall().andThrow(
+ new RuntimeException("listener failed"));
+
+ EasyMock.replay(component, listener);
+ try {
+ router.fireEvent(new Component.Event(component));
+ Assert.fail("Did not receive expected exception from listener");
+ } catch (RuntimeException e) {
+ // e is a ListenerMethod@MethodException
+ Assert.assertEquals("listener failed", e.getCause().getMessage());
+ }
+ EasyMock.verify(listener);
+ }
+
+ @Test
+ public void fireEvent_exceptionFromListener_errorHandlerCalled() {
+ listener.componentEvent(EasyMock.<Component.Event> anyObject());
+ EasyMock.expectLastCall().andThrow(
+ new RuntimeException("listener failed"));
+ errorHandler.error(EasyMock.<ErrorEvent> anyObject());
+
+ EasyMock.replay(component, listener, errorHandler);
+ router.fireEvent(new Component.Event(component), errorHandler);
+ EasyMock.verify(listener, errorHandler);
+ }
+
+ @Test
+ public void fireEvent_multipleListenersAndException_errorHandlerCalled() {
+ Listener listener2 = EasyMock.createMock(Component.Listener.class);
+ router.addListener(Component.Event.class, listener2,
+ COMPONENT_EVENT_METHOD);
+
+ listener.componentEvent(EasyMock.<Component.Event> anyObject());
+ EasyMock.expectLastCall().andThrow(
+ new RuntimeException("listener failed"));
+ errorHandler.error(EasyMock.<ErrorEvent> anyObject());
+ // second listener should be called despite an error in the first
+ listener2.componentEvent(EasyMock.<Component.Event> anyObject());
+
+ EasyMock.replay(component, listener, listener2, errorHandler);
+ router.fireEvent(new Component.Event(component), errorHandler);
+ EasyMock.verify(listener, listener2, errorHandler);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/event/ShortcutActionTest.java b/server/src/test/java/com/vaadin/tests/event/ShortcutActionTest.java
new file mode 100644
index 0000000000..9af23b86b1
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/event/ShortcutActionTest.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2000-2014 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.event;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashSet;
+
+import org.junit.Test;
+
+import com.vaadin.event.ShortcutAction;
+import com.vaadin.shared.util.SharedUtil;
+import com.vaadin.tests.design.DesignFormatterTest;
+
+/**
+ * Tests various things about shortcut actions.
+ *
+ * @since 7.4
+ * @author Vaadin Ltd
+ */
+public class ShortcutActionTest {
+
+ private static final String[] KEYS = "a b c d e f g h i j k l m n o p q r s t u v w x y z"
+ .split("\\s+");
+
+ @Test
+ public void testHashCodeUniqueness() {
+ HashSet<ShortcutAction> set = new HashSet<ShortcutAction>();
+ for (String modifier : new String[] { "^", "&", "_", "&^", "&_", "_^",
+ "&^_" }) {
+ for (String key : KEYS) {
+ ShortcutAction action = new ShortcutAction(modifier + key);
+ for (ShortcutAction other : set) {
+ assertFalse(equals(action, other));
+ }
+ set.add(action);
+ }
+ }
+ }
+
+ @Test
+ public void testModifierOrderIrrelevant() {
+ for (String key : KEYS) {
+ // two modifiers
+ for (String modifier : new String[] { "&^", "&_", "_^" }) {
+ ShortcutAction action1 = new ShortcutAction(modifier + key);
+ ShortcutAction action2 = new ShortcutAction(
+ modifier.substring(1) + modifier.substring(0, 1) + key);
+ assertTrue(modifier + key, equals(action1, action2));
+ }
+ // three modifiers
+ ShortcutAction action1 = new ShortcutAction("&^_" + key);
+ for (String modifier : new String[] { "&_^", "^&_", "^_&", "_^&",
+ "_&^" }) {
+ ShortcutAction action2 = new ShortcutAction(modifier + key);
+ assertTrue(modifier + key, equals(action1, action2));
+
+ }
+ }
+ }
+
+ @Test
+ public void testSameKeycodeDifferentCaptions() {
+ ShortcutAction act1 = new ShortcutAction("E&xit");
+ ShortcutAction act2 = new ShortcutAction("Lu&xtorpeda - Autystyczny");
+ assertFalse(equals(act1, act2));
+ }
+
+ /**
+ * A static method to allow comparison two different actions.
+ *
+ * @see DesignFormatterTest
+ *
+ * @param act
+ * One action to compare.
+ * @param other
+ * Second action to compare.
+ * @return <b>true</b> when both actions are the same (caption, icon, and
+ * key combination).
+ */
+ public static final boolean equals(ShortcutAction act, ShortcutAction other) {
+ if (SharedUtil.equals(other.getCaption(), act.getCaption())
+ && SharedUtil.equals(other.getIcon(), act.getIcon())
+ && act.getKeyCode() == other.getKeyCode()
+ && act.getModifiers().length == other.getModifiers().length) {
+ HashSet<Integer> thisSet = new HashSet<Integer>(
+ act.getModifiers().length);
+ // this is a bit tricky comparison, but there is no nice way of
+ // making int[] into a Set
+ for (int mod : act.getModifiers()) {
+ thisSet.add(mod);
+ }
+ for (int mod : other.getModifiers()) {
+ thisSet.remove(mod);
+ }
+ return thisSet.isEmpty();
+ }
+ return false;
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/AbstractBeanContainerListenersTest.java b/server/src/test/java/com/vaadin/tests/server/AbstractBeanContainerListenersTest.java
new file mode 100644
index 0000000000..b9b4f8025d
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/AbstractBeanContainerListenersTest.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.AbstractListenerMethodsTestBase;
+
+public class AbstractBeanContainerListenersTest extends
+ AbstractListenerMethodsTestBase {
+ public void testPropertySetChangeListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(BeanItemContainer.class,
+ PropertySetChangeEvent.class, PropertySetChangeListener.class,
+ new BeanItemContainer<PropertySetChangeListener>(
+ PropertySetChangeListener.class));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/AbstractContainerListenersTest.java b/server/src/test/java/com/vaadin/tests/server/AbstractContainerListenersTest.java
new file mode 100644
index 0000000000..91036c03ed
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/AbstractContainerListenersTest.java
@@ -0,0 +1,22 @@
+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.AbstractListenerMethodsTestBase;
+
+public class AbstractContainerListenersTest extends
+ AbstractListenerMethodsTestBase {
+
+ 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/src/test/java/com/vaadin/tests/server/AbstractInMemoryContainerListenersTest.java b/server/src/test/java/com/vaadin/tests/server/AbstractInMemoryContainerListenersTest.java
new file mode 100644
index 0000000000..072998b8e1
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/AbstractInMemoryContainerListenersTest.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.AbstractListenerMethodsTestBase;
+
+public class AbstractInMemoryContainerListenersTest extends
+ AbstractListenerMethodsTestBase {
+ public void testItemSetChangeListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(IndexedContainer.class,
+ ItemSetChangeEvent.class, ItemSetChangeListener.class);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/AbstractPropertyListenersTest.java b/server/src/test/java/com/vaadin/tests/server/AbstractPropertyListenersTest.java
new file mode 100644
index 0000000000..fd38b52a37
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/AbstractPropertyListenersTest.java
@@ -0,0 +1,25 @@
+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.AbstractListenerMethodsTestBase;
+
+public class AbstractPropertyListenersTest extends
+ AbstractListenerMethodsTestBase {
+ 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/src/test/java/com/vaadin/tests/server/AssertionsEnabledTest.java b/server/src/test/java/com/vaadin/tests/server/AssertionsEnabledTest.java
new file mode 100644
index 0000000000..087a7fb0f5
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/AssertionsEnabledTest.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2000-2014 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;
+
+import junit.framework.TestCase;
+
+public class AssertionsEnabledTest extends TestCase {
+ public void testAssertionsEnabled() {
+ boolean assertFailed = false;
+ try {
+ assert false;
+ } catch (AssertionError e) {
+ assertFailed = true;
+ } finally {
+ assertTrue("Unit tests should be run with assertions enabled",
+ assertFailed);
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/AtmosphereVersionTest.java b/server/src/test/java/com/vaadin/tests/server/AtmosphereVersionTest.java
new file mode 100644
index 0000000000..90a0283cda
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/AtmosphereVersionTest.java
@@ -0,0 +1,18 @@
+package com.vaadin.tests.server;
+
+import junit.framework.TestCase;
+
+import org.atmosphere.util.Version;
+
+import com.vaadin.server.Constants;
+
+public class AtmosphereVersionTest extends TestCase {
+ /**
+ * Test that the atmosphere version constant matches the version on our
+ * classpath
+ */
+ public void testAtmosphereVersion() {
+ assertEquals(Constants.REQUIRED_ATMOSPHERE_RUNTIME_VERSION,
+ Version.getRawVersion());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/ClassesSerializableTest.java b/server/src/test/java/com/vaadin/tests/server/ClassesSerializableTest.java
new file mode 100644
index 0000000000..c22e289bc4
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/ClassesSerializableTest.java
@@ -0,0 +1,325 @@
+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.Comparator;
+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 ClassesSerializableTest 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\\.server\\.themeutils\\..*", //
+ "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\\.event\\.UIEvents", //
+ "com\\.vaadin\\.server\\.VaadinPortlet", //
+ "com\\.vaadin\\.server\\.MockServletConfig", //
+ "com\\.vaadin\\.server\\.MockServletContext", //
+ "com\\.vaadin\\.server\\.Constants", //
+ "com\\.vaadin\\.server\\.VaadinServiceClassLoaderUtil", //
+ "com\\.vaadin\\.server\\.VaadinServiceClassLoaderUtil\\$GetClassLoaderPrivilegedAction", //
+ "com\\.vaadin\\.server\\.communication\\.FileUploadHandler\\$SimpleMultiPartInputStream", //
+ "com\\.vaadin\\.server\\.communication\\.PushRequestHandler.*",
+ "com\\.vaadin\\.server\\.communication\\.PushHandler.*", // PushHandler
+ "com\\.vaadin\\.server\\.communication\\.DateSerializer", //
+ "com\\.vaadin\\.server\\.communication\\.JSONSerializer", //
+ // and its inner classes do not need to be serializable
+ "com\\.vaadin\\.util\\.SerializerHelper", // fully static
+ // class level filtering, also affecting nested classes and
+ // interfaces
+ "com\\.vaadin\\.server\\.LegacyCommunicationManager.*", //
+ "com\\.vaadin\\.buildhelpers.*", //
+ "com\\.vaadin\\.util\\.ReflectTools.*", //
+ "com\\.vaadin\\.data\\.util\\.ReflectTools.*", //
+ "com\\.vaadin\\.data\\.util.BeanItemContainerGenerator.*",
+ "com\\.vaadin\\.data\\.util\\.sqlcontainer\\.connection\\.MockInitialContextFactory",
+ "com\\.vaadin\\.data\\.util\\.sqlcontainer\\.DataGenerator",
+ "com\\.vaadin\\.data\\.util\\.sqlcontainer\\.FreeformQueryUtil",
+ "com\\.vaadin\\.sass.*", //
+ "com\\.vaadin\\.testbench.*", //
+ "com\\.vaadin\\.util\\.CurrentInstance\\$1", //
+ "com\\.vaadin\\.server\\.AbstractClientConnector\\$1", //
+ "com\\.vaadin\\.server\\.AbstractClientConnector\\$1\\$1", //
+ "com\\.vaadin\\.server\\.JsonCodec\\$1", //
+ "com\\.vaadin\\.server\\.communication\\.PushConnection", //
+ "com\\.vaadin\\.server\\.communication\\.AtmospherePushConnection.*", //
+ "com\\.vaadin\\.util\\.ConnectorHelper", //
+ "com\\.vaadin\\.server\\.VaadinSession\\$FutureAccess", //
+ "com\\.vaadin\\.external\\..*", //
+ "com\\.vaadin\\.util\\.WeakValueMap.*", //
+ "com\\.vaadin\\.themes\\.valoutil\\.BodyStyleName", //
+ "com\\.vaadin\\.server\\.communication\\.JSR356WebsocketInitializer.*", //
+ "com\\.vaadin\\.screenshotbrowser\\.ScreenshotBrowser.*", //
+ };
+
+ /**
+ * 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 @Ignore annotation on the class
+ if (isTestClass(cls)) {
+ continue;
+ }
+
+ // report non-serializable classes and interfaces
+ if (!Serializable.class.isAssignableFrom(cls)) {
+ if (cls.getSuperclass() == Object.class
+ && cls.getInterfaces().length == 1) {
+ // Single interface implementors
+ Class<?> iface = cls.getInterfaces()[0];
+
+ if (iface == Runnable.class) {
+ // Ignore Runnables used with access()
+ continue;
+ } else if (iface == Comparator.class) {
+ // Ignore inline comparators
+ continue;
+ }
+ }
+ 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);
+ }
+ }
+
+ private boolean isTestClass(Class<?> cls) {
+ if (cls.getEnclosingClass() != null
+ && isTestClass(cls.getEnclosingClass())) {
+ return true;
+ }
+
+ // Test classes with a @Test annotation on some method
+ for (Method method : cls.getMethods()) {
+ if (method.isAnnotationPresent(Test.class)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * 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/src/test/java/com/vaadin/tests/server/ClientMethodSerializationTest.java b/server/src/test/java/com/vaadin/tests/server/ClientMethodSerializationTest.java
new file mode 100644
index 0000000000..1ec19724d8
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/ClientMethodSerializationTest.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2000-2014 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;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.reflect.Method;
+
+import junit.framework.TestCase;
+
+import com.vaadin.server.ClientConnector;
+import com.vaadin.server.ClientMethodInvocation;
+import com.vaadin.server.JavaScriptCallbackHelper;
+import com.vaadin.server.JsonCodec;
+import com.vaadin.ui.JavaScript.JavaScriptCallbackRpc;
+import com.vaadin.util.ReflectTools;
+
+import elemental.json.Json;
+import elemental.json.JsonArray;
+import elemental.json.JsonValue;
+import elemental.json.impl.JsonUtil;
+
+public class ClientMethodSerializationTest extends TestCase {
+
+ private static final Method JAVASCRIPT_CALLBACK_METHOD = ReflectTools
+ .findMethod(JavaScriptCallbackRpc.class, "call", String.class,
+ JsonArray.class);
+
+ private static final Method BASIC_PARAMS_CALL_METHOD = ReflectTools
+ .findMethod(ClientMethodSerializationTest.class,
+ "basicParamsMethodForTesting", String.class, Integer.class);
+
+ private static final Method NO_PARAMS_CALL_METHOD = ReflectTools
+ .findMethod(ClientMethodSerializationTest.class,
+ "noParamsMethodForTesting");
+
+ public void basicParamsMethodForTesting(String stringParam,
+ Integer integerParam) {
+ }
+
+ public void noParamsMethodForTesting() {
+ }
+
+ /**
+ * Tests the {@link ClientMethodInvocation} serialization when using
+ * {@link JavaScriptCallbackHelper#invokeCallback(String, Object...)}.
+ * #12532
+ */
+ public void testClientMethodSerialization_WithJSONArray_ContentStaysSame()
+ throws Exception {
+ JsonArray originalArray = Json.createArray();
+ originalArray.set(0, "callbackParameter1");
+ originalArray.set(1, "callBackParameter2");
+ originalArray.set(2, "12345");
+ ClientMethodInvocation original = new ClientMethodInvocation(null,
+ "interfaceName", JAVASCRIPT_CALLBACK_METHOD, new Object[] {
+ "callBackMethodName", originalArray });
+
+ ClientMethodInvocation copy = (ClientMethodInvocation) serializeAndDeserialize(original);
+ JsonArray copyArray = (JsonArray) copy.getParameters()[1];
+ assertEquals(JsonUtil.stringify(originalArray),
+ JsonUtil.stringify(copyArray));
+ }
+
+ public void testClientMethodSerialization_WithBasicParams_NoChanges()
+ throws Exception {
+ String stringParam = "a string 123";
+ Integer integerParam = 1234567890;
+ ClientMethodInvocation original = new ClientMethodInvocation(null,
+ "interfaceName", BASIC_PARAMS_CALL_METHOD, new Serializable[] {
+ stringParam, integerParam });
+ ClientMethodInvocation copy = (ClientMethodInvocation) serializeAndDeserialize(original);
+ String copyString = (String) copy.getParameters()[0];
+ Integer copyInteger = (Integer) copy.getParameters()[1];
+ assertEquals(copyString, stringParam);
+ assertEquals(copyInteger, integerParam);
+ }
+
+ public void testClientMethodSerialization_NoParams_NoExceptions() {
+ ClientMethodInvocation original = new ClientMethodInvocation(null,
+ "interfaceName", NO_PARAMS_CALL_METHOD, null);
+ ClientMethodInvocation copy = (ClientMethodInvocation) serializeAndDeserialize(original);
+ }
+
+ private static Serializable serializeAndDeserialize(Serializable input) {
+ Serializable output = null;
+ try {
+ ByteArrayOutputStream bs = new ByteArrayOutputStream();
+ ObjectOutputStream out = new ObjectOutputStream(bs);
+ out.writeObject(input);
+ byte[] data = bs.toByteArray();
+ ObjectInputStream in = new ObjectInputStream(
+ new ByteArrayInputStream(data));
+ output = (Serializable) in.readObject();
+ } catch (Exception e) {
+ fail("Exception during serialization/deserialization: "
+ + e.getMessage());
+ }
+ return output;
+ }
+
+ public void testSerializeTwice() {
+ String name = "javascriptFunctionName";
+ String[] arguments = { "1", "2", "3" };
+ JsonArray args = (JsonArray) JsonCodec.encode(arguments, null,
+ Object[].class, null).getEncodedValue();
+ ClientConnector connector = null;
+
+ ClientMethodInvocation original = new ClientMethodInvocation(connector,
+ "interfaceName", JAVASCRIPT_CALLBACK_METHOD, new Object[] {
+ name, args });
+
+ ClientMethodInvocation copy = (ClientMethodInvocation) serializeAndDeserialize(original);
+ assertEquals(copy.getMethodName(), original.getMethodName());
+ assertEquals(copy.getParameters().length,
+ original.getParameters().length);
+ for (int i = 0; i < copy.getParameters().length; i++) {
+ Object originalParameter = original.getParameters()[i];
+ Object copyParameter = copy.getParameters()[i];
+ if (originalParameter instanceof JsonValue) {
+ assertEquals(((JsonValue) originalParameter).toJson(),
+ ((JsonValue) copyParameter).toJson());
+ } else {
+ assertEquals(originalParameter, copyParameter);
+ }
+ }
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/ContextClickListenerTest.java b/server/src/test/java/com/vaadin/tests/server/ContextClickListenerTest.java
new file mode 100644
index 0000000000..58d4d8d831
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/ContextClickListenerTest.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2000-2014 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;
+
+import java.util.EventObject;
+
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.event.ContextClickEvent;
+import com.vaadin.event.ContextClickEvent.ContextClickListener;
+import com.vaadin.ui.AbstractComponent;
+import com.vaadin.ui.Grid.GridContextClickEvent;
+import com.vaadin.ui.Table.TableContextClickEvent;
+
+/**
+ * Server-side unit tests to see that context click events are sent to listeners
+ * correctly.
+ *
+ * If a listener is listening to a super type of an event, it should get the
+ * event. i.e. Listening to ContextClickEvent, it should get the specialized
+ * GridContextClickEvent as well.
+ *
+ * If a listener is listening to a sub-type of an event, it should not get the
+ * super version. i.e. Listening to GridContextClickEvent, it should not get a
+ * plain ContextClickEvent.
+ */
+public class ContextClickListenerTest extends AbstractComponent {
+
+ private final static ContextClickEvent contextClickEvent = EasyMock
+ .createMock(ContextClickEvent.class);
+ private final static GridContextClickEvent gridContextClickEvent = EasyMock
+ .createMock(GridContextClickEvent.class);
+ private final static TableContextClickEvent tableContextClickEvent = EasyMock
+ .createMock(TableContextClickEvent.class);
+
+ private final AssertListener contextListener = new AssertListener();
+ private final AssertListener ctxtListener2 = new AssertListener();
+
+ public static class AssertListener implements ContextClickListener {
+
+ private Class<?> expected = null;
+ private String error = null;
+
+ @Override
+ public void contextClick(ContextClickEvent event) {
+ if (expected == null) {
+ error = "Unexpected context click event.";
+ return;
+ }
+
+ if (!expected.isAssignableFrom(event.getClass())) {
+ error = "Expected event type did not match the actual event.";
+ }
+
+ expected = null;
+ }
+
+ public <T extends ContextClickEvent> void expect(Class<T> clazz) {
+ validate();
+ expected = clazz;
+ }
+
+ public void validate() {
+ if (expected != null) {
+ Assert.fail("Expected context click never happened.");
+ } else if (error != null) {
+ Assert.fail(error);
+ }
+ }
+ }
+
+ @Test
+ public void testListenerGetsASubClass() {
+ addContextClickListener(contextListener);
+ contextListener.expect(GridContextClickEvent.class);
+ fireEvent(gridContextClickEvent);
+ }
+
+ @Test
+ public void testListenerGetsExactClass() {
+ addContextClickListener(contextListener);
+ contextListener.expect(ContextClickEvent.class);
+ fireEvent(contextClickEvent);
+ }
+
+ /**
+ * Multiple listeners should get fitting events.
+ */
+ @Test
+ public void testMultipleListenerGetEvents() {
+ addContextClickListener(ctxtListener2);
+ addContextClickListener(contextListener);
+
+ ctxtListener2.expect(GridContextClickEvent.class);
+ contextListener.expect(GridContextClickEvent.class);
+
+ fireEvent(gridContextClickEvent);
+ }
+
+ @Test
+ public void testAddAndRemoveListener() {
+ addContextClickListener(contextListener);
+ contextListener.expect(ContextClickEvent.class);
+
+ fireEvent(contextClickEvent);
+
+ removeContextClickListener(contextListener);
+
+ fireEvent(contextClickEvent);
+ }
+
+ @Test
+ public void testAddAndRemoveMultipleListeners() {
+ addContextClickListener(ctxtListener2);
+ addContextClickListener(contextListener);
+
+ ctxtListener2.expect(GridContextClickEvent.class);
+ contextListener.expect(GridContextClickEvent.class);
+ fireEvent(gridContextClickEvent);
+
+ removeContextClickListener(ctxtListener2);
+
+ contextListener.expect(GridContextClickEvent.class);
+ fireEvent(gridContextClickEvent);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void testExpectedEventNotReceived() {
+ addContextClickListener(contextListener);
+ contextListener.expect(GridContextClickEvent.class);
+ fireEvent(contextClickEvent);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void testUnexpectedEventReceived() {
+ addContextClickListener(contextListener);
+ fireEvent(gridContextClickEvent);
+ }
+
+ @Override
+ protected void fireEvent(EventObject event) {
+ super.fireEvent(event);
+
+ // Validate listeners automatically.
+ ctxtListener2.validate();
+ contextListener.validate();
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/CsrfTokenMissingTest.java b/server/src/test/java/com/vaadin/tests/server/CsrfTokenMissingTest.java
new file mode 100644
index 0000000000..cd9beafa10
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/CsrfTokenMissingTest.java
@@ -0,0 +1,253 @@
+/*
+ * Copyright 2000-2014 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;
+
+import java.util.UUID;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.server.MockServletConfig;
+import com.vaadin.server.ServiceException;
+import com.vaadin.server.VaadinService;
+import com.vaadin.server.VaadinServlet;
+import com.vaadin.server.VaadinServletRequest;
+import com.vaadin.server.VaadinServletService;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.server.communication.ServerRpcHandler.RpcRequest;
+import com.vaadin.shared.ApplicationConstants;
+import com.vaadin.tests.util.AlwaysLockedVaadinSession;
+import com.vaadin.tests.util.MockDeploymentConfiguration;
+
+import elemental.json.JsonException;
+
+/**
+ * Test the actual csrf token validation by the server.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class CsrfTokenMissingTest {
+
+ // Dummy fields just to run the test.
+ private VaadinServlet mockServlet;
+
+ // The mock deployment configuration.
+ private MockDeploymentConfiguration mockDeploymentConfiguration;
+
+ private VaadinServletService mockService;
+
+ // The mock UI session.
+ private VaadinSession mockSession;
+
+ // The mock vaadin request.
+ private VaadinServletRequest vaadinRequest;
+
+ /**
+ * Initialize the mock servlet and other stuff for our tests.
+ *
+ */
+ @Before
+ public void initMockStuff() throws ServiceException, ServletException {
+ mockServlet = new VaadinServlet();
+ mockServlet.init(new MockServletConfig());
+ mockDeploymentConfiguration = new MockDeploymentConfiguration();
+
+ mockService = new VaadinServletService(mockServlet,
+ mockDeploymentConfiguration);
+
+ mockSession = new AlwaysLockedVaadinSession(mockService);
+
+ vaadinRequest = new VaadinServletRequest(
+ EasyMock.createMock(HttpServletRequest.class), mockService);
+
+ }
+
+ private enum TokenType {
+ MISSING, INVALID, VALID
+ }
+
+ private TokenType tokenType;
+
+ private String invalidToken;
+
+ public String getInvalidToken() {
+ if (invalidToken == null) {
+ // Just making sure this will never be in the same format as a valid
+ // token.
+ invalidToken = UUID.randomUUID().toString().substring(1);
+ }
+ return invalidToken;
+ }
+
+ private String getValidToken() {
+ return mockSession.getCsrfToken();
+ }
+
+ /*
+ * Gets the payload with the default token.
+ */
+ private String getPayload() {
+ switch (tokenType) {
+ case MISSING:
+ return getPayload(null);
+
+ case INVALID:
+ return getPayload(getInvalidToken());
+
+ case VALID:
+ return getPayload(getValidToken());
+ }
+
+ return null;
+ }
+
+ /*
+ * Gets the payload with the specified token.
+ */
+ private String getPayload(String token) {
+ return "{"
+ + (token != null ? "\"csrfToken\":" + "\"" + token + "\", "
+ : "")
+ + "\"rpc\":[[\"0\",\"com.vaadin.shared.ui.ui.UIServerRpc\",\"resize\",[\"449\",\"1155\",\"1155\",\"449\"]],[\"4\",\"com.vaadin.shared.ui.button.ButtonServerRpc\",\"click\",[{\"clientY\":\"53\", \"clientX\":\"79\", \"shiftKey\":false, \"button\":\"LEFT\", \"ctrlKey\":false, \"type\":\"1\", \"metaKey\":false, \"altKey\":false, \"relativeY\":\"17\", \"relativeX\":\"61\"}]]], \"syncId\":1}";
+ }
+
+ /*
+ * Init the test parameters.
+ */
+ private void initTest(boolean enableSecurity, TokenType tokenType) {
+ mockDeploymentConfiguration.setXsrfProtectionEnabled(enableSecurity);
+ this.tokenType = tokenType;
+ }
+
+ /*
+ * Create the requets.
+ */
+ private RpcRequest createRequest() {
+ try {
+ return new RpcRequest(getPayload(), vaadinRequest);
+ } catch (JsonException e) {
+ LOGGER.log(Level.SEVERE, "", e);
+
+ Assert.assertTrue(false);
+ return null;
+ }
+ }
+
+ /*
+ * Gets whether the token from the request is the default one.
+ */
+ private boolean isDefaultToken(RpcRequest rpcRequest) {
+ return ApplicationConstants.CSRF_TOKEN_DEFAULT_VALUE.equals(rpcRequest
+ .getCsrfToken());
+ }
+
+ /*
+ * Gets whether the token from the request is the invalid one.
+ */
+ private boolean isInvalidToken(RpcRequest rpcRequest) {
+ return getInvalidToken().equals(rpcRequest.getCsrfToken());
+ }
+
+ /*
+ * Gets whether the token from the request is the valid one.
+ */
+ private boolean isValidToken(RpcRequest rpcRequest) {
+ return getValidToken().equals(rpcRequest.getCsrfToken());
+ }
+
+ /*
+ * Gets whether the token from the request is valid.
+ */
+ private boolean isRequestValid(RpcRequest rpcRequest) {
+ return VaadinService.isCsrfTokenValid(mockSession,
+ rpcRequest.getCsrfToken());
+ }
+
+ private static Logger LOGGER = Logger.getLogger(CsrfTokenMissingTest.class
+ .getName());
+ static {
+ LOGGER.setLevel(Level.ALL);
+ }
+
+ @Test
+ public void securityOnAndNoToken() {
+ initTest(true, TokenType.MISSING);
+
+ RpcRequest rpcRequest = createRequest();
+
+ Assert.assertTrue(isDefaultToken(rpcRequest));
+ Assert.assertFalse(isRequestValid(rpcRequest));
+ }
+
+ @Test
+ public void securityOffAndNoToken() {
+ initTest(false, TokenType.MISSING);
+
+ RpcRequest rpcRequest = createRequest();
+
+ Assert.assertTrue(isDefaultToken(rpcRequest));
+ Assert.assertTrue(isRequestValid(rpcRequest));
+ }
+
+ @Test
+ public void securityOnAndInvalidToken() {
+ initTest(true, TokenType.INVALID);
+
+ RpcRequest rpcRequest = createRequest();
+
+ Assert.assertTrue(isInvalidToken(rpcRequest));
+ Assert.assertFalse(isRequestValid(rpcRequest));
+ }
+
+ @Test
+ public void securityOffAndInvalidToken() {
+ initTest(false, TokenType.INVALID);
+
+ RpcRequest rpcRequest = createRequest();
+
+ Assert.assertTrue(isInvalidToken(rpcRequest));
+ Assert.assertTrue(isRequestValid(rpcRequest));
+ }
+
+ @Test
+ public void securityOnAndValidToken() {
+ initTest(true, TokenType.VALID);
+
+ RpcRequest rpcRequest = createRequest();
+
+ Assert.assertTrue(isValidToken(rpcRequest));
+ Assert.assertTrue(isRequestValid(rpcRequest));
+ }
+
+ @Test
+ public void securityOffAndValidToken() {
+ initTest(false, TokenType.VALID);
+
+ RpcRequest rpcRequest = createRequest();
+
+ Assert.assertTrue(isValidToken(rpcRequest));
+ Assert.assertTrue(isRequestValid(rpcRequest));
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/EventRouterTest.java b/server/src/test/java/com/vaadin/tests/server/EventRouterTest.java
new file mode 100644
index 0000000000..67f39d301d
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/EventRouterTest.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 EventRouterTest 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/src/test/java/com/vaadin/tests/server/ExtensionTest.java b/server/src/test/java/com/vaadin/tests/server/ExtensionTest.java
new file mode 100644
index 0000000000..8f8e8dcb59
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/ExtensionTest.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2014 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;
+
+import org.junit.Test;
+
+import com.vaadin.server.AbstractClientConnector;
+import com.vaadin.server.AbstractExtension;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.TextField;
+
+public class ExtensionTest {
+
+ public static class DummyExtension extends AbstractExtension {
+ public DummyExtension(AbstractClientConnector target) {
+ super(target);
+ }
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testRemoveExtensionFromWrongConnector() {
+ Label l = new Label();
+ TextField t = new TextField();
+ t.removeExtension(new DummyExtension(l));
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/FileResourceTest.java b/server/src/test/java/com/vaadin/tests/server/FileResourceTest.java
new file mode 100644
index 0000000000..4798fb9f05
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/FileResourceTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2014 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;
+
+import java.io.File;
+
+import org.junit.Test;
+
+import com.vaadin.server.FileResource;
+
+public class FileResourceTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullFile() {
+ new FileResource(null);
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void nonExistingFile() {
+ new FileResource(new File("nonexisting")).getStream();
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/FileTypeResolverTest.java b/server/src/test/java/com/vaadin/tests/server/FileTypeResolverTest.java
new file mode 100644
index 0000000000..3c68e86afa
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/FileTypeResolverTest.java
@@ -0,0 +1,79 @@
+package com.vaadin.tests.server;
+
+import java.io.File;
+
+import junit.framework.TestCase;
+
+import com.vaadin.util.FileTypeResolver;
+
+public class FileTypeResolverTest 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/src/test/java/com/vaadin/tests/server/IndexedContainerListenersTest.java b/server/src/test/java/com/vaadin/tests/server/IndexedContainerListenersTest.java
new file mode 100644
index 0000000000..594f5627dd
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/IndexedContainerListenersTest.java
@@ -0,0 +1,21 @@
+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.AbstractListenerMethodsTestBase;
+
+public class IndexedContainerListenersTest extends
+ AbstractListenerMethodsTestBase {
+ 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/src/test/java/com/vaadin/tests/server/KeyMapperTest.java b/server/src/test/java/com/vaadin/tests/server/KeyMapperTest.java
new file mode 100644
index 0000000000..d632e65c9f
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/KeyMapperTest.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 KeyMapperTest 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/src/test/java/com/vaadin/tests/server/MimeTypesTest.java b/server/src/test/java/com/vaadin/tests/server/MimeTypesTest.java
new file mode 100644
index 0000000000..36007fae17
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/MimeTypesTest.java
@@ -0,0 +1,17 @@
+package com.vaadin.tests.server;
+
+import junit.framework.TestCase;
+
+import com.vaadin.server.ClassResource;
+import com.vaadin.ui.Embedded;
+
+public class MimeTypesTest extends TestCase {
+
+ public void testEmbeddedPDF() {
+ 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/src/test/java/com/vaadin/tests/server/PropertyFormatterTest.java b/server/src/test/java/com/vaadin/tests/server/PropertyFormatterTest.java
new file mode 100644
index 0000000000..6563556a4e
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/PropertyFormatterTest.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 PropertyFormatterTest 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/src/test/java/com/vaadin/tests/server/PropertysetItemListenersTest.java b/server/src/test/java/com/vaadin/tests/server/PropertysetItemListenersTest.java
new file mode 100644
index 0000000000..8a91ea1868
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/PropertysetItemListenersTest.java
@@ -0,0 +1,14 @@
+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.AbstractListenerMethodsTestBase;
+
+public class PropertysetItemListenersTest extends
+ AbstractListenerMethodsTestBase {
+ public void testPropertySetChangeListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(PropertysetItem.class,
+ PropertySetChangeEvent.class, PropertySetChangeListener.class);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/SerializationTest.java b/server/src/test/java/com/vaadin/tests/server/SerializationTest.java
new file mode 100644
index 0000000000..4de30e579e
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/SerializationTest.java
@@ -0,0 +1,139 @@
+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.server.VaadinSession;
+import com.vaadin.ui.Form;
+
+public class SerializationTest extends TestCase {
+
+ public void testValidators() throws Exception {
+ RegexpValidator validator = new RegexpValidator(".*", "Error");
+ validator.validate("aaa");
+ RegexpValidator validator2 = 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);
+ }
+
+ public void testVaadinSession() throws Exception {
+ VaadinSession session = new VaadinSession(null);
+
+ session = serializeAndDeserialize(session);
+
+ assertNotNull(
+ "Pending access queue was not recreated after deserialization",
+ session.getPendingAccessQueue());
+ }
+
+ private static <S extends Serializable> S serializeAndDeserialize(S 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));
+ @SuppressWarnings("unchecked")
+ S s2 = (S) in.readObject();
+
+ // using special toString(Object) method to avoid calling
+ // Property.toString(), which will be temporarily disabled
+ // TODO This is hilariously broken (#12723)
+ 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;
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/SimpleMultiPartInputStreamTest.java b/server/src/test/java/com/vaadin/tests/server/SimpleMultiPartInputStreamTest.java
new file mode 100644
index 0000000000..04e621d5d2
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/SimpleMultiPartInputStreamTest.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.communication.FileUploadHandler.SimpleMultiPartInputStream;
+
+public class SimpleMultiPartInputStreamTest 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/src/test/java/com/vaadin/tests/server/StreamResourceTest.java b/server/src/test/java/com/vaadin/tests/server/StreamResourceTest.java
new file mode 100644
index 0000000000..4971f556db
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/StreamResourceTest.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2000-2014 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;
+
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.server.StreamResource;
+import com.vaadin.server.StreamResource.StreamSource;
+
+/**
+ *
+ * @author Vaadin Ltd
+ */
+public class StreamResourceTest {
+
+ @Test
+ public void testEqualsWithNullFields() {
+ StreamResource resource1 = new StreamResource(null, null);
+ StreamResource resource2 = new StreamResource(null, null);
+
+ Assert.assertEquals(resource1, resource2);
+ }
+
+ @Test
+ public void testNotEqualsWithNullFields() {
+ StreamResource resource1 = new StreamResource(null, null);
+ StreamResource resource2 = new StreamResource(
+ EasyMock.createMock(StreamSource.class), "");
+
+ Assert.assertNotEquals(resource1, resource2);
+ }
+
+ @Test
+ public void testHashCodeForNullFields() {
+ StreamResource resource = new StreamResource(null, null);
+ // No NPE
+ resource.hashCode();
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/StreamVariableMappingTest.java b/server/src/test/java/com/vaadin/tests/server/StreamVariableMappingTest.java
new file mode 100644
index 0000000000..b430c7cf84
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/StreamVariableMappingTest.java
@@ -0,0 +1,88 @@
+package com.vaadin.tests.server;
+
+import junit.framework.TestCase;
+
+import org.easymock.EasyMock;
+
+import com.vaadin.server.LegacyCommunicationManager;
+import com.vaadin.server.MockServletConfig;
+import com.vaadin.server.StreamVariable;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.VaadinServlet;
+import com.vaadin.server.VaadinServletService;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.tests.util.AlwaysLockedVaadinSession;
+import com.vaadin.tests.util.MockDeploymentConfiguration;
+import com.vaadin.ui.ConnectorTracker;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.Upload;
+
+public class StreamVariableMappingTest extends TestCase {
+ private static final String variableName = "myName";
+
+ private Upload owner;
+ private StreamVariable streamVariable;
+
+ private LegacyCommunicationManager cm;
+
+ @Override
+ protected void setUp() throws Exception {
+ final VaadinSession application = new AlwaysLockedVaadinSession(null);
+ final UI uI = new UI() {
+ @Override
+ protected void init(VaadinRequest request) {
+ }
+
+ @Override
+ public VaadinSession getSession() {
+ return application;
+ }
+ };
+ owner = new Upload() {
+ @Override
+ public UI getUI() {
+ return uI;
+ }
+ };
+ streamVariable = EasyMock.createMock(StreamVariable.class);
+ cm = createCommunicationManager();
+
+ super.setUp();
+ }
+
+ public void testAddStreamVariable() {
+ owner.getUI().getConnectorTracker().registerConnector(owner);
+ String targetUrl = cm.getStreamVariableTargetUrl(owner, variableName,
+ streamVariable);
+ assertTrue(targetUrl.startsWith("app://APP/UPLOAD/-1/"
+ + owner.getConnectorId() + "/myName/"));
+
+ ConnectorTracker tracker = owner.getUI().getConnectorTracker();
+ StreamVariable streamVariable2 = tracker.getStreamVariable(
+ owner.getConnectorId(), variableName);
+ assertSame(streamVariable, streamVariable2);
+ }
+
+ public void testRemoveVariable() {
+ ConnectorTracker tracker = owner.getUI().getConnectorTracker();
+ tracker.registerConnector(owner);
+ cm.getStreamVariableTargetUrl(owner, variableName, streamVariable);
+ assertNotNull(tracker.getStreamVariable(owner.getConnectorId(),
+ variableName));
+
+ tracker.cleanStreamVariable(owner.getConnectorId(), variableName);
+ assertNull(tracker.getStreamVariable(owner.getConnectorId(),
+ variableName));
+ }
+
+ private LegacyCommunicationManager createCommunicationManager()
+ throws Exception {
+ VaadinServlet servlet = new VaadinServlet();
+ servlet.init(new MockServletConfig());
+ VaadinServletService vss = new VaadinServletService(servlet,
+ new MockDeploymentConfiguration());
+ servlet.init(new MockServletConfig());
+ return new LegacyCommunicationManager(
+ new AlwaysLockedVaadinSession(vss));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/clientconnector/AttachDetachListenersTest.java b/server/src/test/java/com/vaadin/tests/server/clientconnector/AttachDetachListenersTest.java
new file mode 100644
index 0000000000..28c5be29cb
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/clientconnector/AttachDetachListenersTest.java
@@ -0,0 +1,195 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.tests.server.clientconnector;
+
+import org.easymock.EasyMock;
+import org.easymock.IArgumentMatcher;
+import org.easymock.IMocksControl;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.event.ConnectorEvent;
+import com.vaadin.server.ClientConnector.AttachEvent;
+import com.vaadin.server.ClientConnector.AttachListener;
+import com.vaadin.server.ClientConnector.DetachEvent;
+import com.vaadin.server.ClientConnector.DetachListener;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.VaadinService;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.tests.util.AlwaysLockedVaadinSession;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.CssLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Layout;
+import com.vaadin.ui.UI;
+
+public class AttachDetachListenersTest {
+
+ private IMocksControl control;
+
+ private VaadinSession session;
+ private UI ui;
+ private Layout content;
+ private Component component;
+
+ AttachListener attachListener;
+ DetachListener detachListener;
+
+ @Before
+ public void setUp() {
+ control = EasyMock.createStrictControl();
+
+ session = new AlwaysLockedVaadinSession(
+ control.createMock(VaadinService.class));
+
+ ui = new UI() {
+ @Override
+ protected void init(VaadinRequest request) {
+ }
+ };
+ content = new CssLayout();
+ component = new Label();
+
+ attachListener = control.createMock(AttachListener.class);
+ detachListener = control.createMock(DetachListener.class);
+ }
+
+ @Test
+ public void attachListeners_setSessionLast() {
+ attachListener.attach(eventEquals(new AttachEvent(component)));
+ attachListener.attach(eventEquals(new AttachEvent(content)));
+ attachListener.attach(eventEquals(new AttachEvent(ui)));
+
+ control.replay();
+
+ ui.addAttachListener(attachListener);
+ content.addAttachListener(attachListener);
+ component.addAttachListener(attachListener);
+
+ ui.setContent(content);
+ content.addComponent(component);
+ ui.setSession(session);
+
+ control.verify();
+ }
+
+ @Test
+ public void attachListeners_setSessionFirst() {
+ attachListener.attach(eventEquals(new AttachEvent(ui)));
+ attachListener.attach(eventEquals(new AttachEvent(content)));
+ attachListener.attach(eventEquals(new AttachEvent(component)));
+
+ control.replay();
+
+ ui.addAttachListener(attachListener);
+ content.addAttachListener(attachListener);
+ component.addAttachListener(attachListener);
+
+ ui.setSession(session);
+ ui.setContent(content);
+ content.addComponent(component);
+
+ control.verify();
+ }
+
+ @Test
+ public void attachListeners_setSessionBetween() {
+ attachListener.attach(eventEquals(new AttachEvent(content)));
+ attachListener.attach(eventEquals(new AttachEvent(ui)));
+ attachListener.attach(eventEquals(new AttachEvent(component)));
+
+ control.replay();
+
+ ui.addAttachListener(attachListener);
+ content.addAttachListener(attachListener);
+ component.addAttachListener(attachListener);
+
+ ui.setContent(content);
+ ui.setSession(session);
+ content.addComponent(component);
+
+ control.verify();
+ }
+
+ @Test
+ public void detachListeners_setSessionNull() {
+ setupDetachListeners();
+
+ ui.setContent(content);
+ content.addComponent(component);
+ ui.setSession(null);
+
+ control.verify();
+ }
+
+ @Test
+ public void detachListeners_removeComponent() {
+ setupDetachListeners();
+
+ ui.setContent(content);
+ content.addComponent(component);
+ content.removeAllComponents();
+ ui.setSession(null);
+
+ control.verify();
+ }
+
+ @Test
+ public void detachListeners_setContentNull() {
+ setupDetachListeners();
+
+ ui.setContent(content);
+ content.addComponent(component);
+ ui.setContent(null);
+ ui.setSession(null);
+
+ control.verify();
+ }
+
+ public static class EventEquals<E extends ConnectorEvent> implements
+ IArgumentMatcher {
+
+ private E expected;
+
+ public EventEquals(E expected) {
+ this.expected = expected;
+ }
+
+ @Override
+ public void appendTo(StringBuffer buffer) {
+ buffer.append("EventEquals(");
+ buffer.append("expected " + expected.getClass().getSimpleName()
+ + " with connector " + expected.getConnector());
+ buffer.append(")");
+ }
+
+ @Override
+ public boolean matches(Object argument) {
+ return expected.getClass().isInstance(argument)
+ && ((ConnectorEvent) argument).getConnector() == expected
+ .getConnector();
+ }
+ }
+
+ public static <E extends ConnectorEvent> E eventEquals(E expected) {
+ EasyMock.reportMatcher(new EventEquals<E>(expected));
+ return null;
+ }
+
+ private void setupDetachListeners() {
+ detachListener.detach(eventEquals(new DetachEvent(component)));
+ detachListener.detach(eventEquals(new DetachEvent(content)));
+ detachListener.detach(eventEquals(new DetachEvent(ui)));
+
+ control.replay();
+
+ ui.addDetachListener(detachListener);
+ content.addDetachListener(detachListener);
+ component.addDetachListener(detachListener);
+
+ ui.setSession(session);
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/AbstractListenerMethodsTestBase.java b/server/src/test/java/com/vaadin/tests/server/component/AbstractListenerMethodsTestBase.java
new file mode 100644
index 0000000000..4e8f987def
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/AbstractListenerMethodsTestBase.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 AbstractListenerMethodsTestBase 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 "
+ + AbstractListenerMethodsTestBase.class
+ .getName() + ";");
+ System.out.println("import " + c.getName() + ";");
+ System.out.println("public class "
+ + c.getSimpleName()
+ + "Listeners extends "
+ + AbstractListenerMethodsTestBase.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/src/test/java/com/vaadin/tests/server/component/ComponentSizeParseTest.java b/server/src/test/java/com/vaadin/tests/server/component/ComponentSizeParseTest.java
new file mode 100644
index 0000000000..2083d1f473
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/ComponentSizeParseTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2000-2014 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;
+
+import junit.framework.TestCase;
+
+import org.junit.Assert;
+
+import com.vaadin.server.Sizeable.Unit;
+import com.vaadin.shared.ui.label.LabelState;
+import com.vaadin.ui.Label;
+
+public class ComponentSizeParseTest extends TestCase {
+
+ private final class LabelWithPublicState extends Label {
+ @Override
+ protected LabelState getState() {
+ return super.getState();
+ }
+ }
+
+ public void testAllTheUnit() {
+ testUnit("10.0px", 10, Unit.PIXELS);
+ testUnit("10.0pt", 10, Unit.POINTS);
+ testUnit("10.0pc", 10, Unit.PICAS);
+ testUnit("10.0em", 10, Unit.EM);
+ testUnit("10.0rem", 10, Unit.REM);
+ testUnit("10.0mm", 10, Unit.MM);
+ testUnit("10.0cm", 10, Unit.CM);
+ testUnit("10.0in", 10, Unit.INCH);
+ testUnit("10.0%", 10, Unit.PERCENTAGE);
+ }
+
+ private void testUnit(String string, int amout, Unit unit) {
+ LabelWithPublicState label = new LabelWithPublicState();
+ label.setHeight(string);
+
+ Assert.assertEquals(amout, label.getHeight(), 0);
+ Assert.assertEquals(unit, label.getHeightUnits());
+
+ label = new LabelWithPublicState();
+
+ label.setHeight(10, unit);
+ label.beforeClientResponse(true);
+ Assert.assertEquals(string, label.getState().height);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/DeclarativeMarginTestBase.java b/server/src/test/java/com/vaadin/tests/server/component/DeclarativeMarginTestBase.java
new file mode 100644
index 0000000000..faaf8ebfc2
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/DeclarativeMarginTestBase.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2000-2014 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;
+
+import org.junit.Assert;
+
+import com.vaadin.shared.ui.MarginInfo;
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.Layout;
+import com.vaadin.ui.Layout.MarginHandler;
+
+public abstract class DeclarativeMarginTestBase<L extends Layout & MarginHandler>
+ extends DeclarativeTestBase<L> {
+
+ protected void testMargins(String componentTag) {
+
+ for (int i = 0; i < 16; ++i) {
+ boolean top = (i & 1) == 1;
+ boolean right = (i & 2) == 2;
+ boolean bottom = (i & 4) == 4;
+ boolean left = (i & 8) == 8;
+
+ MarginInfo m = new MarginInfo(top, right, bottom, left);
+
+ String design = getMarginTag(componentTag, top, right, bottom, left);
+
+ // The assertEquals machinery in DeclarativeTestBase uses bean
+ // introspection and MarginInfo is not a proper bean. It ends up
+ // considering *all* MarginInfo objects equal... (#18229)
+ L layout = read(design);
+ Assert.assertEquals(m, layout.getMargin());
+
+ testWrite(design, layout);
+ }
+ }
+
+ private String getMarginTag(String componentTag, boolean top,
+ boolean right, boolean bottom, boolean left) {
+ String s = "<" + componentTag + " ";
+
+ if (left && right && top && bottom) {
+ s += "margin";
+ } else {
+ if (left) {
+ s += "margin-left ";
+ }
+ if (right) {
+ s += "margin-right ";
+ }
+ if (top) {
+ s += "margin-top ";
+ }
+ if (bottom) {
+ s += "margin-bottom ";
+ }
+ }
+ return s + " />";
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/FieldDefaultValues.java b/server/src/test/java/com/vaadin/tests/server/component/FieldDefaultValues.java
new file mode 100644
index 0000000000..16bbd7008f
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/FieldDefaultValues.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2000-2014 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;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.tests.VaadinClasses;
+import com.vaadin.ui.Field;
+import com.vaadin.ui.Slider;
+
+public class FieldDefaultValues {
+
+ @Test
+ public void testFieldsHaveDefaultValueAfterClear() throws Exception {
+ for (Field<?> field : createFields()) {
+ Object originalValue = field.getValue();
+
+ field.clear();
+
+ Object clearedValue = field.getValue();
+
+ Assert.assertEquals("Expected to get default value after clearing "
+ + field.getClass().getName(), originalValue, clearedValue);
+ }
+ }
+
+ @Test
+ public void testFieldsAreEmptyAfterClear() throws Exception {
+ for (Field<?> field : createFields()) {
+ field.clear();
+
+ if (field instanceof Slider) {
+ Assert.assertFalse(
+ "Slider should not be empty even after being cleared",
+ field.isEmpty());
+
+ } else {
+ Assert.assertTrue(field.getClass().getName()
+ + " should be empty after being cleared",
+ field.isEmpty());
+ }
+ }
+ }
+
+ @SuppressWarnings("rawtypes")
+ private static List<Field<?>> createFields() throws InstantiationException,
+ IllegalAccessException {
+ List<Field<?>> fieldInstances = new ArrayList<Field<?>>();
+
+ for (Class<? extends Field> fieldType : VaadinClasses.getFields()) {
+ fieldInstances.add(fieldType.newInstance());
+ }
+ return fieldInstances;
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/FinalMethodTest.java b/server/src/test/java/com/vaadin/tests/server/component/FinalMethodTest.java
new file mode 100644
index 0000000000..ad80007882
--- /dev/null
+++ b/server/src/test/java/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/src/test/java/com/vaadin/tests/server/component/ReadEmptyDesignTest.java b/server/src/test/java/com/vaadin/tests/server/component/ReadEmptyDesignTest.java
new file mode 100644
index 0000000000..5cf3b9700e
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/ReadEmptyDesignTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2000-2014 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;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import junit.framework.TestCase;
+
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.DocumentType;
+import org.jsoup.nodes.Element;
+
+import com.vaadin.ui.Component;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.declarative.Design;
+import com.vaadin.ui.declarative.DesignContext;
+import com.vaadin.ui.declarative.DesignException;
+
+/**
+ * Test cases for checking that reading a design with no elements in the html
+ * body produces null as the root component.
+ */
+public class ReadEmptyDesignTest extends TestCase {
+ InputStream is;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ String html = createDesign().toString();
+ is = new ByteArrayInputStream(html.getBytes());
+ }
+
+ public void testReadComponent() {
+ Component root = Design.read(is);
+ assertNull("The root component should be null.", root);
+ }
+
+ public void testReadContext() {
+ DesignContext ctx = Design.read(is, null);
+ assertNotNull("The design context should not be null.", ctx);
+ assertNull("The root component should be null.", ctx.getRootComponent());
+ }
+
+ public void testReadContextWithRootParameter() {
+ try {
+ Component rootComponent = new VerticalLayout();
+ DesignContext ctx = Design.read(is, rootComponent);
+ fail("Reading a design with no elements should fail when a non-null root Component is specified.");
+ } catch (DesignException e) {
+ // This is the expected outcome, nothing to do.
+ }
+ }
+
+ private Document createDesign() {
+ Document doc = new Document("");
+ DocumentType docType = new DocumentType("html", "", "", "");
+ doc.appendChild(docType);
+ Element html = doc.createElement("html");
+ doc.appendChild(html);
+ html.appendChild(doc.createElement("head"));
+ html.appendChild(doc.createElement("body"));
+ return doc;
+ }
+} \ No newline at end of file
diff --git a/server/src/test/java/com/vaadin/tests/server/component/StateGetDoesNotMarkDirtyTest.java b/server/src/test/java/com/vaadin/tests/server/component/StateGetDoesNotMarkDirtyTest.java
new file mode 100644
index 0000000000..da4d8a92d4
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/StateGetDoesNotMarkDirtyTest.java
@@ -0,0 +1,100 @@
+package com.vaadin.tests.server.component;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import org.mockito.Mockito;
+
+import com.vaadin.tests.VaadinClasses;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.ConnectorTracker;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.UI;
+
+public class StateGetDoesNotMarkDirtyTest extends TestCase {
+
+ private Set<String> excludedMethods = new HashSet<String>();
+
+ @Override
+ protected void setUp() throws Exception {
+ excludedMethods.add(Label.class.getName() + "getDataSourceValue");
+ excludedMethods.add("getConnectorId");
+ }
+
+ public void testGetDoesntMarkStateDirty() throws Exception {
+ for (Class<? extends Component> c : VaadinClasses.getComponents()) {
+ Component newInstance = construct(c);
+ prepareMockUI(newInstance);
+
+ Set<Method> methods = new HashSet<Method>();
+ methods.addAll(Arrays.asList(c.getMethods()));
+ methods.addAll(Arrays.asList(c.getDeclaredMethods()));
+ for (Method method : methods) {
+ try {
+ if (method.getName().startsWith("is")
+ || method.getName().startsWith("get")) {
+ if (method.getName().startsWith("getState")) {
+ continue;
+ }
+ if (method.getParameterTypes().length > 0) {
+ // usually getters do not have params, if they have
+ // we still wouldnt know what to put into
+ continue;
+ }
+ if (excludedMethods.contains(c.getName()
+ + method.getName())) {
+ // blacklisted method for specific classes
+ continue;
+ }
+ if (excludedMethods.contains(method.getName())) {
+ // blacklisted method for all classes
+ continue;
+ }
+ // just to make sure we can invoke it
+ method.setAccessible(true);
+ method.invoke(newInstance);
+ }
+ } catch (Exception e) {
+ System.err.println("problem with method " + c.getName()
+ + "# " + method.getName());
+ e.printStackTrace();
+ throw e;
+ }
+ }
+ }
+
+ }
+
+ private void prepareMockUI(Component newInstance) {
+ UI ui = Mockito.mock(UI.class);
+ Mockito.when(ui.getLocale()).thenReturn(Locale.ENGLISH);
+ ConnectorTracker connectorTracker = Mockito
+ .mock(ConnectorTracker.class);
+ Mockito.when(ui.getConnectorTracker()).thenReturn(connectorTracker);
+ Mockito.doThrow(new RuntimeException("getState(true) called in getter"))
+ .when(connectorTracker).markDirty(newInstance);
+
+ newInstance.setParent(ui);
+ }
+
+ private Component construct(Class<? extends Component> c) {
+ try {
+ try {
+ Constructor<? extends Component> declaredConstructor = c
+ .getDeclaredConstructor();
+ declaredConstructor.setAccessible(true);
+ return declaredConstructor.newInstance();
+ } catch (NoSuchMethodException e) {
+ return c.newInstance();
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/WriteEmptyDesignTest.java b/server/src/test/java/com/vaadin/tests/server/component/WriteEmptyDesignTest.java
new file mode 100644
index 0000000000..a535de2b24
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/WriteEmptyDesignTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2000-2014 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;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import junit.framework.TestCase;
+
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+
+import com.vaadin.ui.Component;
+import com.vaadin.ui.declarative.Design;
+import com.vaadin.ui.declarative.DesignContext;
+
+/**
+ * Test cases for checking that writing a component hierarchy with null root
+ * produces an html document that has no elements in the html body.
+ */
+public class WriteEmptyDesignTest extends TestCase {
+
+ public void testWriteComponent() throws IOException {
+ OutputStream os = new ByteArrayOutputStream();
+ Design.write((Component) null, os);
+ checkHtml(os.toString());
+ }
+
+ public void testWriteContext() throws IOException {
+ OutputStream os = new ByteArrayOutputStream();
+ DesignContext ctx = new DesignContext();
+ ctx.setRootComponent(null);
+ Design.write(ctx, os);
+ checkHtml(os.toString());
+ }
+
+ private void checkHtml(String html) {
+ Document doc = Jsoup.parse(html);
+ Element body = doc.body();
+ assertEquals("There should be no elements in the html body.", "",
+ body.html());
+ }
+} \ No newline at end of file
diff --git a/server/src/test/java/com/vaadin/tests/server/component/absolutelayout/AbsoluteLayoutDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/absolutelayout/AbsoluteLayoutDeclarativeTest.java
new file mode 100644
index 0000000000..f00eb91c50
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/absolutelayout/AbsoluteLayoutDeclarativeTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2014 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.absolutelayout;
+
+import org.junit.Test;
+
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.AbsoluteLayout;
+import com.vaadin.ui.Button;
+
+/**
+ * Tests declarative support for implementations of {@link AbsoluteLayout}.
+ *
+ * @since 7.4
+ * @author Vaadin Ltd
+ */
+public class AbsoluteLayoutDeclarativeTest extends
+ DeclarativeTestBase<AbsoluteLayout> {
+
+ @Test
+ public void testAbsoluteLayoutFeatures() {
+ String design = "<vaadin-absolute-layout caption=\"test-layout\">"
+ + "<vaadin-button :top='100px' :left='0px' :z-index=21>OK</vaadin-button>"
+ + "<vaadin-button :bottom='0px' :right='0px'>Cancel</vaadin-button>"
+ + "</vaadin-absolute-layout>";
+ AbsoluteLayout layout = new AbsoluteLayout();
+ layout.setCaption("test-layout");
+ Button b1 = new Button("OK");
+ b1.setCaptionAsHtml(true);
+ Button b2 = new Button("Cancel");
+ b2.setCaptionAsHtml(true);
+ layout.addComponent(b1, "top: 100px; left: 0px; z-index: 21");
+ layout.addComponent(b2, "bottom: 0px; right: 0px;");
+
+ testWrite(design, layout);
+ testRead(design, layout);
+ }
+
+ @Test
+ public void testEmpty() {
+ String design = "<vaadin-absolute-layout/>";
+ AbsoluteLayout layout = new AbsoluteLayout();
+ testRead(design, layout);
+ testWrite(design, layout);
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/absolutelayout/AbsoluteLayoutListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/absolutelayout/AbsoluteLayoutListenersTest.java
new file mode 100644
index 0000000000..ece4b5f380
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/absolutelayout/AbsoluteLayoutListenersTest.java
@@ -0,0 +1,14 @@
+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.AbstractListenerMethodsTestBase;
+import com.vaadin.ui.AbsoluteLayout;
+
+public class AbsoluteLayoutListenersTest extends
+ AbstractListenerMethodsTestBase {
+ public void testLayoutClickListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(AbsoluteLayout.class, LayoutClickEvent.class,
+ LayoutClickListener.class);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/absolutelayout/AddComponentsTest.java b/server/src/test/java/com/vaadin/tests/server/component/absolutelayout/AddComponentsTest.java
new file mode 100644
index 0000000000..96f27851cf
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/absolutelayout/AddComponentsTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2000-2014 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.absolutelayout;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import com.vaadin.ui.AbsoluteLayout;
+import com.vaadin.ui.Button;
+
+/**
+ * Tests adding of components to {@link AbsoluteLayout}
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class AddComponentsTest {
+
+ @Test
+ public void testAddExistingWithDifferentPosition() {
+ AbsoluteLayout layout = new AbsoluteLayout();
+ Button b1 = new Button("OK");
+ layout.addComponent(b1, "top: 100px; left: 0px;");
+ assertEquals(1, layout.getComponentCount());
+ layout.addComponent(b1, "bottom: 0px; right: 0px;");
+ assertEquals(1, layout.getComponentCount());
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/absolutelayout/ComponentPositionTest.java b/server/src/test/java/com/vaadin/tests/server/component/absolutelayout/ComponentPositionTest.java
new file mode 100644
index 0000000000..eac7ff4d8a
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/absolutelayout/ComponentPositionTest.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 ComponentPositionTest 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/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentDeclarativeTest.java
new file mode 100644
index 0000000000..fc97c84952
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentDeclarativeTest.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright 2000-2014 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.abstractcomponent;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.lang.reflect.Field;
+import java.nio.charset.Charset;
+import java.util.Locale;
+
+import org.jsoup.nodes.Attributes;
+import org.jsoup.nodes.Element;
+import org.jsoup.parser.Tag;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.server.ErrorMessage.ErrorLevel;
+import com.vaadin.server.ExternalResource;
+import com.vaadin.server.FileResource;
+import com.vaadin.server.Responsive;
+import com.vaadin.server.ThemeResource;
+import com.vaadin.server.UserError;
+import com.vaadin.shared.ui.label.ContentMode;
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.AbstractComponent;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.HorizontalSplitPanel;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.declarative.Design;
+import com.vaadin.ui.declarative.DesignContext;
+
+/**
+ * Test cases for reading and writing the properties of AbstractComponent.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class AbstractComponentDeclarativeTest extends
+ DeclarativeTestBase<AbstractComponent> {
+
+ private AbstractComponent component;
+
+ @Before
+ public void setUp() {
+ Label l = new Label();
+ l.setContentMode(ContentMode.HTML);
+ component = l;
+ }
+
+ @Test
+ public void testEmptyDesign() {
+ String design = "<vaadin-label>";
+ testRead(design, component);
+ testWrite(design, component);
+ }
+
+ @Test
+ public void testProperties() {
+ String design = "<vaadin-label id=\"testId\" primary-style-name=\"test-style\" "
+ + "caption=\"test-caption\" locale=\"fi_FI\" description=\"test-description\" "
+ + "error=\"<div>test-error</div>\" immediate />";
+ component.setId("testId");
+ component.setPrimaryStyleName("test-style");
+ component.setCaption("test-caption");
+ component.setLocale(new Locale("fi", "FI"));
+ component.setDescription("test-description");
+ component.setComponentError(new UserError("<div>test-error</div>",
+ com.vaadin.server.AbstractErrorMessage.ContentMode.HTML,
+ ErrorLevel.ERROR));
+ component.setImmediate(true);
+ testRead(design, component);
+ testWrite(design, component);
+ }
+
+ @Test
+ public void testReadImmediate() {
+ // Additional tests for the immediate property, including
+ // explicit immediate values
+ String[] design = { "<vaadin-label/>",
+ "<vaadin-label immediate=\"false\"/>",
+ "<vaadin-label immediate=\"true\"/>",
+ "<vaadin-label immediate />" };
+ Boolean[] explicitImmediate = { null, Boolean.FALSE, Boolean.TRUE,
+ Boolean.TRUE };
+ boolean[] immediate = { false, false, true, true };
+ for (int i = 0; i < design.length; i++) {
+ component = (AbstractComponent) Design
+ .read(new ByteArrayInputStream(design[i].getBytes(Charset
+ .forName("UTF-8"))));
+ assertEquals(immediate[i], component.isImmediate());
+ assertEquals(explicitImmediate[i], getExplicitImmediate(component));
+ }
+ }
+
+ @Test
+ public void testExternalIcon() {
+ String design = "<vaadin-label icon=\"http://example.com/example.gif\"/>";
+ component
+ .setIcon(new ExternalResource("http://example.com/example.gif"));
+ testRead(design, component);
+ testWrite(design, component);
+ }
+
+ @Test
+ public void testThemeIcon() {
+ String design = "<vaadin-label icon=\"theme://example.gif\"/>";
+ component.setIcon(new ThemeResource("example.gif"));
+ testRead(design, component);
+ testWrite(design, component);
+ }
+
+ @Test
+ public void testFileResourceIcon() {
+ String design = "<vaadin-label icon=\"img/example.gif\"/>";
+ component.setIcon(new FileResource(new File("img/example.gif")));
+ testRead(design, component);
+ testWrite(design, component);
+ }
+
+ @Test
+ public void testWidthAndHeight() {
+ String design = "<vaadin-label width=\"70%\" height=\"12px\"/>";
+ component.setWidth("70%");
+ component.setHeight("12px");
+ testRead(design, component);
+ testWrite(design, component);
+ }
+
+ @Test
+ public void testSizeFull() {
+ String design = "<vaadin-label size-full />";
+ component.setSizeFull();
+ testRead(design, component);
+ testWrite(design, component);
+ }
+
+ @Test
+ public void testSizeAuto() {
+ String design = "<vaadin-label size-auto />";
+ component.setSizeUndefined();
+ testRead(design, component);
+ testWrite(design, component);
+ }
+
+ @Test
+ public void testHeightFull() {
+ String design = "<vaadin-label height-full width=\"20px\"/>";
+ component.setHeight("100%");
+ component.setWidth("20px");
+ testRead(design, component);
+ testWrite(design, component);
+ }
+
+ @Test
+ public void testHeightAuto() {
+ String design = "<vaadin-horizontal-split-panel height-auto width=\"20px\" >";
+ // we need to have default height of 100% -> use split panel
+ AbstractComponent component = new HorizontalSplitPanel();
+ component.setHeight(null);
+ component.setWidth("20px");
+ testRead(design, component);
+ testWrite(design, component);
+ }
+
+ @Test
+ public void testWidthFull() {
+ String design = "<vaadin-button width-full height=\"20px\">Foo</vaadin-button>";
+ AbstractComponent component = new Button();
+ component.setCaptionAsHtml(true);
+ component.setCaption("Foo");
+ component.setHeight("20px");
+ component.setWidth("100%");
+ testRead(design, component);
+ testWrite(design, component);
+ }
+
+ @Test
+ public void testWidthAuto() {
+ String design = "<vaadin-label height=\"20px\"/ width-auto />";
+ component.setCaptionAsHtml(false);
+ component.setHeight("20px");
+ component.setWidth(null);
+ testRead(design, component);
+ testWrite(design, component);
+ }
+
+ @Test
+ public void testResponsive() {
+ String design = "<vaadin-label responsive />";
+ Responsive.makeResponsive(component);
+ testRead(design, component);
+ testWrite(design, component);
+ }
+
+ @Test
+ public void testResponsiveFalse() {
+ String design = "<vaadin-label responsive =\"false\"/>";
+ // Only test read as the attribute responsive=false would not be written
+ testRead(design, component);
+ }
+
+ @Test
+ public void testReadAlreadyResponsive() {
+ AbstractComponent component = new Label();
+ Responsive.makeResponsive(component);
+ Element design = createDesign(true);
+ component.readDesign(design, new DesignContext());
+ assertEquals("Component should have only one extension", 1, component
+ .getExtensions().size());
+ }
+
+ private Element createDesign(boolean responsive) {
+ Attributes attributes = new Attributes();
+ attributes.put("responsive", responsive);
+ Element node = new Element(Tag.valueOf("vaadin-label"), "", attributes);
+ return node;
+ }
+
+ private Boolean getExplicitImmediate(AbstractComponent component) {
+ try {
+ Field immediate = AbstractComponent.class
+ .getDeclaredField("explicitImmediateValue");
+ immediate.setAccessible(true);
+ return (Boolean) immediate.get(component);
+ } catch (Exception e) {
+ throw new RuntimeException(
+ "Getting the field explicitImmediateValue failed.");
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentStyleNamesTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentStyleNamesTest.java
new file mode 100644
index 0000000000..18eb79aadc
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentStyleNamesTest.java
@@ -0,0 +1,61 @@
+package com.vaadin.tests.server.component.abstractcomponent;
+
+import junit.framework.TestCase;
+
+import com.vaadin.ui.AbstractComponent;
+
+public class AbstractComponentStyleNamesTest 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/src/test/java/com/vaadin/tests/server/component/abstractcomponentcontainer/AbstractComponentContainerListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractcomponentcontainer/AbstractComponentContainerListenersTest.java
new file mode 100644
index 0000000000..3a2150b700
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractcomponentcontainer/AbstractComponentContainerListenersTest.java
@@ -0,0 +1,22 @@
+package com.vaadin.tests.server.component.abstractcomponentcontainer;
+
+import com.vaadin.tests.server.component.AbstractListenerMethodsTestBase;
+import com.vaadin.ui.HasComponents.ComponentAttachEvent;
+import com.vaadin.ui.HasComponents.ComponentAttachListener;
+import com.vaadin.ui.HasComponents.ComponentDetachEvent;
+import com.vaadin.ui.HasComponents.ComponentDetachListener;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.VerticalLayout;
+
+public class AbstractComponentContainerListenersTest extends
+ AbstractListenerMethodsTestBase {
+ 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/src/test/java/com/vaadin/tests/server/component/abstractcomponentcontainer/AddParentAsChildTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractcomponentcontainer/AddParentAsChildTest.java
new file mode 100644
index 0000000000..176d178112
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractcomponentcontainer/AddParentAsChildTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2000-2014 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.abstractcomponentcontainer;
+
+import java.util.Iterator;
+
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+import com.vaadin.ui.AbstractComponentContainer;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.HasComponents;
+
+/**
+ * Tests for avoiding add parent as child for
+ * {@link AbstractComponentContainer#addComponent(Component)}
+ *
+ * @author Vaadin Ltd
+ */
+public class AddParentAsChildTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testAddComponent() {
+ AbstractComponentContainer container = new ComponentContainer();
+ HasComponents hasComponentsMock = EasyMock
+ .createMock(HasComponents.class);
+ container.setParent(hasComponentsMock);
+
+ container.addComponent(hasComponentsMock);
+ }
+
+ class ComponentContainer extends AbstractComponentContainer {
+
+ @Override
+ public void replaceComponent(Component oldComponent,
+ Component newComponent) {
+ }
+
+ @Override
+ public int getComponentCount() {
+ return 0;
+ }
+
+ @Override
+ public Iterator<Component> iterator() {
+ return null;
+ }
+
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbsFieldValidatorsTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbsFieldValidatorsTest.java
new file mode 100644
index 0000000000..59831d92e1
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbsFieldValidatorsTest.java
@@ -0,0 +1,117 @@
+package com.vaadin.tests.server.component.abstractfield;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+import com.vaadin.data.Validator;
+import com.vaadin.ui.AbstractField;
+
+public class AbsFieldValidatorsTest {
+
+ AbstractField<Object> field = new AbstractField<Object>() {
+ @Override
+ public Class getType() {
+ return Object.class;
+ }
+ };
+
+ Validator validator = EasyMock.createMock(Validator.class);
+ Validator validator2 = EasyMock.createMock(Validator.class);
+
+ @Test
+ public void testAddValidator() {
+ assertNotNull(field.getValidators());
+ assertEquals(0, field.getValidators().size());
+
+ field.addValidator(validator);
+ assertEquals(1, field.getValidators().size());
+ assertTrue(field.getValidators().contains(validator));
+
+ field.addValidator(validator2);
+ assertEquals(2, field.getValidators().size());
+ assertTrue(field.getValidators().contains(validator));
+ assertTrue(field.getValidators().contains(validator2));
+ }
+
+ @Test
+ public void testRemoveValidator() {
+ field.addValidator(validator);
+ field.addValidator(validator2);
+
+ field.removeValidator(validator);
+ assertNotNull(field.getValidators());
+ assertEquals(1, field.getValidators().size());
+ assertFalse(field.getValidators().contains(validator));
+ assertTrue(field.getValidators().contains(validator2));
+
+ field.removeValidator(validator2);
+ assertNotNull(field.getValidators());
+ assertEquals(0, field.getValidators().size());
+ assertFalse(field.getValidators().contains(validator));
+ assertFalse(field.getValidators().contains(validator2));
+ }
+
+ @Test
+ public void testRemoveAllValidators() {
+ field.addValidator(validator);
+ field.addValidator(validator2);
+
+ field.removeAllValidators();
+ assertNotNull(field.getValidators());
+ assertEquals(0, field.getValidators().size());
+ assertFalse(field.getValidators().contains(validator));
+ assertFalse(field.getValidators().contains(validator2));
+ }
+
+ @Test
+ public void validatorShouldMakeImmediate() {
+ assertFalse("field should not be immediate by default",
+ field.isImmediate());
+ field.addValidator(validator);
+ assertTrue("field should be immediate when it has a validator",
+ field.isImmediate());
+ }
+
+ @Test
+ public void nonImmediateFieldWithValidator() {
+ field.setImmediate(false);
+ field.addValidator(validator);
+ assertFalse("field should be non-immediate because explicitly set",
+ field.isImmediate());
+ }
+
+ @Test
+ public void removeValidatorMakesNonImmediate() {
+ field.addValidator(validator);
+ field.removeValidator(validator);
+ assertFalse(
+ "field should be non-immediate after validator was removed",
+ field.isImmediate());
+ }
+
+ @Test
+ public void requiredMakesImmediate() {
+ assertFalse("field should not be immediate by default",
+ field.isImmediate());
+ field.setRequired(true);
+ assertTrue("field should be immediate when it is required",
+ field.isImmediate());
+ }
+
+ @Test
+ public void removeRequiredMakesNonImmediate() {
+ assertFalse("field should not be immediate by default",
+ field.isImmediate());
+ field.setRequired(true);
+ field.setRequired(false);
+ assertFalse(
+ "field should not be immediate even though it was required",
+ field.isImmediate());
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbsFieldValueConversionErrorTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbsFieldValueConversionErrorTest.java
new file mode 100644
index 0000000000..02aa6afe07
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbsFieldValueConversionErrorTest.java
@@ -0,0 +1,87 @@
+package com.vaadin.tests.server.component.abstractfield;
+
+import junit.framework.TestCase;
+
+import org.junit.Assert;
+
+import com.vaadin.data.Validator.InvalidValueException;
+import com.vaadin.data.util.MethodProperty;
+import com.vaadin.data.util.converter.Converter.ConversionException;
+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.TextField;
+
+public class AbsFieldValueConversionErrorTest 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 testValidateConversionErrorParameters() {
+ TextField tf = new TextField();
+ tf.setConverter(new StringToIntegerConverter());
+ tf.setPropertyDataSource(new MethodProperty<String>(paulaBean, "age"));
+ tf.setConversionError("(Type: {0}) Converter exception message: {1}");
+ tf.setValue("abc");
+ try {
+ tf.validate();
+ fail();
+ } catch (InvalidValueException e) {
+ Assert.assertEquals(
+ "(Type: Integer) Converter exception message: Could not convert 'abc' to java.lang.Integer",
+ e.getMessage());
+ }
+
+ }
+
+ public void testConvertToModelConversionErrorParameters() {
+ TextField tf = new TextField();
+ tf.setConverter(new StringToIntegerConverter());
+ tf.setPropertyDataSource(new MethodProperty<String>(paulaBean, "age"));
+ tf.setConversionError("(Type: {0}) Converter exception message: {1}");
+ tf.setValue("abc");
+ try {
+ tf.getConvertedValue();
+ fail();
+ } catch (ConversionException e) {
+ Assert.assertEquals(
+ "(Type: Integer) Converter exception message: Could not convert 'abc' to java.lang.Integer",
+ e.getMessage());
+ }
+
+ }
+
+ public void testNullConversionMessages() {
+ TextField tf = new TextField();
+ tf.setConverter(new StringToIntegerConverter());
+ tf.setPropertyDataSource(new MethodProperty<String>(paulaBean, "age"));
+ tf.setConversionError(null);
+ tf.setValue("abc");
+ try {
+ tf.validate();
+ fail();
+ } catch (InvalidValueException e) {
+ Assert.assertEquals(null, e.getMessage());
+ }
+
+ }
+
+ public void testDefaultConversionErrorMessage() {
+ TextField tf = new TextField();
+ tf.setConverter(new StringToIntegerConverter());
+ tf.setPropertyDataSource(new MethodProperty<String>(paulaBean, "age"));
+ tf.setValue("abc");
+
+ try {
+ tf.validate();
+ fail();
+ } catch (InvalidValueException e) {
+ Assert.assertEquals("Could not convert value to Integer",
+ e.getMessage());
+ }
+
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbsFieldValueConversionsTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbsFieldValueConversionsTest.java
new file mode 100644
index 0000000000..94ff10926f
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbsFieldValueConversionsTest.java
@@ -0,0 +1,266 @@
+package com.vaadin.tests.server.component.abstractfield;
+
+import java.util.Locale;
+
+import junit.framework.TestCase;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.util.MethodProperty;
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.data.util.converter.Converter;
+import com.vaadin.data.util.converter.Converter.ConversionException;
+import com.vaadin.data.util.converter.StringToIntegerConverter;
+import com.vaadin.server.VaadinSession;
+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.tests.util.AlwaysLockedVaadinSession;
+import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.TextField;
+
+public class AbsFieldValueConversionsTest extends TestCase {
+
+ Person paulaBean = new Person("Paula", "Brilliant", "paula@brilliant.com",
+ 34, Sex.FEMALE, new Address("Paula street 1", 12345, "P-town",
+ Country.FINLAND));
+
+ /**
+ * Java uses a non-breaking space (ascii 160) instead of space when
+ * formatting
+ */
+ private static final char FORMATTED_SPACE = 160;
+
+ 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 testNonmodifiedBufferedFieldConversion() {
+ VaadinSession.setCurrent(new AlwaysLockedVaadinSession(null));
+ TextField tf = new TextField("salary");
+ tf.setBuffered(true);
+ tf.setLocale(new Locale("en", "US"));
+ ObjectProperty<Integer> ds = new ObjectProperty<Integer>(123456789);
+ tf.setPropertyDataSource(ds);
+ assertEquals((Integer) 123456789, ds.getValue());
+ assertEquals("123,456,789", tf.getValue());
+ tf.setLocale(new Locale("fi", "FI"));
+ assertEquals((Integer) 123456789, ds.getValue());
+ assertEquals("123" + FORMATTED_SPACE + "456" + FORMATTED_SPACE + "789",
+ tf.getValue());
+
+ }
+
+ public void testModifiedBufferedFieldConversion() {
+ VaadinSession.setCurrent(new AlwaysLockedVaadinSession(null));
+ TextField tf = new TextField("salary");
+ tf.setBuffered(true);
+ tf.setLocale(new Locale("en", "US"));
+ ObjectProperty<Integer> ds = new ObjectProperty<Integer>(123456789);
+ tf.setPropertyDataSource(ds);
+ assertEquals((Integer) 123456789, ds.getValue());
+ assertEquals("123,456,789", tf.getValue());
+ tf.setValue("123,123");
+ assertEquals((Integer) 123456789, ds.getValue());
+ assertEquals("123,123", tf.getValue());
+
+ tf.setLocale(new Locale("fi", "FI"));
+ assertEquals((Integer) 123456789, ds.getValue());
+ // Value should not be updated when field is buffered
+ assertEquals("123,123", tf.getValue());
+ }
+
+ public void testStringIdentityConversion() {
+ TextField tf = new TextField();
+ tf.setConverter(new Converter<String, String>() {
+
+ @Override
+ public String convertToModel(String value,
+ Class<? extends String> targetType, Locale locale) {
+ return value;
+ }
+
+ @Override
+ public String convertToPresentation(String value,
+ Class<? extends String> targetType, 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 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 testChangeReadOnlyFieldLocale() {
+ VaadinSession.setCurrent(new AlwaysLockedVaadinSession(null));
+
+ TextField tf = new TextField("salary");
+ tf.setLocale(new Locale("en", "US"));
+ ObjectProperty<Integer> ds = new ObjectProperty<Integer>(123456789);
+ ds.setReadOnly(true);
+ tf.setPropertyDataSource(ds);
+ assertEquals((Integer) 123456789, ds.getValue());
+ assertEquals("123,456,789", tf.getValue());
+ tf.setLocale(new Locale("fi", "FI"));
+ assertEquals((Integer) 123456789, ds.getValue());
+ assertEquals("123" + FORMATTED_SPACE + "456" + FORMATTED_SPACE + "789",
+ tf.getValue());
+ }
+
+ public void testBooleanNullConversion() {
+ CheckBox cb = new CheckBox();
+ cb.setConverter(new Converter<Boolean, Boolean>() {
+
+ @Override
+ public Boolean convertToModel(Boolean value,
+ Class<? extends Boolean> targetType, 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,
+ Class<? extends Boolean> targetType, 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(), Boolean.class, 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());
+
+ }
+
+ // Now specific to Integer because StringToNumberConverter has been removed
+ public static class NumberBean {
+ private Integer number;
+
+ public Integer getNumber() {
+ return number;
+ }
+
+ public void setNumber(Integer number) {
+ this.number = number;
+ }
+
+ }
+
+ public void testNumberDoubleConverterChange() {
+ final VaadinSession a = new AlwaysLockedVaadinSession(null);
+ VaadinSession.setCurrent(a);
+ TextField tf = new TextField() {
+ @Override
+ public VaadinSession getSession() {
+ 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(
+ "StringToInteger 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());
+
+ }
+
+ @Test
+ public void testNullConverter() {
+ TextField tf = new TextField("foo");
+ tf.setConverter(new StringToIntegerConverter());
+ tf.setPropertyDataSource(new ObjectProperty<Integer>(12));
+ tf.setConverter((Converter) null);
+ try {
+ Object v = tf.getConvertedValue();
+ System.out.println(v);
+ Assert.fail("Trying to convert String -> Integer should fail when there is no converter");
+ } catch (ConversionException e) {
+ // ok, should happen when there is no converter but conversion is
+ // needed
+ }
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbstractFieldDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbstractFieldDeclarativeTest.java
new file mode 100644
index 0000000000..96ed8b6f1e
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbstractFieldDeclarativeTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2000-2014 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.abstractfield;
+
+import org.junit.Test;
+
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.AbstractField;
+import com.vaadin.ui.TextField;
+
+/**
+ * Tests declarative support for implementations of {@link AbstractField}.
+ *
+ * @since 7.4
+ * @author Vaadin Ltd
+ */
+public class AbstractFieldDeclarativeTest extends
+ DeclarativeTestBase<AbstractField<?>> {
+
+ @Test
+ public void testPlainText() {
+ String design = "<vaadin-text-field buffered validation-visible='false' invalid-committed"
+ + " invalid-allowed='false' required required-error='This is a required field'"
+ + " conversion-error='Input {0} cannot be parsed' tabindex=3 readonly/>";
+ AbstractField tf = new TextField();
+ tf.setBuffered(true);
+ tf.setBuffered(true);
+ tf.setValidationVisible(false);
+ tf.setInvalidCommitted(true);
+ tf.setInvalidAllowed(false);
+ tf.setRequired(true);
+ tf.setRequiredError("This is a required field");
+ tf.setConversionError("Input {0} cannot be parsed");
+ tf.setTabIndex(3);
+ tf.setReadOnly(true);
+ testRead(design, tf);
+ testWrite(design, tf);
+
+ // Test with readonly=false
+ design = design.replace("readonly", "");
+ tf.setReadOnly(false);
+ testRead(design, tf);
+ testWrite(design, tf);
+ }
+
+ @Test
+ public void testModelReadOnly() {
+ // Test that read only value coming from property data source is not
+ // written to design.
+ String design = "<vaadin-text-field value=test></vaadin-text-field>";
+ AbstractField component = new TextField();
+ ObjectProperty<String> property = new ObjectProperty<String>("test");
+ property.setReadOnly(true);
+ component.setPropertyDataSource(property);
+ testWrite(design, component);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbstractFieldListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbstractFieldListenersTest.java
new file mode 100644
index 0000000000..def3ceb643
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbstractFieldListenersTest.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.AbstractListenerMethodsTestBase;
+import com.vaadin.ui.CheckBox;
+
+public class AbstractFieldListenersTest extends AbstractListenerMethodsTestBase {
+ 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/src/test/java/com/vaadin/tests/server/component/abstractfield/DefaultConverterFactoryTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractfield/DefaultConverterFactoryTest.java
new file mode 100644
index 0000000000..68e198c37a
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractfield/DefaultConverterFactoryTest.java
@@ -0,0 +1,133 @@
+package com.vaadin.tests.server.component.abstractfield;
+
+import java.math.BigDecimal;
+import java.util.Locale;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.util.MethodProperty;
+import com.vaadin.server.VaadinSession;
+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.tests.util.AlwaysLockedVaadinSession;
+import com.vaadin.ui.TextField;
+
+public class DefaultConverterFactoryTest extends TestCase {
+
+ public static class FloatBean {
+ float f1;
+ Float f2;
+
+ public FloatBean(float f1, Float f2) {
+ this.f1 = f1;
+ this.f2 = f2;
+ }
+
+ public float getF1() {
+ return f1;
+ }
+
+ public void setF1(float f1) {
+ this.f1 = f1;
+ }
+
+ public Float getF2() {
+ return f2;
+ }
+
+ public void setF2(Float f2) {
+ this.f2 = f2;
+ }
+
+ }
+
+ public static class LongBean {
+ long l1;
+ Long l2;
+
+ public LongBean(long l1, Long l2) {
+ this.l1 = l1;
+ this.l2 = l2;
+ }
+
+ public long getL1() {
+ return l1;
+ }
+
+ public void setL1(long l1) {
+ this.l1 = l1;
+ }
+
+ public Long getL2() {
+ return l2;
+ }
+
+ public void setL2(Long l2) {
+ this.l2 = l2;
+ }
+
+ }
+
+ 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 testFloatConversion() {
+ VaadinSession sess = new AlwaysLockedVaadinSession(null);
+ VaadinSession.setCurrent(sess);
+
+ TextField tf = new TextField();
+ tf.setLocale(new Locale("en", "US"));
+ tf.setPropertyDataSource(new MethodProperty<Integer>(new FloatBean(12f,
+ 23f), "f2"));
+ assertEquals("23", tf.getValue());
+ tf.setValue("24");
+ assertEquals("24", tf.getValue());
+ assertEquals(24f, tf.getConvertedValue());
+ assertEquals(24f, tf.getPropertyDataSource().getValue());
+ }
+
+ public void testLongConversion() {
+ VaadinSession sess = new AlwaysLockedVaadinSession(null);
+ VaadinSession.setCurrent(sess);
+
+ TextField tf = new TextField();
+ tf.setLocale(new Locale("en", "US"));
+ tf.setPropertyDataSource(new MethodProperty<Integer>(new LongBean(12,
+ 1982739187238L), "l2"));
+ assertEquals("1,982,739,187,238", tf.getValue());
+ tf.setValue("1982739187239");
+ assertEquals("1,982,739,187,239", tf.getValue());
+ assertEquals(1982739187239L, tf.getConvertedValue());
+ assertEquals(1982739187239L, tf.getPropertyDataSource().getValue());
+ }
+
+ public void testDefaultNumberConversion() {
+ VaadinSession app = new AlwaysLockedVaadinSession(null);
+ VaadinSession.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/src/test/java/com/vaadin/tests/server/component/abstractfield/RemoveListenersOnDetachTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractfield/RemoveListenersOnDetachTest.java
new file mode 100644
index 0000000000..f547f2c66b
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractfield/RemoveListenersOnDetachTest.java
@@ -0,0 +1,106 @@
+package com.vaadin.tests.server.component.abstractfield;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import com.vaadin.data.Property;
+import com.vaadin.data.util.AbstractProperty;
+import com.vaadin.data.util.converter.Converter.ConversionException;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.tests.util.AlwaysLockedVaadinSession;
+import com.vaadin.ui.AbstractField;
+import com.vaadin.ui.UI;
+
+public class RemoveListenersOnDetachTest {
+
+ int numValueChanges = 0;
+ int numReadOnlyChanges = 0;
+
+ AbstractField field = new AbstractField() {
+ final private VaadinSession application = new AlwaysLockedVaadinSession(
+ null);
+ private UI uI = new UI() {
+
+ @Override
+ protected void init(VaadinRequest request) {
+
+ }
+
+ @Override
+ public VaadinSession getSession() {
+ return 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 VaadinSession getSession() {
+ return application;
+ }
+ };
+
+ Property<String> property = new AbstractProperty<String>() {
+ @Override
+ public String getValue() {
+ return null;
+ }
+
+ @Override
+ public void setValue(String newValue) throws ReadOnlyException,
+ ConversionException {
+ fireValueChange();
+ }
+
+ @Override
+ public Class<String> 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/src/test/java/com/vaadin/tests/server/component/abstractorderedlayout/AbstractOrderedLayoutDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractorderedlayout/AbstractOrderedLayoutDeclarativeTest.java
new file mode 100644
index 0000000000..87f810d562
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractorderedlayout/AbstractOrderedLayoutDeclarativeTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2000-2014 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.abstractorderedlayout;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.vaadin.shared.ui.label.ContentMode;
+import com.vaadin.tests.server.component.DeclarativeMarginTestBase;
+import com.vaadin.ui.AbstractOrderedLayout;
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.VerticalLayout;
+
+/**
+ * Tests declarative support for AbstractOrderedLayout.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class AbstractOrderedLayoutDeclarativeTest extends
+ DeclarativeMarginTestBase<AbstractOrderedLayout> {
+
+ private List<String> defaultAlignments = Arrays.asList(new String[] {
+ ":top", ":left" });
+
+ @Test
+ public void testMargins() {
+ testMargins("vaadin-vertical-layout");
+ }
+
+ @Test
+ public void testExpandRatio() {
+ String design = getDesign(1);
+ AbstractOrderedLayout layout = getLayout(1, null);
+ testRead(design, layout);
+ testWrite(design, layout);
+ design = getDesign(0.25f);
+ layout = getLayout(0.25f, null);
+ testRead(design, layout);
+ testWrite(design, layout);
+ }
+
+ @Test
+ public void testAlignment() {
+ String design = getDesign(0, ":top", ":left");
+ AbstractOrderedLayout layout = getLayout(0, Alignment.TOP_LEFT);
+ testRead(design, layout);
+ testWrite(design, layout);
+ design = getDesign(0, ":middle", ":center");
+ layout = getLayout(0, Alignment.MIDDLE_CENTER);
+ testRead(design, layout);
+ testWrite(design, layout);
+ design = getDesign(0, ":bottom", ":right");
+ layout = getLayout(0, Alignment.BOTTOM_RIGHT);
+ testRead(design, layout);
+ testWrite(design, layout);
+ }
+
+ private String getDesign(float expandRatio, String... alignments) {
+ String result = "<vaadin-vertical-layout caption=test-layout>";
+ result += "<vaadin-label caption=test-label ";
+ String ratioString = expandRatio == 1.0f ? null : String
+ .valueOf(expandRatio);
+ if (expandRatio != 0) {
+ if (ratioString == null) {
+ result += ":expand";
+ } else {
+ result += ":expand=" + ratioString;
+ }
+ }
+ for (String alignment : alignments) {
+ if (!defaultAlignments.contains(alignment)) {
+ result += " " + alignment;
+ }
+ }
+ result += "></vaadin-label><vaadin-button ";
+ if (expandRatio != 0) {
+ if (ratioString == null) {
+ result += ":expand";
+ } else {
+ result += ":expand=" + ratioString;
+ }
+ }
+ for (String alignment : alignments) {
+ if (!defaultAlignments.contains(alignment)) {
+ result += " " + alignment;
+ }
+ }
+ result += "></vaadin-button></vaadin-vertical-layout>";
+ return result;
+ }
+
+ private AbstractOrderedLayout getLayout(float expandRatio,
+ Alignment alignment) {
+ VerticalLayout layout = new VerticalLayout();
+ layout.setCaption("test-layout");
+ Label l = new Label();
+ l.setCaption("test-label");
+ l.setContentMode(ContentMode.HTML);
+ layout.addComponent(l);
+ layout.setExpandRatio(l, expandRatio);
+ Button b = new Button();
+ b.setCaptionAsHtml(true);
+ layout.addComponent(b);
+ layout.setExpandRatio(b, expandRatio);
+ if (alignment != null) {
+ layout.setComponentAlignment(l, alignment);
+ layout.setComponentAlignment(b, alignment);
+ }
+ return layout;
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/abstractorderedlayout/AbstractOrderedLayoutListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractorderedlayout/AbstractOrderedLayoutListenersTest.java
new file mode 100644
index 0000000000..e7393e5f7d
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractorderedlayout/AbstractOrderedLayoutListenersTest.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.AbstractListenerMethodsTestBase;
+import com.vaadin.ui.VerticalLayout;
+
+public class AbstractOrderedLayoutListenersTest extends
+ AbstractListenerMethodsTestBase {
+ public void testLayoutClickListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(VerticalLayout.class, LayoutClickEvent.class,
+ LayoutClickListener.class);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/abstractorderedlayout/AddComponentsTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractorderedlayout/AddComponentsTest.java
new file mode 100644
index 0000000000..36e54a2826
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractorderedlayout/AddComponentsTest.java
@@ -0,0 +1,154 @@
+package com.vaadin.tests.server.component.abstractorderedlayout;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.junit.Test;
+
+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 });
+ }
+
+ @Test
+ public void testConstructorsWithComponents() {
+ AbstractOrderedLayout layout1 = new HorizontalLayout(children);
+ assertOrder(layout1, new int[] { 0, 1, 2, 3 });
+ shuffleChildComponents(layout1);
+
+ AbstractOrderedLayout layout2 = new VerticalLayout(children);
+ assertOrder(layout2, new int[] { 0, 1, 2, 3 });
+ shuffleChildComponents(layout2);
+ }
+
+ @Test
+ public void testAddComponents() {
+ HorizontalLayout layout1 = new HorizontalLayout();
+ layout1.addComponents(children);
+ assertOrder(layout1, new int[] { 0, 1, 2, 3 });
+
+ Label extra = new Label("Extra");
+ layout1.addComponents(extra);
+ assertSame(extra, layout1.getComponent(4));
+
+ layout1.removeAllComponents();
+ layout1.addComponents(children[3], children[2], children[1],
+ children[0]);
+ assertOrder(layout1, new int[] { 3, 2, 1, 0 });
+
+ VerticalLayout layout2 = new VerticalLayout(children);
+ layout2.addComponents(children);
+ assertOrder(layout2, new int[] { 0, 1, 2, 3 });
+
+ layout2.addComponents(extra);
+ assertSame(extra, layout2.getComponent(4));
+
+ layout2.removeAllComponents();
+ layout2.addComponents(children[3], children[2], children[1],
+ children[0]);
+ assertOrder(layout2, new int[] { 3, 2, 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/src/test/java/com/vaadin/tests/server/component/abstractorderedlayout/LayoutSettingsOnReplaceTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractorderedlayout/LayoutSettingsOnReplaceTest.java
new file mode 100644
index 0000000000..9d1972c232
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractorderedlayout/LayoutSettingsOnReplaceTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2000-2014 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.abstractorderedlayout;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.ui.AbstractComponent;
+import com.vaadin.ui.AbstractOrderedLayout;
+import com.vaadin.ui.Alignment;
+
+/**
+ * Tests for abstract layout settings which should be preserved on replace
+ * component
+ *
+ * @since 7.2
+ * @author Vaadin Ltd
+ */
+public class LayoutSettingsOnReplaceTest {
+
+ @Test
+ public void testExpandRatio() {
+ AbstractOrderedLayout layout = new AbstractOrderedLayout() {
+ };
+
+ AbstractComponent first = new AbstractComponent() {
+ };
+ AbstractComponent second = new AbstractComponent() {
+ };
+
+ layout.addComponent(first);
+ layout.addComponent(second);
+
+ int ratio = 2;
+ layout.setExpandRatio(first, ratio);
+ layout.setExpandRatio(second, 1);
+
+ AbstractComponent replace = new AbstractComponent() {
+ };
+ layout.replaceComponent(first, replace);
+
+ Assert.assertEquals("Expand ratio for replaced component is not "
+ + "the same as for previous one", ratio,
+ layout.getExpandRatio(replace), 0.0001);
+ }
+
+ @Test
+ public void testAlignment() {
+ AbstractOrderedLayout layout = new AbstractOrderedLayout() {
+ };
+
+ AbstractComponent first = new AbstractComponent() {
+ };
+ AbstractComponent second = new AbstractComponent() {
+ };
+
+ layout.addComponent(first);
+ layout.addComponent(second);
+
+ Alignment alignment = Alignment.BOTTOM_RIGHT;
+ layout.setComponentAlignment(first, alignment);
+ layout.setComponentAlignment(second, Alignment.MIDDLE_CENTER);
+
+ AbstractComponent replace = new AbstractComponent() {
+ };
+ layout.replaceComponent(first, replace);
+
+ Assert.assertEquals("Alignment for replaced component is not "
+ + "the same as for previous one", alignment,
+ layout.getComponentAlignment(replace));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/abstractselect/AbstractSelectDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractselect/AbstractSelectDeclarativeTest.java
new file mode 100644
index 0000000000..6800320753
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractselect/AbstractSelectDeclarativeTest.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright 2000-2014 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.abstractselect;
+
+import org.jsoup.nodes.Attributes;
+import org.jsoup.nodes.Element;
+import org.jsoup.parser.Tag;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.Container;
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.server.ExternalResource;
+import com.vaadin.server.Resource;
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.tests.design.DeclarativeTestBaseBase;
+import com.vaadin.ui.AbstractSelect;
+import com.vaadin.ui.AbstractSelect.ItemCaptionMode;
+import com.vaadin.ui.ComboBox;
+import com.vaadin.ui.ListSelect;
+import com.vaadin.ui.declarative.DesignContext;
+import com.vaadin.ui.declarative.DesignException;
+
+/**
+ * Test cases for reading the properties of selection components.
+ *
+ * @author Vaadin Ltd
+ */
+public class AbstractSelectDeclarativeTest extends
+ DeclarativeTestBase<AbstractSelect> {
+
+ public String getDesignSingleSelectNewItemsAllowed() {
+ return "<vaadin-combo-box new-items-allowed item-caption-mode='icon_only'"
+ + " null-selection-item-id='nullIid'/>";
+
+ }
+
+ public AbstractSelect getExpectedSingleSelectNewItemsAllowed() {
+ ComboBox c = new ComboBox();
+ c.setNewItemsAllowed(true);
+ c.setItemCaptionMode(ItemCaptionMode.ICON_ONLY);
+ c.setNullSelectionAllowed(true);// Default
+ c.setNullSelectionItemId("nullIid");
+ return c;
+ }
+
+ public String getDesignMultiSelect() {
+ return "<vaadin-list-select multi-select null-selection-allowed='false' new-items-allowed item-caption-mode='property' />";
+ }
+
+ public AbstractSelect getExpectedMultiSelect() {
+ ListSelect c = new ListSelect();
+ c.setNewItemsAllowed(true);
+ c.setNullSelectionAllowed(false);
+ c.setItemCaptionMode(ItemCaptionMode.PROPERTY);
+ c.setMultiSelect(true);
+ return c;
+ }
+
+ @Test
+ public void testReadSingleSelectNewItemsAllowed() {
+ testRead(getDesignSingleSelectNewItemsAllowed(),
+ getExpectedSingleSelectNewItemsAllowed());
+ }
+
+ @Test
+ public void testWriteSingleSelectNewItemsAllowed() {
+ testWrite(getDesignSingleSelectNewItemsAllowed(),
+ getExpectedSingleSelectNewItemsAllowed());
+ }
+
+ @Test
+ public void testReadMultiSelect() {
+ testRead(getDesignMultiSelect(), getExpectedMultiSelect());
+ }
+
+ @Test
+ public void testWriteMultiSelect() {
+ testWrite(getDesignMultiSelect(), getExpectedMultiSelect());
+ }
+
+ @Test
+ public void testReadInlineData() {
+ testRead(getDesignForInlineData(), getExpectedComponentForInlineData());
+ }
+
+ @Test(expected = DesignException.class)
+ public void testReadMultipleValuesForSingleSelect() {
+ testRead("<vaadin-list-select>" + "<option selected>1</option>"
+ + "<option selected>2</option>" + "</vaadin-list-select>", null);
+ }
+
+ @Test
+ public void testReadMultipleValuesForMultiSelect() {
+ ListSelect ls = new ListSelect();
+ ls.setMultiSelect(true);
+ ls.addItem("1");
+ ls.addItem("2");
+ ls.select("1");
+ ls.select("2");
+ testRead("<vaadin-list-select multi-select>"
+ + "<option selected>1</option>" + "<option selected>2</option>"
+ + "</vaadin-list-select>", ls);
+ }
+
+ @Test
+ public void testReadSingleValueForMultiSelect() {
+ ListSelect ls = new ListSelect();
+ ls.setMultiSelect(true);
+ ls.addItem("1");
+ ls.addItem("2");
+ ls.select("1");
+ testRead("<vaadin-list-select multi-select>"
+ + "<option selected>1</option>" + "<option>2</option>"
+ + "</vaadin-list-select>", ls);
+ }
+
+ @Test
+ public void testReadSingleValueForSingleSelect() {
+ ListSelect ls = new ListSelect();
+ ls.setMultiSelect(false);
+ ls.addItem("1");
+ ls.addItem("2");
+ ls.select("1");
+ testRead("<vaadin-list-select>" + "<option selected>1</option>"
+ + "<option>2</option>" + "</vaadin-list-select>", ls);
+ }
+
+ @Test
+ public void testWriteInlineDataIgnored() {
+ // No data is written by default
+ testWrite(stripOptionTags(getDesignForInlineData()),
+ getExpectedComponentForInlineData());
+ }
+
+ @Test
+ public void testWriteInlineData() {
+ testWrite(getDesignForInlineData(),
+ getExpectedComponentForInlineData(), true);
+ }
+
+ private String getDesignForInlineData() {
+ return "<vaadin-list-select>\n"
+ + " <option icon='http://some.url/icon.png'>Value 1</option>\n" //
+ + " <option selected>Value 2</option>\n"//
+ + "</vaadin-list-select>";
+ }
+
+ private AbstractSelect getExpectedComponentForInlineData() {
+ AbstractSelect as = new ListSelect();
+ as.addItem("Value 1");
+ as.setItemIcon("Value 1", new ExternalResource(
+ "http://some.url/icon.png"));
+ as.addItem("Value 2");
+ as.setValue("Value 2");
+ return as;
+ }
+
+ @Test
+ public void testReadAttributesSingleSelect() {
+ Element design = createDesignWithAttributesSingleSelect();
+ ComboBox cb = new ComboBox();
+ IndexedContainer container = new IndexedContainer();
+ container.addContainerProperty("icon", Resource.class, null);
+ container.addContainerProperty("name", String.class, null);
+ cb.setContainerDataSource(container);
+ cb.readDesign(design, new DesignContext());
+ Assert.assertTrue("Adding new items should be allowed.",
+ cb.isNewItemsAllowed());
+ assertEquals("Wrong item caption mode.",
+ AbstractSelect.ItemCaptionMode.PROPERTY,
+ cb.getItemCaptionMode());
+ assertEquals("Wrong item caption property id.", "name",
+ cb.getItemCaptionPropertyId());
+ assertEquals("Wrong item icon property id.", "icon",
+ cb.getItemIconPropertyId());
+ Assert.assertTrue("Null selection should be allowed.",
+ cb.isNullSelectionAllowed());
+ assertEquals("Wrong null selection item id.", "No items selected",
+ cb.getNullSelectionItemId());
+ }
+
+ @Test
+ public void testReadAttributesMultiSelect() {
+ Element design = createDesignWithAttributesMultiSelect();
+ ListSelect ls = new ListSelect();
+ ls.readDesign(design, new DesignContext());
+ Assert.assertTrue("Multi select should be allowed.", ls.isMultiSelect());
+ assertEquals("Wrong caption mode.",
+ AbstractSelect.ItemCaptionMode.EXPLICIT,
+ ls.getItemCaptionMode());
+ Assert.assertFalse("Null selection should not be allowed.",
+ ls.isNullSelectionAllowed());
+ }
+
+ private Element createDesignWithAttributesSingleSelect() {
+ Attributes attributes = new Attributes();
+ attributes.put("new-items-allowed", true);
+ attributes.put("multi-select", "false");
+ attributes.put("item-caption-mode", "property");
+ attributes.put("item-caption-property-id", "name");
+ attributes.put("item-icon-property-id", "icon");
+ attributes.put("null-selection-allowed", true);
+ attributes.put("null-selection-item-id", "No items selected");
+ return new Element(Tag.valueOf("vaadin-combo-box"), "", attributes);
+ }
+
+ private Element createDesignWithAttributesMultiSelect() {
+ Attributes attributes = new Attributes();
+ attributes.put("multi-select", true);
+ attributes.put("item-caption-mode", "EXPLICIT");
+ attributes.put("null-selection-allowed", "false");
+ return new Element(Tag.valueOf("vaadin-list-select"), "", attributes);
+ }
+
+ @Test
+ public void testWriteAttributesSingleSelect() {
+ ComboBox cb = createSingleSelectWithOnlyAttributes();
+ Element e = new Element(Tag.valueOf("vaadin-combo-box"), "");
+ cb.writeDesign(e, new DesignContext());
+ assertEquals("Wrong caption for the combo box.", "A combo box",
+ e.attr("caption"));
+ Assert.assertTrue("Adding new items should be allowed.",
+ "".equals(e.attr("new-items-allowed")));
+ assertEquals("Wrong item caption mode.", "icon_only",
+ e.attr("item-caption-mode"));
+ assertEquals("Wrong item icon property id.", "icon",
+ e.attr("item-icon-property-id"));
+ Assert.assertTrue(
+ "Null selection should be allowed.",
+ "".equals(e.attr("null-selection-allowed"))
+ || "true".equals(e.attr("null-selection-allowed")));
+ assertEquals("Wrong null selection item id.", "No item selected",
+ e.attr("null-selection-item-id"));
+ }
+
+ @Test
+ public void testWriteMultiListSelect() {
+ ListSelect ls = createMultiSelect();
+ Element e = new Element(Tag.valueOf("vaadin-list-select"), "");
+ ls.writeDesign(e, new DesignContext());
+ assertEquals("Null selection should not be allowed.", "false",
+ e.attr("null-selection-allowed"));
+ Assert.assertTrue(
+ "Multi select should be allowed.",
+ "".equals(e.attr("multi-select"))
+ || "true".equals(e.attr("multi-select")));
+ }
+
+ @Test
+ public void testHtmlEntities() {
+ String design = "<vaadin-combo-box>"
+ + " <option item-id=\"one\">&gt; One</option>"
+ + " <option>&gt; Two</option>" + "</vaadin-combo-box>";
+ AbstractSelect read = read(design);
+
+ Assert.assertEquals("> One", read.getItemCaption("one"));
+
+ AbstractSelect underTest = new ComboBox();
+ underTest.addItem("> One");
+
+ Element root = new Element(Tag.valueOf("vaadin-combo-box"), "");
+ DesignContext dc = new DesignContext();
+ dc.setShouldWriteDataDelegate(DeclarativeTestBaseBase.ALWAYS_WRITE_DATA);
+ underTest.writeDesign(root, dc);
+
+ Assert.assertEquals("&gt; One", root.getElementsByTag("option").first()
+ .html());
+ }
+
+ public ComboBox createSingleSelectWithOnlyAttributes() {
+ ComboBox cb = new ComboBox();
+ Container dataSource = new IndexedContainer();
+ dataSource.addContainerProperty("icon", Resource.class, null);
+ cb.setContainerDataSource(dataSource);
+ cb.setCaption("A combo box");
+ cb.setNewItemsAllowed(true);
+ cb.setItemCaptionMode(ItemCaptionMode.ICON_ONLY);
+ cb.setItemIconPropertyId("icon");
+ cb.setNullSelectionAllowed(true);
+ cb.setNullSelectionItemId("No item selected");
+ return cb;
+ }
+
+ public ListSelect createMultiSelect() {
+ ListSelect ls = new ListSelect();
+ ls.setNullSelectionAllowed(false);
+ ls.setMultiSelect(true);
+ return ls;
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/abstractselect/AbstractSelectListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractselect/AbstractSelectListenersTest.java
new file mode 100644
index 0000000000..ee806cb5f7
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractselect/AbstractSelectListenersTest.java
@@ -0,0 +1,21 @@
+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.AbstractListenerMethodsTestBase;
+import com.vaadin.ui.ComboBox;
+
+public class AbstractSelectListenersTest extends
+ AbstractListenerMethodsTestBase {
+ 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/src/test/java/com/vaadin/tests/server/component/abstractselect/AbstractSelectStateTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractselect/AbstractSelectStateTest.java
new file mode 100644
index 0000000000..52b215f4c8
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractselect/AbstractSelectStateTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2014 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.abstractselect;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.shared.ui.select.AbstractSelectState;
+import com.vaadin.ui.AbstractSelect;
+
+/**
+ * Tests for AbstractSelect state
+ *
+ */
+public class AbstractSelectStateTest {
+
+ @Test
+ public void getState_selectHasCustomState() {
+ TestSelect select = new TestSelect();
+ AbstractSelectState state = select.getState();
+ Assert.assertEquals("Unexpected state class",
+ AbstractSelectState.class, state.getClass());
+ }
+
+ @Test
+ public void getPrimaryStyleName_selectHasCustomPrimaryStyleName() {
+ TestSelect combobox = new TestSelect();
+ AbstractSelectState state = new AbstractSelectState();
+ Assert.assertEquals("Unexpected primary style name",
+ state.primaryStyleName, combobox.getPrimaryStyleName());
+ }
+
+ @Test
+ public void selectStateHasCustomPrimaryStyleName() {
+ AbstractSelectState state = new AbstractSelectState();
+ Assert.assertEquals("Unexpected primary style name", "v-select",
+ state.primaryStyleName);
+ }
+
+ private static class TestSelect extends AbstractSelect {
+
+ @Override
+ public AbstractSelectState getState() {
+ return super.getState();
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/abstractselect/OptionGroupDeclarativeTests.java b/server/src/test/java/com/vaadin/tests/server/component/abstractselect/OptionGroupDeclarativeTests.java
new file mode 100644
index 0000000000..509e46c278
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractselect/OptionGroupDeclarativeTests.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2000-2014 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.abstractselect;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.server.ThemeResource;
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.OptionGroup;
+
+public class OptionGroupDeclarativeTests extends
+ DeclarativeTestBase<OptionGroup> {
+
+ private OptionGroup og;
+
+ @Before
+ public void init() {
+ og = new OptionGroup();
+ }
+
+ @Test
+ public void testBasicSyntax() {
+
+ String expected = "<vaadin-option-group />";
+ testReadWrite(expected);
+
+ }
+
+ @Test
+ public void testOptionSyntax() {
+
+ og.addItems("foo", "bar", "baz", "bang");
+
+ //@formatter:off
+ String expected =
+ "<vaadin-option-group>"
+ + "<option>foo</option>"
+ + "<option>bar</option>"
+ + "<option>baz</option>"
+ + "<option>bang</option>"
+ + "</vaadin-option-group>";
+ //@formatter:on
+
+ testReadWrite(expected);
+
+ }
+
+ @Test
+ public void testDisabledOptionSyntax() {
+
+ og.addItems("foo", "bar", "baz", "bang");
+ og.setItemEnabled("baz", false);
+
+ //@formatter:off
+ String expected =
+ "<vaadin-option-group>"
+ + "<option>foo</option>"
+ + "<option>bar</option>"
+ + "<option disabled>baz</option>"
+ + "<option>bang</option>"
+ + "</vaadin-option-group>";
+ //@formatter:on
+
+ testReadWrite(expected);
+
+ }
+
+ @Test
+ public void testIconSyntax() {
+
+ og.addItems("foo", "bar", "baz", "bang");
+ og.setItemIcon("bar", new ThemeResource("foobar.png"));
+
+ //@formatter:off
+ String expected =
+ "<vaadin-option-group>"
+ + "<option>foo</option>"
+ + "<option icon='theme://foobar.png'>bar</option>"
+ + "<option>baz</option>"
+ + "<option>bang</option>"
+ + "</vaadin-option-group>";
+ //@formatter:on
+
+ testReadWrite(expected);
+
+ }
+
+ @Test
+ public void testHTMLCaption() {
+
+ og.addItems("foo", "bar", "baz", "bang");
+
+ og.setHtmlContentAllowed(true);
+
+ og.setItemCaption("foo", "<b>True</b>");
+ og.setItemCaption("bar", "<font color='red'>False</font>");
+
+ //@formatter:off
+ String expected =
+ "<vaadin-option-group html-content-allowed>"
+ + "<option item-id=\"foo\"><b>True</b></option>"
+ + "<option item-id=\"bar\"><font color='red'>False</font></option>"
+ + "<option>baz</option>"
+ + "<option>bang</option>"
+ + "</vaadin-option-group>";
+ //@formatter:on
+
+ testReadWrite(expected);
+ }
+
+ @Test
+ public void testPlaintextCaption() {
+
+ og.addItems("foo", "bar", "baz", "bang");
+
+ og.setItemCaption("foo", "<b>True</b>");
+ og.setItemCaption("bar", "<font color=\"red\">False</font>");
+
+ //@formatter:off
+ String expected =
+ "<vaadin-option-group>"
+ + "<option item-id=\"foo\">&lt;b&gt;True&lt;/b&gt;</option>"
+ + "<option item-id=\"bar\">&lt;font color=\"red\"&gt;False&lt;/font&gt;</option>"
+ + "<option>baz</option>"
+ + "<option>bang</option>"
+ + "</vaadin-option-group>";
+ //@formatter:on
+
+ testReadWrite(expected);
+ }
+
+ private void testReadWrite(String design) {
+ testWrite(design, og, true);
+ testRead(design, og);
+ }
+
+ @Override
+ public OptionGroup testRead(String design, OptionGroup expected) {
+
+ OptionGroup read = super.testRead(design, expected);
+ testWrite(design, read, true);
+
+ return read;
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/abstractselect/OptionGroupTests.java b/server/src/test/java/com/vaadin/tests/server/component/abstractselect/OptionGroupTests.java
new file mode 100644
index 0000000000..c4a3d73652
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractselect/OptionGroupTests.java
@@ -0,0 +1,32 @@
+package com.vaadin.tests.server.component.abstractselect;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collection;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.ui.OptionGroup;
+
+public class OptionGroupTests {
+
+ private OptionGroup optionGroup;
+
+ @Before
+ public void setup() {
+ optionGroup = new OptionGroup();
+ }
+
+ @Test
+ public void itemsAreAdded() {
+ optionGroup.addItems("foo", "bar");
+
+ Collection<?> itemIds = optionGroup.getItemIds();
+
+ assertEquals(2, itemIds.size());
+ assertTrue(itemIds.contains("foo"));
+ assertTrue(itemIds.contains("bar"));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/abstractsinglecomponentcontainer/RemoveFromParentLockingTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractsinglecomponentcontainer/RemoveFromParentLockingTest.java
new file mode 100644
index 0000000000..2334542676
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractsinglecomponentcontainer/RemoveFromParentLockingTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2000-2014 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.abstractsinglecomponentcontainer;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+
+public class RemoveFromParentLockingTest {
+
+ private static VerticalLayout createTestComponent() {
+ VaadinSession session = new VaadinSession(null) {
+ private final ReentrantLock lock = new ReentrantLock();
+
+ @Override
+ public Lock getLockInstance() {
+ return lock;
+ }
+ };
+
+ session.getLockInstance().lock();
+
+ UI ui = new UI() {
+ @Override
+ protected void init(VaadinRequest request) {
+ }
+ };
+ ui.setSession(session);
+
+ VerticalLayout layout = new VerticalLayout();
+ ui.setContent(layout);
+
+ session.getLockInstance().unlock();
+ return layout;
+ }
+
+ @Test
+ public void attachNoSessionLocked() {
+ VerticalLayout testComponent = createTestComponent();
+
+ VerticalLayout target = new VerticalLayout();
+
+ try {
+ target.addComponent(testComponent);
+ throw new AssertionError(
+ "Moving component when not holding its sessions's lock should throw");
+ } catch (IllegalStateException e) {
+ Assert.assertEquals(
+ "Cannot remove from parent when the session is not locked.",
+ e.getMessage());
+ }
+ }
+
+ @Test
+ public void attachSessionLocked() {
+ VerticalLayout testComponent = createTestComponent();
+
+ VerticalLayout target = new VerticalLayout();
+
+ testComponent.getUI().getSession().getLockInstance().lock();
+
+ target.addComponent(testComponent);
+ // OK if we get here without any exception
+ }
+
+ @Test
+ public void crossAttachOtherSessionLocked() {
+ VerticalLayout notLockedComponent = createTestComponent();
+
+ VerticalLayout lockedComponent = createTestComponent();
+
+ // Simulate the situation when attaching cross sessions
+ lockedComponent.getUI().getSession().getLockInstance().lock();
+ VaadinSession.setCurrent(lockedComponent.getUI().getSession());
+
+ try {
+ lockedComponent.addComponent(notLockedComponent);
+ throw new AssertionError(
+ "Moving component when not holding its sessions's lock should throw");
+ } catch (IllegalStateException e) {
+ Assert.assertEquals(
+ "Cannot remove from parent when the session is not locked."
+ + " Furthermore, there is another locked session, indicating that the component might be about to be moved from one session to another.",
+ e.getMessage());
+ } finally {
+ VaadinSession.setCurrent(null);
+ }
+ }
+
+ @Test
+ public void crossAttachThisSessionLocked() {
+ VerticalLayout notLockedComponent = createTestComponent();
+
+ VerticalLayout lockedComponent = createTestComponent();
+
+ // Simulate the situation when attaching cross sessions
+ lockedComponent.getUI().getSession().getLockInstance().lock();
+ VaadinSession.setCurrent(lockedComponent.getUI().getSession());
+
+ try {
+ notLockedComponent.addComponent(lockedComponent);
+ } catch (AssertionError e) {
+ // All is fine, don't care about the exact wording in this case
+ } finally {
+ VaadinSession.setCurrent(null);
+ }
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/abstractsinglecomponentcontainer/SetParentAsContentTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractsinglecomponentcontainer/SetParentAsContentTest.java
new file mode 100644
index 0000000000..b84794d58a
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractsinglecomponentcontainer/SetParentAsContentTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2000-2014 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.abstractsinglecomponentcontainer;
+
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+import com.vaadin.ui.AbstractSingleComponentContainer;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.HasComponents;
+
+/**
+ *
+ * Tests for avoiding set parent as child for
+ * {@link AbstractSingleComponentContainer#setContent(Component)}
+ *
+ * @author Vaadin Ltd
+ */
+public class SetParentAsContentTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testSetContent() {
+ AbstractSingleComponentContainer container = new AbstractSingleComponentContainer() {
+ };
+ HasComponents hasComponentsMock = EasyMock
+ .createMock(HasComponents.class);
+ container.setParent(hasComponentsMock);
+
+ container.setContent(hasComponentsMock);
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/abstractsplitpanel/AbstractSplitPanelDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractsplitpanel/AbstractSplitPanelDeclarativeTest.java
new file mode 100644
index 0000000000..02094cb611
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractsplitpanel/AbstractSplitPanelDeclarativeTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2000-2014 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.abstractsplitpanel;
+
+import org.junit.Test;
+
+import com.vaadin.server.Sizeable.Unit;
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.AbstractSplitPanel;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.HorizontalSplitPanel;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.VerticalSplitPanel;
+
+/**
+ * Tests declarative support for AbstractSplitPanel.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class AbstractSplitPanelDeclarativeTest extends
+ DeclarativeTestBase<AbstractSplitPanel> {
+
+ @Test
+ public void testWithBothChildren() {
+ String design = "<vaadin-horizontal-split-panel split-position=20.5% "
+ + "min-split-position=20% max-split-position=50px locked "
+ + "reversed> <vaadin-table /> <vaadin-vertical-layout />"
+ + "</vaadin-horizontal-split-panel>";
+ AbstractSplitPanel sp = new HorizontalSplitPanel();
+ sp.setSplitPosition(20.5f, Unit.PERCENTAGE, true);
+ sp.setMinSplitPosition(20, Unit.PERCENTAGE);
+ sp.setMaxSplitPosition(50, Unit.PIXELS);
+ sp.setLocked(true);
+ sp.addComponent(new Table());
+ sp.addComponent(new VerticalLayout());
+ testRead(design, sp);
+ testWrite(design, sp);
+ }
+
+ @Test
+ public void testWithFirstChild() {
+ String design = "<vaadin-vertical-split-panel><vaadin-table caption=\"First slot\"/>"
+ + "</vaadin-vertical-split-panel>";
+ AbstractSplitPanel sp = new VerticalSplitPanel();
+ Table t = new Table();
+ t.setCaption("First slot");
+ sp.addComponent(t);
+ testRead(design, sp);
+ testWrite(design, sp);
+ }
+
+ @Test
+ public void testWithSecondChild() {
+ String design = "<vaadin-horizontal-split-panel><vaadin-button :second>Second slot</vaadin-button>"
+ + "</vaadin-vertical-split-panel>";
+ AbstractSplitPanel sp = new HorizontalSplitPanel();
+ Button b = new Button("Second slot");
+ b.setCaptionAsHtml(true);
+ sp.setSecondComponent(b);
+ testRead(design, sp);
+ testWrite(design, sp);
+ }
+
+ @Test
+ public void testEmpty() {
+ String design = "<vaadin-horizontal-split-panel/>";
+ AbstractSplitPanel sp = new HorizontalSplitPanel();
+ testRead(design, sp);
+ testWrite(design, sp);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/abstractsplitpanel/AbstractSplitPanelListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractsplitpanel/AbstractSplitPanelListenersTest.java
new file mode 100644
index 0000000000..5dd2f406bc
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractsplitpanel/AbstractSplitPanelListenersTest.java
@@ -0,0 +1,14 @@
+package com.vaadin.tests.server.component.abstractsplitpanel;
+
+import com.vaadin.tests.server.component.AbstractListenerMethodsTestBase;
+import com.vaadin.ui.AbstractSplitPanel.SplitterClickEvent;
+import com.vaadin.ui.AbstractSplitPanel.SplitterClickListener;
+import com.vaadin.ui.HorizontalSplitPanel;
+
+public class AbstractSplitPanelListenersTest extends
+ AbstractListenerMethodsTestBase {
+ public void testSplitterClickListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(HorizontalSplitPanel.class,
+ SplitterClickEvent.class, SplitterClickListener.class);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/abstracttextfield/AbstractTextFieldDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstracttextfield/AbstractTextFieldDeclarativeTest.java
new file mode 100644
index 0000000000..275cca33a0
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstracttextfield/AbstractTextFieldDeclarativeTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2000-2014 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.abstracttextfield;
+
+import org.junit.Test;
+
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.AbstractTextField;
+import com.vaadin.ui.AbstractTextField.TextChangeEventMode;
+import com.vaadin.ui.TextField;
+
+/**
+ * Tests declarative support for AbstractTextField.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class AbstractTextFieldDeclarativeTest extends
+ DeclarativeTestBase<AbstractTextField> {
+
+ @Test
+ public void testAttributes() {
+ String design = "<vaadin-text-field null-representation=this-is-null "
+ + "null-setting-allowed maxlength=5 columns=3 "
+ + "input-prompt=input text-change-event-mode=eager "
+ + "text-change-timeout=100 />";
+ AbstractTextField tf = new TextField();
+ tf.setNullRepresentation("this-is-null");
+ tf.setNullSettingAllowed(true);
+ tf.setMaxLength(5);
+ tf.setColumns(3);
+ tf.setInputPrompt("input");
+ tf.setTextChangeEventMode(TextChangeEventMode.EAGER);
+ tf.setTextChangeTimeout(100);
+ testRead(design, tf);
+ testWrite(design, tf);
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/abstracttextfield/AbstractTextFieldListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstracttextfield/AbstractTextFieldListenersTest.java
new file mode 100644
index 0000000000..0896b5d649
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstracttextfield/AbstractTextFieldListenersTest.java
@@ -0,0 +1,28 @@
+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.AbstractListenerMethodsTestBase;
+import com.vaadin.ui.TextField;
+
+public class AbstractTextFieldListenersTest extends
+ AbstractListenerMethodsTestBase {
+ 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/src/test/java/com/vaadin/tests/server/component/audio/AudioDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/audio/AudioDeclarativeTest.java
new file mode 100644
index 0000000000..f9bfd2d316
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/audio/AudioDeclarativeTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2000-2014 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.audio;
+
+import java.io.File;
+
+import org.junit.Test;
+
+import com.vaadin.server.ExternalResource;
+import com.vaadin.server.FileResource;
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.Audio;
+
+/**
+ * Tests specs of declarative support for abstract media and its
+ * implementations.
+ *
+ * @since 7.4
+ * @author Vaadin Ltd
+ */
+public class AudioDeclarativeTest extends DeclarativeTestBase<Audio> {
+
+ @Test
+ public void testEmptyAudio() {
+ String design = "<vaadin-audio />";
+ Audio audio = new Audio();
+ testRead(design, audio);
+ testWrite(design, audio);
+ }
+
+ @Test
+ public void testAudioMultipleSources() {
+ String design = "<vaadin-audio muted show-controls='false'>"
+ + "some <b>text</b>" //
+ + "<source href='http://foo.pl' />"
+ + "<source href='https://bar.pl' />" //
+ + "<source href='ohai' />" //
+ + "</vaadin-audio>";
+ Audio audio = new Audio();
+ audio.setAltText("some <b>text</b>");
+ audio.setAutoplay(false);
+ audio.setMuted(true);
+ audio.setShowControls(false);
+ audio.setSources(new ExternalResource("http://foo.pl"),
+ new ExternalResource("https://bar.pl"), new FileResource(
+ new File("ohai")));
+ testRead(design, audio);
+ testWrite(design, audio);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/audio/AudioStateTest.java b/server/src/test/java/com/vaadin/tests/server/component/audio/AudioStateTest.java
new file mode 100644
index 0000000000..d18127791e
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/audio/AudioStateTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2000-2014 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.audio;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.shared.ui.audio.AudioState;
+import com.vaadin.ui.Audio;
+
+/**
+ * Tests for Audio state.
+ *
+ */
+public class AudioStateTest {
+ @Test
+ public void getState_audioHasCustomState() {
+ TestAudio audio = new TestAudio();
+ AudioState state = audio.getState();
+ Assert.assertEquals("Unexpected state class", AudioState.class,
+ state.getClass());
+ }
+
+ @Test
+ public void getPrimaryStyleName_audioHasCustomPrimaryStyleName() {
+ Audio audio = new Audio();
+ AudioState state = new AudioState();
+ Assert.assertEquals("Unexpected primary style name",
+ state.primaryStyleName, audio.getPrimaryStyleName());
+ }
+
+ @Test
+ public void audioStateHasCustomPrimaryStyleName() {
+ AudioState state = new AudioState();
+ Assert.assertEquals("Unexpected primary style name", "v-audio",
+ state.primaryStyleName);
+ }
+
+ private static class TestAudio extends Audio {
+
+ @Override
+ public AudioState getState() {
+ return super.getState();
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/audio/VideoDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/audio/VideoDeclarativeTest.java
new file mode 100644
index 0000000000..dafff32be2
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/audio/VideoDeclarativeTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2000-2014 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.audio;
+
+import java.io.File;
+
+import org.junit.Test;
+
+import com.vaadin.server.ExternalResource;
+import com.vaadin.server.FileResource;
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.Video;
+
+public class VideoDeclarativeTest extends DeclarativeTestBase<Video> {
+
+ @Test
+ public void testEmptyVideo() {
+ String design = "<vaadin-video />";
+ Video audio = new Video();
+ testRead(design, audio);
+ testWrite(design, audio);
+ }
+
+ @Test
+ public void testVideoMultipleSources() {
+ String design = "<vaadin-video muted show-controls='false'>"
+ + "some <b>text</b>" //
+ + "<source href='http://foo.pl' />"
+ + "<source href='https://bar.pl' />" //
+ + "<source href='ohai' />" //
+ + "<poster href='http://foo.pl/poster' />" //
+ + "</vaadin-video>";
+ Video video = new Video();
+ video.setAltText("some <b>text</b>");
+ video.setAutoplay(false);
+ video.setMuted(true);
+ video.setShowControls(false);
+ video.setSources(new ExternalResource("http://foo.pl"),
+ new ExternalResource("https://bar.pl"), new FileResource(
+ new File("ohai")));
+ video.setPoster(new ExternalResource("http://foo.pl/poster"));
+ testRead(design, video);
+ testWrite(design, video);
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/browserframe/BrowserFrameDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/browserframe/BrowserFrameDeclarativeTest.java
new file mode 100644
index 0000000000..b62499a28e
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/browserframe/BrowserFrameDeclarativeTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2014 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.browserframe;
+
+import org.junit.Test;
+
+import com.vaadin.server.ExternalResource;
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.BrowserFrame;
+
+/**
+ * Tests declarative support for implementations of {@link BrowserFrame}.
+ *
+ * @since 7.4
+ * @author Vaadin Ltd
+ */
+public class BrowserFrameDeclarativeTest extends
+ DeclarativeTestBase<BrowserFrame> {
+
+ protected String getDesign() {
+ return "<vaadin-browser-frame source='http://foo.bar/some.html' />";
+ }
+
+ protected BrowserFrame getExpectedResult() {
+ BrowserFrame i = new BrowserFrame();
+ i.setSource(new ExternalResource("http://foo.bar/some.html"));
+ return i;
+ };
+
+ @Test
+ public void read() {
+ testRead(getDesign(), getExpectedResult());
+ }
+
+ @Test
+ public void write() {
+ testWrite(getDesign(), getExpectedResult());
+ }
+
+ @Test
+ public void testEmpty() {
+ testRead("<vaadin-browser-frame/>", new BrowserFrame());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/button/ButtonClickTest.java b/server/src/test/java/com/vaadin/tests/server/component/button/ButtonClickTest.java
new file mode 100644
index 0000000000..6283ccf6af
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/button/ButtonClickTest.java
@@ -0,0 +1,84 @@
+package com.vaadin.tests.server.component.button;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.UI;
+
+/**
+ * Tests the public click() method.
+ */
+public class ButtonClickTest {
+ private boolean clicked = false;
+
+ @Test
+ public void clickDetachedButton() {
+ Button b = new Button();
+ final ObjectProperty<Integer> counter = new ObjectProperty<Integer>(0);
+ b.addClickListener(new ClickListener() {
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ counter.setValue(counter.getValue() + 1);
+ }
+ });
+
+ b.click();
+ Assert.assertEquals(Integer.valueOf(1), counter.getValue());
+ }
+
+ @Test
+ public void testClick() {
+ getButton().click();
+ Assert.assertTrue("Button doesn't fire clicks", clicked);
+ }
+
+ @Test
+ public void testClickDisabled() {
+ Button b = getButton();
+ b.setEnabled(false);
+ b.click();
+ Assert.assertFalse("Disabled button fires click events", clicked);
+ }
+
+ @Test
+ public void testClickReadOnly() {
+ Button b = getButton();
+ b.setReadOnly(true);
+ b.click();
+ Assert.assertFalse("Read only button fires click events", clicked);
+ }
+
+ private Button getButton() {
+ Button b = new Button();
+ UI ui = createUI();
+ b.setParent(ui);
+ addClickListener(b);
+ return b;
+ }
+
+ private UI createUI() {
+ UI ui = new UI() {
+
+ @Override
+ protected void init(VaadinRequest request) {
+ }
+ };
+ return ui;
+ }
+
+ private void addClickListener(Button b) {
+ clicked = false;
+ b.addClickListener(new Button.ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent ev) {
+ clicked = true;
+ }
+ });
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/button/ButtonDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/button/ButtonDeclarativeTest.java
new file mode 100644
index 0000000000..439a0d5be0
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/button/ButtonDeclarativeTest.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2000-2014 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.button;
+
+import org.jsoup.nodes.Element;
+import org.jsoup.parser.Tag;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.event.ShortcutAction.KeyCode;
+import com.vaadin.event.ShortcutAction.ModifierKey;
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.NativeButton;
+import com.vaadin.ui.declarative.DesignContext;
+
+/**
+ * Tests declarative support for implementations of {@link Button} and
+ * {@link NativeButton}.
+ *
+ * @since 7.4
+ * @author Vaadin Ltd
+ */
+public class ButtonDeclarativeTest extends DeclarativeTestBase<Button> {
+
+ @Test
+ public void testEmptyPlainText() {
+ String design = "<vaadin-button plain-text></vaadin-button>";
+ testButtonAndNativeButton(design, false, "");
+ }
+
+ @Test
+ public void testPlainTextCaption() {
+ String design = "<vaadin-button plain-text>Click</vaadin-button>";
+ testButtonAndNativeButton(design, false, "Click");
+ }
+
+ @Test
+ public void testEmptyHtml() {
+ String design = "<vaadin-button />";
+ testButtonAndNativeButton(design, true, "");
+ }
+
+ @Test
+ public void testHtmlCaption() {
+ String design = "<vaadin-button><b>Click</b></vaadin-button>";
+ testButtonAndNativeButton(design, true, "<b>Click</b>");
+ }
+
+ @Test
+ public void testWithCaptionAttribute() {
+ // The caption attribute should be ignored
+ String design = "<vaadin-button caption=Caption>Click</vaadin-button>";
+ String expectedWritten = "<vaadin-button>Click</vaadin-button>";
+ testButtonAndNativeButton(design, true, "Click", expectedWritten);
+ }
+
+ @Test
+ public void testWithOnlyCaptionAttribute() {
+ String design = "<vaadin-button caption=Click/>";
+ String expectedWritten = "<vaadin-button/>";
+ testButtonAndNativeButton(design, true, "", expectedWritten);
+ }
+
+ @Test
+ public void testHtmlEntitiesInCaption() {
+ String designPlainText = "<vaadin-button plain-text=\"true\">&gt; One</vaadin-button>";
+ String expectedCaptionPlainText = "> One";
+
+ Button read = read(designPlainText);
+ Assert.assertEquals(expectedCaptionPlainText, read.getCaption());
+
+ designPlainText = designPlainText.replace("vaadin-button",
+ "vaadin-native-button");
+ Button nativeButton = read(designPlainText);
+ Assert.assertEquals(expectedCaptionPlainText, nativeButton.getCaption());
+
+ String designHtml = "<vaadin-button>&gt; One</vaadin-button>";
+ String expectedCaptionHtml = "&gt; One";
+ read = read(designHtml);
+ Assert.assertEquals(expectedCaptionHtml, read.getCaption());
+
+ designHtml = designHtml
+ .replace("vaadin-button", "vaadin-native-button");
+ nativeButton = read(designHtml);
+ Assert.assertEquals(expectedCaptionHtml, nativeButton.getCaption());
+
+ read = new Button("&amp; Test");
+ read.setHtmlContentAllowed(true);
+ Element root = new Element(Tag.valueOf("vaadin-button"), "");
+ read.writeDesign(root, new DesignContext());
+ assertEquals("&amp; Test", root.html());
+
+ read.setHtmlContentAllowed(false);
+ root = new Element(Tag.valueOf("vaadin-button"), "");
+ read.writeDesign(root, new DesignContext());
+ assertEquals("&amp;amp; Test", root.html());
+
+ }
+
+ public void testButtonAndNativeButton(String design, boolean html,
+ String caption) {
+ testButtonAndNativeButton(design, html, caption, design);
+ }
+
+ public void testButtonAndNativeButton(String design, boolean html,
+ String caption, String expectedWritten) {
+ // Test Button
+ Button b = new Button();
+ b.setCaptionAsHtml(html);
+ b.setCaption(caption);
+ testRead(expectedWritten, b);
+ testWrite(expectedWritten, b);
+ // Test NativeButton
+ design = design.replace("vaadin-button", "vaadin-native-button");
+ expectedWritten = expectedWritten.replace("vaadin-button",
+ "vaadin-native-button");
+ NativeButton nb = new NativeButton();
+ nb.setCaptionAsHtml(html);
+ nb.setCaption(caption);
+ testRead(expectedWritten, nb);
+ testWrite(expectedWritten, nb);
+ }
+
+ @Test
+ public void testAttributes() {
+ String design = "<vaadin-button tabindex=3 plain-text icon-alt=OK "
+ + "click-shortcut=shift-ctrl-o></vaadin-button>";
+ Button b = new Button("");
+ b.setTabIndex(3);
+ b.setIconAlternateText("OK");
+ b.setClickShortcut(KeyCode.O, ModifierKey.CTRL, ModifierKey.SHIFT);
+ testRead(design, b);
+ testWrite(design, b);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/button/ButtonListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/button/ButtonListenersTest.java
new file mode 100644
index 0000000000..4478048b12
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/button/ButtonListenersTest.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.AbstractListenerMethodsTestBase;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+
+public class ButtonListenersTest extends AbstractListenerMethodsTestBase {
+ 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/src/test/java/com/vaadin/tests/server/component/calendar/CalendarBasicsTest.java b/server/src/test/java/com/vaadin/tests/server/component/calendar/CalendarBasicsTest.java
new file mode 100644
index 0000000000..1592fb6c38
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/calendar/CalendarBasicsTest.java
@@ -0,0 +1,290 @@
+/*
+ * Copyright 2000-2014 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.calendar;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.ui.Calendar;
+import com.vaadin.ui.Calendar.TimeFormat;
+import com.vaadin.ui.components.calendar.CalendarComponentEvents.BackwardEvent;
+import com.vaadin.ui.components.calendar.CalendarComponentEvents.DateClickEvent;
+import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventResize;
+import com.vaadin.ui.components.calendar.CalendarComponentEvents.ForwardEvent;
+import com.vaadin.ui.components.calendar.CalendarComponentEvents.MoveEvent;
+import com.vaadin.ui.components.calendar.CalendarComponentEvents.WeekClick;
+import com.vaadin.ui.components.calendar.event.BasicEventProvider;
+import com.vaadin.ui.components.calendar.event.CalendarEventProvider;
+
+/**
+ * Basic API tests for the calendar
+ */
+public class CalendarBasicsTest {
+
+ @Test
+ public void testEmptyConstructorInitialization() {
+
+ Calendar calendar = new Calendar();
+
+ // The calendar should have a basic event provider with no events
+ CalendarEventProvider provider = calendar.getEventProvider();
+ assertNotNull("Event provider should not be null", provider);
+
+ // Basic event handlers should be registered
+ assertNotNull(calendar.getHandler(BackwardEvent.EVENT_ID));
+ assertNotNull(calendar.getHandler(ForwardEvent.EVENT_ID));
+ assertNotNull(calendar.getHandler(WeekClick.EVENT_ID));
+ assertNotNull(calendar.getHandler(DateClickEvent.EVENT_ID));
+ assertNotNull(calendar.getHandler(MoveEvent.EVENT_ID));
+ assertNotNull(calendar.getHandler(EventResize.EVENT_ID));
+
+ // Calendar should have undefined size
+ assertTrue(calendar.getWidth() < 0);
+ assertTrue(calendar.getHeight() < 0);
+ }
+
+ @Test
+ public void testConstructorWithCaption() {
+ final String caption = "My Calendar Caption";
+ Calendar calendar = new Calendar(caption);
+ assertEquals(caption, calendar.getCaption());
+ }
+
+ @Test
+ public void testConstructorWithCustomEventProvider() {
+ BasicEventProvider myProvider = new BasicEventProvider();
+ Calendar calendar = new Calendar(myProvider);
+ assertEquals(myProvider, calendar.getEventProvider());
+ }
+
+ @Test
+ public void testConstructorWithCustomEventProviderAndCaption() {
+ BasicEventProvider myProvider = new BasicEventProvider();
+ final String caption = "My Calendar Caption";
+ Calendar calendar = new Calendar(caption, myProvider);
+ assertEquals(caption, calendar.getCaption());
+ assertEquals(myProvider, calendar.getEventProvider());
+ }
+
+ @Test
+ public void testDefaultStartAndEndDates() {
+ Calendar calendar = new Calendar();
+
+ // If no start and end date is set the calendar will display the current
+ // week
+ java.util.Calendar c = new GregorianCalendar();
+ java.util.Calendar c2 = new GregorianCalendar();
+
+ c2.setTime(calendar.getStartDate());
+ assertEquals(c.getFirstDayOfWeek(),
+ c2.get(java.util.Calendar.DAY_OF_WEEK));
+ c2.setTime(calendar.getEndDate());
+
+ c.set(java.util.Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek() + 6);
+ assertEquals(c.get(java.util.Calendar.DAY_OF_WEEK),
+ c2.get(java.util.Calendar.DAY_OF_WEEK));
+ }
+
+ @Test
+ public void testCustomStartAndEndDates() {
+ Calendar calendar = new Calendar();
+ java.util.Calendar c = new GregorianCalendar();
+
+ Date start = c.getTime();
+ c.add(java.util.Calendar.DATE, 3);
+ Date end = c.getTime();
+
+ calendar.setStartDate(start);
+ calendar.setEndDate(end);
+
+ assertEquals(start.getTime(), calendar.getStartDate().getTime());
+ assertEquals(end.getTime(), calendar.getEndDate().getTime());
+ }
+
+ @Test
+ public void testCustomLocale() {
+ Calendar calendar = new Calendar();
+ calendar.setLocale(Locale.CANADA_FRENCH);
+
+ // Setting the locale should set the internal calendars locale
+ assertEquals(Locale.CANADA_FRENCH, calendar.getLocale());
+ java.util.Calendar c = new GregorianCalendar(Locale.CANADA_FRENCH);
+ assertEquals(c.getTimeZone().getRawOffset(), calendar
+ .getInternalCalendar().getTimeZone().getRawOffset());
+ }
+
+ @Test
+ public void testTimeFormat() {
+ Calendar calendar = new Calendar();
+
+ // The default timeformat depends on the current locale
+ calendar.setLocale(Locale.ENGLISH);
+ assertEquals(TimeFormat.Format12H, calendar.getTimeFormat());
+
+ calendar.setLocale(Locale.ITALIAN);
+ assertEquals(TimeFormat.Format24H, calendar.getTimeFormat());
+
+ // Setting a specific time format overrides the locale
+ calendar.setTimeFormat(TimeFormat.Format12H);
+ assertEquals(TimeFormat.Format12H, calendar.getTimeFormat());
+ }
+
+ @Test
+ public void testTimeZone() {
+ Calendar calendar = new Calendar();
+ calendar.setLocale(Locale.CANADA_FRENCH);
+
+ // By default the calendars timezone is returned
+ assertEquals(calendar.getInternalCalendar().getTimeZone(),
+ calendar.getTimeZone());
+
+ // One can override the default behaviour by specifying a timezone
+ TimeZone customTimeZone = TimeZone.getTimeZone("Europe/Helsinki");
+ calendar.setTimeZone(customTimeZone);
+ assertEquals(customTimeZone, calendar.getTimeZone());
+ }
+
+ @Test
+ public void testVisibleDaysOfWeek() {
+ Calendar calendar = new Calendar();
+
+ // The defaults are the whole week
+ assertEquals(1, calendar.getFirstVisibleDayOfWeek());
+ assertEquals(7, calendar.getLastVisibleDayOfWeek());
+
+ calendar.setFirstVisibleDayOfWeek(0); // Invalid input
+ assertEquals(1, calendar.getFirstVisibleDayOfWeek());
+
+ calendar.setLastVisibleDayOfWeek(0); // Invalid input
+ assertEquals(7, calendar.getLastVisibleDayOfWeek());
+
+ calendar.setFirstVisibleDayOfWeek(8); // Invalid input
+ assertEquals(1, calendar.getFirstVisibleDayOfWeek());
+
+ calendar.setLastVisibleDayOfWeek(8); // Invalid input
+ assertEquals(7, calendar.getLastVisibleDayOfWeek());
+
+ calendar.setFirstVisibleDayOfWeek(4);
+ assertEquals(4, calendar.getFirstVisibleDayOfWeek());
+
+ calendar.setLastVisibleDayOfWeek(6);
+ assertEquals(6, calendar.getLastVisibleDayOfWeek());
+
+ calendar.setFirstVisibleDayOfWeek(7); // Invalid since last day is 6
+ assertEquals(4, calendar.getFirstVisibleDayOfWeek());
+
+ calendar.setLastVisibleDayOfWeek(2); // Invalid since first day is 4
+ assertEquals(6, calendar.getLastVisibleDayOfWeek());
+ }
+
+ @Test
+ public void testVisibleHoursInDay() {
+ Calendar calendar = new Calendar();
+
+ // Defaults are the whole day
+ assertEquals(0, calendar.getFirstVisibleHourOfDay());
+ assertEquals(23, calendar.getLastVisibleHourOfDay());
+ }
+
+ @Test
+ public void isClientChangeAllowed_connectorEnabled() {
+ TestCalendar calendar = new TestCalendar(true);
+ Assert.assertTrue(
+ "Calendar with enabled connector doesn't allow client change",
+ calendar.isClientChangeAllowed());
+ }
+
+ // regression test to ensure old functionality is not broken
+ @Test
+ public void defaultFirstDayOfWeek() {
+ Calendar calendar = new Calendar();
+ calendar.setLocale(Locale.GERMAN);
+ // simulating consequences of markAsDirty
+ calendar.beforeClientResponse(true);
+ assertEquals(java.util.Calendar.MONDAY, calendar.getInternalCalendar()
+ .getFirstDayOfWeek());
+ }
+
+ @Test
+ public void customFirstDayOfWeek() {
+ Calendar calendar = new Calendar();
+ calendar.setLocale(Locale.GERMAN);
+ calendar.setFirstDayOfWeek(java.util.Calendar.SUNDAY);
+
+ // simulating consequences of markAsDirty
+ calendar.beforeClientResponse(true);
+ assertEquals(java.util.Calendar.SUNDAY, calendar.getInternalCalendar()
+ .getFirstDayOfWeek());
+ }
+
+ @Test
+ public void customFirstDayOfWeekCanSetEvenBeforeLocale() {
+ Calendar calendar = new Calendar();
+ calendar.setFirstDayOfWeek(java.util.Calendar.SUNDAY);
+
+ calendar.setLocale(Locale.GERMAN);
+ // simulating consequences of markAsDirty
+ calendar.beforeClientResponse(true);
+ assertEquals(java.util.Calendar.SUNDAY, calendar.getInternalCalendar()
+ .getFirstDayOfWeek());
+ }
+
+ @Test
+ public void customFirstDayOfWeekSetNullRestoresDefault() {
+ Calendar calendar = new Calendar();
+ calendar.setLocale(Locale.GERMAN);
+ calendar.setFirstDayOfWeek(java.util.Calendar.SUNDAY);
+ calendar.setFirstDayOfWeek(null);
+ // simulating consequences of markAsDirty
+ calendar.beforeClientResponse(true);
+ assertEquals(java.util.Calendar.MONDAY, calendar.getInternalCalendar()
+ .getFirstDayOfWeek());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void customFirstDayOfWeekValidation() {
+ Calendar calendar = new Calendar();
+ int someWrongDayOfWeek = 10;
+ calendar.setFirstDayOfWeek(someWrongDayOfWeek);
+ }
+
+ private static class TestCalendar extends Calendar {
+ TestCalendar(boolean connectorEnabled) {
+ isConnectorEnabled = connectorEnabled;
+ }
+
+ @Override
+ public boolean isConnectorEnabled() {
+ return isConnectorEnabled;
+ }
+
+ @Override
+ public boolean isClientChangeAllowed() {
+ return super.isClientChangeAllowed();
+ }
+
+ private final boolean isConnectorEnabled;
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/calendar/CalendarDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/calendar/CalendarDeclarativeTest.java
new file mode 100644
index 0000000000..f0ee8f7298
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/calendar/CalendarDeclarativeTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2000-2014 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.calendar;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.TimeZone;
+
+import org.junit.Test;
+
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.Calendar;
+import com.vaadin.ui.Calendar.TimeFormat;
+
+public class CalendarDeclarativeTest extends DeclarativeTestBase<Calendar> {
+
+ @Test
+ public void testEmpty() {
+ verifyDeclarativeDesign("<vaadin-calendar></vaadin-calendar>", new Calendar());
+ }
+
+ @Test
+ public void testCalendarAllFeatures() throws ParseException {
+ String design = "<vaadin-calendar start-date='2014-11-17' end-date='2014-11-23' "
+ + "first-visible-day-of-week=2 last-visible-day-of-week=5 "
+ + "time-zone='EST' time-format='12h' first-visible-hour-of-day=8 "
+ + "last-visible-hour-of-day=18 weekly-caption-format='mmm MM/dd' />";
+
+ DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+ Calendar calendar = new Calendar();
+ calendar.setStartDate(format.parse("2014-11-17"));
+ calendar.setEndDate(format.parse("2014-11-23"));
+ calendar.setFirstVisibleDayOfWeek(2);
+ calendar.setLastVisibleDayOfWeek(5);
+ calendar.setTimeZone(TimeZone.getTimeZone("EST"));
+ calendar.setTimeFormat(TimeFormat.Format12H);
+ calendar.setFirstVisibleHourOfDay(8);
+ calendar.setLastVisibleHourOfDay(18);
+ calendar.setWeeklyCaptionFormat("mmm MM/dd");
+ verifyDeclarativeDesign(design, calendar);
+ }
+
+ protected void verifyDeclarativeDesign(String design, Calendar expected) {
+ testRead(design, expected);
+ testWrite(design, expected);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/calendar/ContainerDataSourceTest.java b/server/src/test/java/com/vaadin/tests/server/component/calendar/ContainerDataSourceTest.java
new file mode 100644
index 0000000000..8a066497cd
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/calendar/ContainerDataSourceTest.java
@@ -0,0 +1,394 @@
+/*
+ * Copyright 2000-2014 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.calendar;
+
+import java.util.Date;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.junit.Test;
+
+import com.vaadin.data.Container.Indexed;
+import com.vaadin.data.Container.Sortable;
+import com.vaadin.data.Item;
+import com.vaadin.data.Property;
+import com.vaadin.data.util.BeanItemContainer;
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.ui.Calendar;
+import com.vaadin.ui.components.calendar.ContainerEventProvider;
+import com.vaadin.ui.components.calendar.event.BasicEvent;
+import com.vaadin.ui.components.calendar.event.CalendarEvent;
+
+public class ContainerDataSourceTest extends TestCase {
+
+ private Calendar calendar;
+
+ @Override
+ public void setUp() {
+ calendar = new Calendar();
+ }
+
+ /**
+ * Tests adding a bean item container to the Calendar
+ */
+ @Test
+ public void testWithBeanItemContainer() {
+
+ // Create a container to use as a datasource
+ Indexed container = createTestBeanItemContainer();
+
+ // Set datasource
+ calendar.setContainerDataSource(container);
+
+ // Start and end dates to query for
+ java.util.Calendar cal = java.util.Calendar.getInstance();
+ cal.setTime(((CalendarEvent) container.getIdByIndex(0)).getStart());
+ Date start = cal.getTime();
+ cal.add(java.util.Calendar.MONTH, 1);
+ Date end = cal.getTime();
+
+ // Test the all events are returned
+ List<CalendarEvent> events = calendar.getEventProvider().getEvents(
+ start, end);
+ assertEquals(container.size(), events.size());
+
+ // Test that a certain range is returned
+ cal.setTime(((CalendarEvent) container.getIdByIndex(6)).getStart());
+ end = cal.getTime();
+ events = calendar.getEventProvider().getEvents(start, end);
+ assertEquals(6, events.size());
+ }
+
+ /**
+ * This tests tests that if you give the Calendar an unsorted (== not sorted
+ * by starting date) container then the calendar should gracefully handle
+ * it. In this case the size of the container will be wrong. The test is
+ * exactly the same as {@link #testWithBeanItemContainer()} except that the
+ * beans has been intentionally sorted by caption instead of date.
+ */
+ @Test
+ public void testWithUnsortedBeanItemContainer() {
+ // Create a container to use as a datasource
+ Indexed container = createTestBeanItemContainer();
+
+ // Make the container sorted by caption
+ ((Sortable) container).sort(new Object[] { "caption" },
+ new boolean[] { true });
+
+ // Set data source
+ calendar.setContainerDataSource(container);
+
+ // Start and end dates to query for
+ java.util.Calendar cal = java.util.Calendar.getInstance();
+ cal.setTime(((CalendarEvent) container.getIdByIndex(0)).getStart());
+ Date start = cal.getTime();
+ cal.add(java.util.Calendar.MONTH, 1);
+ Date end = cal.getTime();
+
+ // Test the all events are returned
+ List<CalendarEvent> events = calendar.getEventProvider().getEvents(
+ start, end);
+ assertEquals(container.size(), events.size());
+
+ // Test that a certain range is returned
+ cal.setTime(((CalendarEvent) container.getIdByIndex(6)).getStart());
+ end = cal.getTime();
+ events = calendar.getEventProvider().getEvents(start, end);
+
+ // The events size is 1 since the getEvents returns the wrong range
+ assertEquals(1, events.size());
+ }
+
+ /**
+ * Tests adding a Indexed container to the Calendar
+ */
+ @Test
+ public void testWithIndexedContainer() {
+
+ // Create a container to use as a datasource
+ Indexed container = createTestIndexedContainer();
+
+ // Set datasource
+ calendar.setContainerDataSource(container, "testCaption",
+ "testDescription", "testStartDate", "testEndDate", null);
+
+ // Start and end dates to query for
+ java.util.Calendar cal = java.util.Calendar.getInstance();
+ cal.setTime((Date) container.getItem(container.getIdByIndex(0))
+ .getItemProperty("testStartDate").getValue());
+ Date start = cal.getTime();
+ cal.add(java.util.Calendar.MONTH, 1);
+ Date end = cal.getTime();
+
+ // Test the all events are returned
+ List<CalendarEvent> events = calendar.getEventProvider().getEvents(
+ start, end);
+ assertEquals(container.size(), events.size());
+
+ // Check that event values are present
+ CalendarEvent e = events.get(0);
+ assertEquals("Test 1", e.getCaption());
+ assertEquals("Description 1", e.getDescription());
+ assertTrue(e.getStart().compareTo(start) == 0);
+
+ // Test that a certain range is returned
+ cal.setTime((Date) container.getItem(container.getIdByIndex(6))
+ .getItemProperty("testStartDate").getValue());
+ end = cal.getTime();
+ events = calendar.getEventProvider().getEvents(start, end);
+ assertEquals(6, events.size());
+ }
+
+ @Test
+ public void testNullLimitsBeanItemContainer() {
+ // Create a container to use as a datasource
+ Indexed container = createTestBeanItemContainer();
+
+ // Start and end dates to query for
+ java.util.Calendar cal = java.util.Calendar.getInstance();
+ cal.setTime(((CalendarEvent) container.getIdByIndex(0)).getStart());
+ Date start = cal.getTime();
+ cal.add(java.util.Calendar.MONTH, 1);
+ Date end = cal.getTime();
+
+ // Set datasource
+ calendar.setContainerDataSource(container);
+
+ // Test null start time
+ List<CalendarEvent> events = calendar.getEventProvider().getEvents(
+ null, end);
+ assertEquals(container.size(), events.size());
+
+ // Test null end time
+ events = calendar.getEventProvider().getEvents(start, null);
+ assertEquals(container.size(), events.size());
+
+ // Test both null times
+ events = calendar.getEventProvider().getEvents(null, null);
+ assertEquals(container.size(), events.size());
+ }
+
+ @Test
+ public void testNullLimitsIndexedContainer() {
+ // Create a container to use as a datasource
+ Indexed container = createTestIndexedContainer();
+
+ // Start and end dates to query for
+ java.util.Calendar cal = java.util.Calendar.getInstance();
+ cal.setTime((Date) container.getItem(container.getIdByIndex(0))
+ .getItemProperty("testStartDate").getValue());
+ Date start = cal.getTime();
+ cal.add(java.util.Calendar.MONTH, 1);
+ Date end = cal.getTime();
+
+ // Set datasource
+ calendar.setContainerDataSource(container, "testCaption",
+ "testDescription", "testStartDate", "testEndDate", null);
+
+ // Test null start time
+ List<CalendarEvent> events = calendar.getEventProvider().getEvents(
+ null, end);
+ assertEquals(container.size(), events.size());
+
+ // Test null end time
+ events = calendar.getEventProvider().getEvents(start, null);
+ assertEquals(container.size(), events.size());
+
+ // Test both null times
+ events = calendar.getEventProvider().getEvents(null, null);
+ assertEquals(container.size(), events.size());
+ }
+
+ /**
+ * Tests the addEvent convenience method with the default event provider
+ */
+ @Test
+ public void testAddEventConvinienceMethod() {
+
+ // Start and end dates to query for
+ java.util.Calendar cal = java.util.Calendar.getInstance();
+ Date start = cal.getTime();
+ cal.add(java.util.Calendar.MONTH, 1);
+ Date end = cal.getTime();
+
+ // Ensure no events
+ assertEquals(0, calendar.getEvents(start, end).size());
+
+ // Add an event
+ BasicEvent event = new BasicEvent("Test", "Test", start);
+ calendar.addEvent(event);
+
+ // Ensure event exists
+ List<CalendarEvent> events = calendar.getEvents(start, end);
+ assertEquals(1, events.size());
+ assertEquals(events.get(0).getCaption(), event.getCaption());
+ assertEquals(events.get(0).getDescription(), event.getDescription());
+ assertEquals(events.get(0).getStart(), event.getStart());
+ }
+
+ /**
+ * Test the removeEvent convenience method with the default event provider
+ */
+ @Test
+ public void testRemoveEventConvinienceMethod() {
+
+ // Start and end dates to query for
+ java.util.Calendar cal = java.util.Calendar.getInstance();
+ Date start = cal.getTime();
+ cal.add(java.util.Calendar.MONTH, 1);
+ Date end = cal.getTime();
+
+ // Ensure no events
+ assertEquals(0, calendar.getEvents(start, end).size());
+
+ // Add an event
+ CalendarEvent event = new BasicEvent("Test", "Test", start);
+ calendar.addEvent(event);
+
+ // Ensure event exists
+ assertEquals(1, calendar.getEvents(start, end).size());
+
+ // Remove event
+ calendar.removeEvent(event);
+
+ // Ensure no events
+ assertEquals(0, calendar.getEvents(start, end).size());
+ }
+
+ @Test
+ public void testAddEventConvinienceMethodWithCustomEventProvider() {
+
+ // Use a container data source
+ calendar.setEventProvider(new ContainerEventProvider(
+ new BeanItemContainer<BasicEvent>(BasicEvent.class)));
+
+ // Start and end dates to query for
+ java.util.Calendar cal = java.util.Calendar.getInstance();
+ Date start = cal.getTime();
+ cal.add(java.util.Calendar.MONTH, 1);
+ Date end = cal.getTime();
+
+ // Ensure no events
+ assertEquals(0, calendar.getEvents(start, end).size());
+
+ // Add an event
+ BasicEvent event = new BasicEvent("Test", "Test", start);
+ calendar.addEvent(event);
+
+ // Ensure event exists
+ List<CalendarEvent> events = calendar.getEvents(start, end);
+ assertEquals(1, events.size());
+ assertEquals(events.get(0).getCaption(), event.getCaption());
+ assertEquals(events.get(0).getDescription(), event.getDescription());
+ assertEquals(events.get(0).getStart(), event.getStart());
+ }
+
+ @Test
+ public void testRemoveEventConvinienceMethodWithCustomEventProvider() {
+
+ // Use a container data source
+ calendar.setEventProvider(new ContainerEventProvider(
+ new BeanItemContainer<BasicEvent>(BasicEvent.class)));
+
+ // Start and end dates to query for
+ java.util.Calendar cal = java.util.Calendar.getInstance();
+ Date start = cal.getTime();
+ cal.add(java.util.Calendar.MONTH, 1);
+ Date end = cal.getTime();
+
+ // Ensure no events
+ assertEquals(0, calendar.getEvents(start, end).size());
+
+ // Add an event
+ BasicEvent event = new BasicEvent("Test", "Test", start);
+ calendar.addEvent(event);
+
+ // Ensure event exists
+ List<CalendarEvent> events = calendar.getEvents(start, end);
+ assertEquals(1, events.size());
+
+ // Remove event
+ calendar.removeEvent(event);
+
+ // Ensure no events
+ assertEquals(0, calendar.getEvents(start, end).size());
+ }
+
+ @Test
+ public void testStyleNamePropertyRetrieved() {
+ IndexedContainer ic = (IndexedContainer) createTestIndexedContainer();
+ ic.addContainerProperty("testStyleName", String.class, "");
+ for (int i = 0; i < 10; i++) {
+ Item item = ic.getItem(ic.getIdByIndex(i));
+ @SuppressWarnings("unchecked")
+ Property<String> itemProperty = item
+ .getItemProperty("testStyleName");
+ itemProperty.setValue("testStyle");
+ }
+
+ ContainerEventProvider provider = new ContainerEventProvider(ic);
+ provider.setCaptionProperty("testCaption");
+ provider.setDescriptionProperty("testDescription");
+ provider.setStartDateProperty("testStartDate");
+ provider.setEndDateProperty("testEndDate");
+ provider.setStyleNameProperty("testStyleName");
+
+ calendar.setEventProvider(provider);
+ java.util.Calendar cal = java.util.Calendar.getInstance();
+ Date now = cal.getTime();
+ cal.add(java.util.Calendar.DAY_OF_MONTH, 20);
+ Date then = cal.getTime();
+ List<CalendarEvent> events = calendar.getEventProvider().getEvents(now,
+ then);
+ for (CalendarEvent ce : events) {
+ assertEquals("testStyle", ce.getStyleName());
+ }
+ }
+
+ private static Indexed createTestBeanItemContainer() {
+ BeanItemContainer<CalendarEvent> eventContainer = new BeanItemContainer<CalendarEvent>(
+ CalendarEvent.class);
+ java.util.Calendar cal = java.util.Calendar.getInstance();
+ for (int i = 1; i <= 10; i++) {
+ eventContainer.addBean(new BasicEvent("Test " + i, "Description "
+ + i, cal.getTime()));
+ cal.add(java.util.Calendar.DAY_OF_MONTH, 2);
+ }
+ return eventContainer;
+ }
+
+ private static Indexed createTestIndexedContainer() {
+ IndexedContainer container = new IndexedContainer();
+ container.addContainerProperty("testCaption", String.class, "");
+ container.addContainerProperty("testDescription", String.class, "");
+ container.addContainerProperty("testStartDate", Date.class, null);
+ container.addContainerProperty("testEndDate", Date.class, null);
+
+ java.util.Calendar cal = java.util.Calendar.getInstance();
+ for (int i = 1; i <= 10; i++) {
+ Item item = container.getItem(container.addItem());
+ item.getItemProperty("testCaption").setValue("Test " + i);
+ item.getItemProperty("testDescription")
+ .setValue("Description " + i);
+ item.getItemProperty("testStartDate").setValue(cal.getTime());
+ item.getItemProperty("testEndDate").setValue(cal.getTime());
+ cal.add(java.util.Calendar.DAY_OF_MONTH, 2);
+ }
+ return container;
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/calendar/ContainerEventProviderTest.java b/server/src/test/java/com/vaadin/tests/server/component/calendar/ContainerEventProviderTest.java
new file mode 100644
index 0000000000..63749a2fc9
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/calendar/ContainerEventProviderTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2000-2014 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.calendar;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.util.BeanItemContainer;
+import com.vaadin.ui.components.calendar.ContainerEventProvider;
+import com.vaadin.ui.components.calendar.event.CalendarEvent;
+
+/**
+ *
+ * @author Vaadin Ltd
+ */
+public class ContainerEventProviderTest {
+
+ @Test
+ public void testDefaultAllDayProperty() {
+ ContainerEventProvider provider = new ContainerEventProvider(null);
+ Assert.assertEquals(ContainerEventProvider.ALL_DAY_PROPERTY,
+ provider.getAllDayProperty());
+
+ }
+
+ @Test
+ public void testSetAllDayProperty() {
+ ContainerEventProvider provider = new ContainerEventProvider(null);
+ Object prop = new Object();
+ provider.setAllDayProperty(prop);
+ Assert.assertEquals(prop, provider.getAllDayProperty());
+ }
+
+ @Test
+ public void testGetEvents() {
+ BeanItemContainer<EventBean> container = new BeanItemContainer<EventBean>(
+ EventBean.class);
+ EventBean bean = new EventBean();
+ container.addBean(bean);
+ ContainerEventProvider provider = new ContainerEventProvider(container);
+ List<CalendarEvent> events = provider.getEvents(bean.getStart(),
+ bean.getEnd());
+ Assert.assertTrue(events.get(0).isAllDay());
+ }
+
+ public static class EventBean {
+
+ public boolean isAllDay() {
+ return true;
+ }
+
+ public void setAllDay(boolean allDay) {
+ }
+
+ public Date getStart() {
+ return Calendar.getInstance().getTime();
+ }
+
+ public Date getEnd() {
+ Calendar calendar = Calendar.getInstance();
+ calendar.add(Calendar.MINUTE, 10);
+ return calendar.getTime();
+ }
+
+ public void setStart(Date date) {
+ }
+
+ public void setEnd(Date date) {
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/checkbox/CheckboxDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/checkbox/CheckboxDeclarativeTest.java
new file mode 100644
index 0000000000..760d8d2548
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/checkbox/CheckboxDeclarativeTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2014 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.checkbox;
+
+import org.junit.Test;
+
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.CheckBox;
+
+/**
+ * Tests declarative support for implementations of {@link CheckBox}.
+ *
+ * @since 7.4
+ * @author Vaadin Ltd
+ */
+public class CheckboxDeclarativeTest extends DeclarativeTestBase<CheckBox> {
+
+ @Test
+ public void testChecked() {
+ String design = "<vaadin-check-box />";
+ CheckBox checkBox = new CheckBox();
+ testRead(design, checkBox);
+ testWrite(design, checkBox);
+ }
+
+ @Test
+ public void testUnchecked() {
+ String design = "<vaadin-check-box checked />";
+ CheckBox checkBox = new CheckBox();
+ checkBox.setValue(true);
+ testRead(design, checkBox);
+ testWrite(design, checkBox);
+ }
+
+ @Test
+ public void testReadOnlyValue() {
+ String design = "<vaadin-check-box readonly checked />";
+ CheckBox checkBox = new CheckBox();
+ checkBox.setValue(true);
+ checkBox.setReadOnly(true);
+ testRead(design, checkBox);
+ testWrite(design, checkBox);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/colorpicker/AbstractColorPickerDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/colorpicker/AbstractColorPickerDeclarativeTest.java
new file mode 100644
index 0000000000..717ba1f45a
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/colorpicker/AbstractColorPickerDeclarativeTest.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2000-2014 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.colorpicker;
+
+import org.junit.Test;
+
+import com.vaadin.shared.ui.colorpicker.Color;
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.AbstractColorPicker;
+import com.vaadin.ui.AbstractColorPicker.PopupStyle;
+import com.vaadin.ui.ColorPicker;
+import com.vaadin.ui.ColorPickerArea;
+
+public class AbstractColorPickerDeclarativeTest extends
+ DeclarativeTestBase<AbstractColorPicker> {
+
+ @Test
+ public void testAllAbstractColorPickerFeatures() {
+ String design = "<vaadin-color-picker color='#fafafa' default-caption-enabled position='100,100'"
+ + " popup-style='simple' rgb-visibility='false' hsv-visibility='false'"
+ + " history-visibility=false textfield-visibility=false />";
+ ColorPicker colorPicker = new ColorPicker();
+ int colorInt = Integer.parseInt("fafafa", 16);
+ colorPicker.setColor(new Color(colorInt));
+ colorPicker.setDefaultCaptionEnabled(true);
+ colorPicker.setPosition(100, 100);
+ colorPicker.setPopupStyle(PopupStyle.POPUP_SIMPLE);
+ colorPicker.setRGBVisibility(false);
+ colorPicker.setHSVVisibility(false);
+ colorPicker.setSwatchesVisibility(true);
+ colorPicker.setHistoryVisibility(false);
+ colorPicker.setTextfieldVisibility(false);
+
+ testWrite(design, colorPicker);
+ testRead(design, colorPicker);
+ }
+
+ @Test
+ public void testEmptyColorPicker() {
+ String design = "<vaadin-color-picker />";
+ ColorPicker colorPicker = new ColorPicker();
+ testRead(design, colorPicker);
+ testWrite(design, colorPicker);
+ }
+
+ @Test
+ public void testAllAbstractColorPickerAreaFeatures() {
+ String design = "<vaadin-color-picker-area color='#fafafa' default-caption-enabled position='100,100'"
+ + " popup-style='simple' rgb-visibility='false' hsv-visibility='false'"
+ + " history-visibility=false textfield-visibility=false />";
+ AbstractColorPicker colorPicker = new ColorPickerArea();
+ int colorInt = Integer.parseInt("fafafa", 16);
+ colorPicker.setColor(new Color(colorInt));
+ colorPicker.setDefaultCaptionEnabled(true);
+ colorPicker.setPosition(100, 100);
+ colorPicker.setPopupStyle(PopupStyle.POPUP_SIMPLE);
+ colorPicker.setRGBVisibility(false);
+ colorPicker.setHSVVisibility(false);
+ colorPicker.setSwatchesVisibility(true);
+ colorPicker.setHistoryVisibility(false);
+ colorPicker.setTextfieldVisibility(false);
+
+ testWrite(design, colorPicker);
+ testRead(design, colorPicker);
+ }
+
+ @Test
+ public void testEmptyColorPickerArea() {
+ String design = "<vaadin-color-picker-area />";
+ AbstractColorPicker colorPicker = new ColorPickerArea();
+ testRead(design, colorPicker);
+ testWrite(design, colorPicker);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/colorpicker/ColorConversionsTest.java b/server/src/test/java/com/vaadin/tests/server/component/colorpicker/ColorConversionsTest.java
new file mode 100644
index 0000000000..8c05e58b9c
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/colorpicker/ColorConversionsTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2014 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.colorpicker;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import com.vaadin.shared.ui.colorpicker.Color;
+
+public class ColorConversionsTest {
+
+ @Test
+ public void convertHSL2RGB() {
+
+ int rgb = Color.HSLtoRGB(100, 50, 50);
+ Color c = new Color(rgb);
+ assertEquals(106, c.getRed());
+ assertEquals(191, c.getGreen());
+ assertEquals(64, c.getBlue());
+ assertEquals("#6abf40", c.getCSS());
+
+ rgb = Color.HSLtoRGB(0, 50, 50);
+ c = new Color(rgb);
+ assertEquals(191, c.getRed());
+ assertEquals(64, c.getGreen());
+ assertEquals(64, c.getBlue());
+ assertEquals("#bf4040", c.getCSS());
+
+ rgb = Color.HSLtoRGB(50, 0, 50);
+ c = new Color(rgb);
+ assertEquals(128, c.getRed());
+ assertEquals(128, c.getGreen());
+ assertEquals(128, c.getBlue());
+ assertEquals("#808080", c.getCSS());
+
+ rgb = Color.HSLtoRGB(50, 100, 0);
+ c = new Color(rgb);
+ assertEquals(0, c.getRed(), 0);
+ assertEquals(0, c.getGreen(), 0);
+ assertEquals(0, c.getBlue(), 0);
+ assertEquals("#000000", c.getCSS());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/combobox/ComboBoxDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/combobox/ComboBoxDeclarativeTest.java
new file mode 100644
index 0000000000..fcc7eb97a1
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/combobox/ComboBoxDeclarativeTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2000-2014 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.combobox;
+
+import org.junit.Test;
+
+import com.vaadin.shared.ui.combobox.FilteringMode;
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.ComboBox;
+
+public class ComboBoxDeclarativeTest extends DeclarativeTestBase<ComboBox> {
+
+ @Test
+ public void testReadOnlyWithOptionsRead() {
+ testRead(getReadOnlyWithOptionsDesign(),
+ getReadOnlyWithOptionsExpected());
+ }
+
+ private ComboBox getReadOnlyWithOptionsExpected() {
+ ComboBox cb = new ComboBox();
+ cb.setTextInputAllowed(false);
+ cb.addItem("Hello");
+ cb.addItem("World");
+ return cb;
+ }
+
+ private String getReadOnlyWithOptionsDesign() {
+ return "<vaadin-combo-box text-input-allowed='false'><option>Hello</option><option>World</option></vaadin-combo-box>";
+ }
+
+ @Test
+ public void testReadOnlyWithOptionsWrite() {
+ testWrite(stripOptionTags(getReadOnlyWithOptionsDesign()),
+ getReadOnlyWithOptionsExpected());
+ }
+
+ @Test
+ public void testBasicRead() {
+ testRead(getBasicDesign(), getBasicExpected());
+ }
+
+ @Test
+ public void testBasicWrite() {
+ testWrite(getBasicDesign(), getBasicExpected());
+ }
+
+ @Test
+ public void testReadOnlyValue() {
+ String design = "<vaadin-combo-box readonly value='foo'><option selected>foo</option></vaadin-combo-box>";
+
+ ComboBox comboBox = new ComboBox();
+ comboBox.addItems("foo", "bar");
+ comboBox.setValue("foo");
+ comboBox.setReadOnly(true);
+
+ testRead(design, comboBox);
+
+ // Selects items are not written out by default
+ String design2 = "<vaadin-combo-box readonly></vaadin-combo-box>";
+ testWrite(design2, comboBox);
+ }
+
+ private String getBasicDesign() {
+ return "<vaadin-combo-box input-prompt=\"Select something\" filtering-mode=\"off\" scroll-to-selected-item='false'>";
+ }
+
+ private ComboBox getBasicExpected() {
+ ComboBox cb = new ComboBox();
+ cb.setInputPrompt("Select something");
+ cb.setTextInputAllowed(true);
+ cb.setFilteringMode(FilteringMode.OFF);
+ cb.setScrollToSelectedItem(false);
+ return cb;
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/combobox/ComboBoxStateTest.java b/server/src/test/java/com/vaadin/tests/server/component/combobox/ComboBoxStateTest.java
new file mode 100644
index 0000000000..0908a355de
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/combobox/ComboBoxStateTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2000-2014 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.combobox;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.shared.ui.combobox.ComboBoxState;
+import com.vaadin.ui.ComboBox;
+
+/**
+ * Tests for ComboBox state.
+ *
+ */
+public class ComboBoxStateTest {
+ @Test
+ public void getState_comboboxHasCustomState() {
+ TestComboBox combobox = new TestComboBox();
+ ComboBoxState state = combobox.getState();
+ Assert.assertEquals("Unexpected state class", ComboBoxState.class,
+ state.getClass());
+ }
+
+ @Test
+ public void getPrimaryStyleName_comboboxHasCustomPrimaryStyleName() {
+ ComboBox combobox = new ComboBox();
+ ComboBoxState state = new ComboBoxState();
+ Assert.assertEquals("Unexpected primary style name",
+ state.primaryStyleName, combobox.getPrimaryStyleName());
+ }
+
+ @Test
+ public void comboboxStateHasCustomPrimaryStyleName() {
+ ComboBoxState state = new ComboBoxState();
+ Assert.assertEquals("Unexpected primary style name", "v-filterselect",
+ state.primaryStyleName);
+ }
+
+ private static class TestComboBox extends ComboBox {
+
+ @Override
+ public ComboBoxState getState() {
+ return super.getState();
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/csslayout/AddComponentsTest.java b/server/src/test/java/com/vaadin/tests/server/component/csslayout/AddComponentsTest.java
new file mode 100644
index 0000000000..441f743214
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/csslayout/AddComponentsTest.java
@@ -0,0 +1,130 @@
+package com.vaadin.tests.server.component.csslayout;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.junit.Test;
+
+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 });
+ }
+
+ @Test
+ public void testConstructorWithComponents() {
+ Layout layout = new CssLayout(children);
+ assertOrder(layout, new int[] { 0, 1, 2, 3 });
+ }
+
+ @Test
+ public void testAddComponents() {
+ CssLayout layout = new CssLayout();
+ layout.addComponents(children);
+ assertOrder(layout, new int[] { 0, 1, 2, 3 });
+
+ Label extra = new Label("Extra");
+ layout.addComponents(extra);
+ assertSame(extra, layout.getComponent(4));
+
+ layout.removeAllComponents();
+ layout.addComponents(children[3], children[2], children[1], children[0]);
+ assertOrder(layout, new int[] { 3, 2, 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/src/test/java/com/vaadin/tests/server/component/csslayout/CssLayoutDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/csslayout/CssLayoutDeclarativeTest.java
new file mode 100644
index 0000000000..31ee1a05f5
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/csslayout/CssLayoutDeclarativeTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2000-2014 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.csslayout;
+
+import org.junit.Test;
+
+import com.vaadin.shared.ui.label.ContentMode;
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.CssLayout;
+import com.vaadin.ui.Label;
+
+/**
+ * Tests declarative support for CssLayout.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class CssLayoutDeclarativeTest extends DeclarativeTestBase<CssLayout> {
+
+ @Test
+ public void testNoChildren() {
+ String design = "<vaadin-css-layout />";
+ CssLayout layout = new CssLayout();
+ testRead(design, layout);
+ testWrite(design, layout);
+ design = "<vaadin-css-layout caption=\"A caption\"/>";
+ layout = new CssLayout();
+ layout.setCaption("A caption");
+ testRead(design, layout);
+ testWrite(design, layout);
+ }
+
+ @Test
+ public void testFeatures() {
+ String design = "<vaadin-css-layout caption=test-layout><vaadin-label caption=test-label />"
+ + "<vaadin-button>test-button</vaadin-button></vaadin-css-layout>";
+ CssLayout layout = new CssLayout();
+ layout.setCaption("test-layout");
+ Label l = new Label();
+ l.setContentMode(ContentMode.HTML);
+ l.setCaption("test-label");
+ layout.addComponent(l);
+ Button b = new Button("test-button");
+ b.setCaptionAsHtml(true);
+ layout.addComponent(b);
+ testRead(design, layout);
+ testWrite(design, layout);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/csslayout/CssLayoutListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/csslayout/CssLayoutListenersTest.java
new file mode 100644
index 0000000000..e000df593b
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/csslayout/CssLayoutListenersTest.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.AbstractListenerMethodsTestBase;
+import com.vaadin.ui.CssLayout;
+
+public class CssLayoutListenersTest extends AbstractListenerMethodsTestBase {
+ public void testLayoutClickListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(CssLayout.class, LayoutClickEvent.class,
+ LayoutClickListener.class);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/customlayout/CustomLayoutDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/customlayout/CustomLayoutDeclarativeTest.java
new file mode 100644
index 0000000000..6ee3490c05
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/customlayout/CustomLayoutDeclarativeTest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2000-2014 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.customlayout;
+
+import org.junit.Test;
+
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.CustomLayout;
+import com.vaadin.ui.Label;
+
+/**
+ * Tests declarative support for {@link CustomLayout}.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class CustomLayoutDeclarativeTest extends
+ DeclarativeTestBase<CustomLayout> {
+
+ @Test
+ public void testEmpty() {
+ String design = "<vaadin-custom-layout>";
+ CustomLayout expected = new CustomLayout();
+ test(design, expected);
+ }
+
+ @Test
+ public void testWithChildren() {
+ String design = "<vaadin-custom-layout>" + //
+ "<vaadin-button plain-text :location='b'></vaadin-button>" + //
+ "<vaadin-label plain-text :location='l'></vaadin-label>" + //
+ "</vaadin-custom-layout>";
+
+ CustomLayout expected = new CustomLayout();
+ expected.addComponent(new Button(), "b");
+ expected.addComponent(new Label(), "l");
+
+ test(design, expected);
+ }
+
+ @Test
+ public void testWithOneChild() {
+ String design = "<vaadin-custom-layout><vaadin-button plain-text></vaadin-button></vaadin-custom-layout>";
+
+ CustomLayout expected = new CustomLayout();
+ expected.addComponent(new Button());
+
+ test(design, expected);
+ }
+
+ @Test
+ public void testWithTemplate() {
+ String design = "<vaadin-custom-layout template-name='template.html'></vaadin-custom-layout>";
+ CustomLayout expected = new CustomLayout("template.html");
+ test(design, expected);
+ }
+
+ @Test
+ public void testWithDuplicateLocations() {
+ String design = "<vaadin-custom-layout>" + //
+ "<vaadin-button plain-text :location='foo'></vaadin-button>" + //
+ "<vaadin-label plain-text :location='foo'></vaadin-label>" + //
+ "</vaadin-custom-layout>";
+
+ CustomLayout expected = new CustomLayout();
+ expected.addComponent(new Button(), "foo");
+ expected.addComponent(new Label(), "foo");
+
+ testRead(design, expected);
+
+ String written = "<vaadin-custom-layout>" + //
+ "<vaadin-label plain-text :location='foo'></vaadin-label>" + //
+ "</vaadin-custom-layout>";
+
+ testWrite(written, expected);
+ }
+
+ protected void test(String design, CustomLayout expected) {
+ testRead(design, expected);
+ testWrite(design, expected);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/customlayout/CustomLayoutTest.java b/server/src/test/java/com/vaadin/tests/server/component/customlayout/CustomLayoutTest.java
new file mode 100644
index 0000000000..4d327e70a6
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/customlayout/CustomLayoutTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2000-2014 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.customlayout;
+
+import java.io.ByteArrayInputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.ui.CustomLayout;
+
+/**
+ *
+ * Tests for {@link CustomLayout}
+ *
+ * @author Vaadin Ltd
+ */
+public class CustomLayoutTest {
+
+ @Test
+ public void ctor_inputStreamProvided_inputStreamIsRead()
+ throws IOException, IllegalArgumentException,
+ IllegalAccessException {
+ Integer buffer = getBufferSize();
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < buffer; i++) {
+ builder.append('a');
+ }
+ byte[] bytes = builder.toString().getBytes(Charset.forName("UTF-8"));
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ InputStreamImpl stream = new InputStreamImpl(inputStream, buffer / 2);
+ new CustomLayout(stream);
+
+ Assert.assertTrue("Stream is not closed in CustomLayout CTOR ",
+ stream.isClosed());
+ Assert.assertEquals("Number of read bytes is incorrect", bytes.length,
+ stream.getCount());
+ }
+
+ private Integer getBufferSize() throws IllegalAccessException {
+ Field[] fields = CustomLayout.class.getDeclaredFields();
+ List<Field> list = new ArrayList<Field>(fields.length);
+ for (Field field : fields) {
+ if ((field.getModifiers() & Modifier.STATIC) > 0) {
+ list.add(field);
+ }
+ }
+ Field field = null;
+ if (list.size() == 1) {
+ field = list.get(0);
+ } else {
+ for (Field fld : list) {
+ if (fld.getName().toLowerCase(Locale.ENGLISH)
+ .startsWith("buffer")) {
+ field = fld;
+ break;
+ }
+ }
+ }
+ Assert.assertNotNull(
+ "Unable to find default buffer size in CustomLayout class",
+ field);
+ field.setAccessible(true);
+ Integer buffer = (Integer) field.get(null);
+ return buffer;
+ }
+
+ private static class InputStreamImpl extends FilterInputStream {
+
+ InputStreamImpl(InputStream inputStream, int maxArrayLength) {
+ super(inputStream);
+ this.maxArrayLength = maxArrayLength;
+ }
+
+ @Override
+ public int read() throws IOException {
+ int read = super.read();
+ if (read != -1) {
+ readCount++;
+ }
+ return read;
+ }
+
+ @Override
+ public int read(byte[] b) throws IOException {
+ if (b.length > maxArrayLength) {
+ return read(b, 0, maxArrayLength);
+ }
+ int count = super.read(b);
+ if (count != -1) {
+ readCount += count;
+ }
+ return count;
+ }
+
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ if (len > maxArrayLength) {
+ return read(b, off, maxArrayLength);
+ }
+ int count = super.read(b, off, len);
+ if (count != -1) {
+ readCount += count;
+ }
+ return count;
+ }
+
+ @Override
+ public void close() throws IOException {
+ isClosed = true;
+ super.close();
+ }
+
+ int getCount() {
+ return readCount;
+ }
+
+ boolean isClosed() {
+ return isClosed;
+ }
+
+ private int readCount;
+ private boolean isClosed;
+ private int maxArrayLength;
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldConverterTest.java b/server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldConverterTest.java
new file mode 100644
index 0000000000..f5467b2d18
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldConverterTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2000-2014 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.datefield;
+
+import java.util.Date;
+import java.util.Locale;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.Property;
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.data.util.converter.Converter;
+import com.vaadin.shared.ui.datefield.Resolution;
+import com.vaadin.ui.DateField;
+
+public class DateFieldConverterTest extends TestCase {
+
+ private Property<Long> date;
+ private DateField datefield;
+
+ @Override
+ public void setUp() {
+ date = new ObjectProperty<Long>(0L);
+ datefield = new DateField();
+ datefield.setBuffered(false);
+ datefield.setConverter(new Converter<Date, Long>() {
+
+ @Override
+ public Long convertToModel(Date value,
+ Class<? extends Long> targetType, Locale locale)
+ throws ConversionException {
+ return value.getTime();
+ }
+
+ @Override
+ public Date convertToPresentation(Long value,
+ Class<? extends Date> targetType, Locale locale)
+ throws ConversionException {
+ return new Date(value);
+ }
+
+ @Override
+ public Class<Long> getModelType() {
+ return Long.class;
+ }
+
+ @Override
+ public Class<Date> getPresentationType() {
+ return Date.class;
+ }
+ });
+ datefield.setPropertyDataSource(date);
+ }
+
+ /*
+ * See #12193.
+ */
+ public void testResolution() {
+ datefield.setValue(new Date(110, 0, 1));
+ datefield.setResolution(Resolution.MINUTE);
+ datefield.validate();
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldDeclarativeTest.java
new file mode 100644
index 0000000000..54ac9a3a4b
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldDeclarativeTest.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2000-2014 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.datefield;
+
+import java.util.Date;
+import java.util.TimeZone;
+
+import org.junit.Test;
+
+import com.vaadin.shared.ui.datefield.Resolution;
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.DateField;
+
+/**
+ * Tests the declarative support for implementations of {@link DateField}.
+ *
+ * @since 7.4
+ * @author Vaadin Ltd
+ */
+public class DateFieldDeclarativeTest extends DeclarativeTestBase<DateField> {
+
+ private String getYearResolutionDesign() {
+ return "<vaadin-date-field resolution='year' value='2020'/>";
+ }
+
+ private DateField getYearResolutionExpected() {
+ DateField df = new DateField();
+ df.setResolution(Resolution.YEAR);
+ df.setValue(new Date(2020 - 1900, 1 - 1, 1));
+ return df;
+ }
+
+ private String getTimezoneDesign() {
+ return "<vaadin-date-field range-start=\"2014-05-05 00:00:00+0300\" range-end=\"2014-06-05 00:00:00+0300\" date-out-of-range-message=\"Please select a sensible date\" date-format=\"yyyy-MM-dd\" lenient show-iso-week-numbers parse-error-message=\"You are doing it wrong\" time-zone=\"GMT+05:00\" value=\"2014-05-15 00:00:00+0300\"/>";
+ }
+
+ private DateField getTimezoneExpected() {
+ DateField df = new DateField();
+
+ df.setRangeStart(new Date(2014 - 1900, 5 - 1, 5));
+ df.setRangeEnd(new Date(2014 - 1900, 6 - 1, 5));
+ df.setDateOutOfRangeMessage("Please select a sensible date");
+ df.setResolution(Resolution.DAY);
+ df.setDateFormat("yyyy-MM-dd");
+ df.setLenient(true);
+ df.setShowISOWeekNumbers(true);
+ df.setParseErrorMessage("You are doing it wrong");
+ df.setTimeZone(TimeZone.getTimeZone("GMT+5"));
+ df.setValue(new Date(2014 - 1900, 5 - 1, 15));
+
+ return df;
+ }
+
+ @Test
+ public void readTimezone() {
+ testRead(getTimezoneDesign(), getTimezoneExpected());
+ }
+
+ @Test
+ public void writeTimezone() {
+ testWrite(getTimezoneDesign(), getTimezoneExpected());
+ }
+
+ @Test
+ public void readYearResolution() {
+ testRead(getYearResolutionDesign(), getYearResolutionExpected());
+ }
+
+ @Test
+ public void writeYearResolution() {
+ // Writing is always done in full resolution..
+ testWrite(
+ getYearResolutionDesign().replace("2020",
+ "2020-01-01 00:00:00+0200"),
+ getYearResolutionExpected());
+ }
+
+ @Test
+ public void testReadOnlyValue() {
+ String design = "<vaadin-date-field readonly resolution='year' value='2020-01-01 00:00:00+0200'/>";
+ DateField df = new DateField();
+ df.setResolution(Resolution.YEAR);
+ df.setValue(new Date(2020 - 1900, 1 - 1, 1));
+ df.setReadOnly(true);
+
+ testRead(design, df);
+ testWrite(design, df);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldListenersTest.java
new file mode 100644
index 0000000000..6d774366a9
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldListenersTest.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.AbstractListenerMethodsTestBase;
+import com.vaadin.ui.DateField;
+
+public class DateFieldListenersTest extends AbstractListenerMethodsTestBase {
+ 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/src/test/java/com/vaadin/tests/server/component/datefield/InlineDateFieldDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/datefield/InlineDateFieldDeclarativeTest.java
new file mode 100644
index 0000000000..04468c658a
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/datefield/InlineDateFieldDeclarativeTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2000-2014 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.datefield;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.text.SimpleDateFormat;
+
+import org.junit.Test;
+
+import com.vaadin.shared.ui.datefield.Resolution;
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.DateField;
+import com.vaadin.ui.InlineDateField;
+import com.vaadin.ui.declarative.Design;
+
+/**
+ * Tests the declarative support for implementations of {@link DateField}.
+ *
+ * @since 7.4
+ * @author Vaadin Ltd
+ */
+public class InlineDateFieldDeclarativeTest extends
+ DeclarativeTestBase<InlineDateField> {
+
+ @Test
+ public void testInlineDateFieldToFromDesign() throws Exception {
+ InlineDateField field = new InlineDateField("Day is",
+ new SimpleDateFormat("yyyy-MM-dd").parse("2003-02-27"));
+ field.setResolution(Resolution.DAY);
+ field.setShowISOWeekNumbers(true);
+ field.setRangeStart(new SimpleDateFormat("yyyy-MM-dd")
+ .parse("2001-02-27"));
+ field.setRangeEnd(new SimpleDateFormat("yyyy-MM-dd")
+ .parse("2011-02-27"));
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ Design.write(field, bos);
+
+ InlineDateField result = (InlineDateField) Design
+ .read(new ByteArrayInputStream(bos.toByteArray()));
+ assertEquals(field.getResolution(), result.getResolution());
+ assertEquals(field.getCaption(), result.getCaption());
+ assertEquals(field.getValue(), result.getValue());
+ assertEquals(field.getRangeStart(), result.getRangeStart());
+ assertEquals(field.getRangeEnd(), result.getRangeEnd());
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/datefield/PopupDateFieldDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/datefield/PopupDateFieldDeclarativeTest.java
new file mode 100644
index 0000000000..b637d10c9e
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/datefield/PopupDateFieldDeclarativeTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2000-2014 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.datefield;
+
+import java.util.Date;
+
+import org.junit.Test;
+
+import com.vaadin.shared.ui.datefield.Resolution;
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.DateField;
+import com.vaadin.ui.PopupDateField;
+
+/**
+ * Tests the declarative support for implementations of {@link DateField}.
+ *
+ * @since 7.4
+ * @author Vaadin Ltd
+ */
+public class PopupDateFieldDeclarativeTest extends
+ DeclarativeTestBase<PopupDateField> {
+
+ private String getBasicDesign() {
+ return "<vaadin-popup-date-field assistive-text='at' text-field-enabled='false' show-iso-week-numbers resolution=\"MINUTE\" range-end=\"2019-01-15\" input-prompt=\"Pick a day\" value=\"2003-02-27 07:15\"></vaadin-popup-date-field>";
+ }
+
+ private PopupDateField getBasicExpected() {
+ PopupDateField pdf = new PopupDateField();
+ pdf.setShowISOWeekNumbers(true);
+ pdf.setResolution(Resolution.MINUTE);
+ pdf.setRangeEnd(new Date(2019 - 1900, 1 - 1, 15));
+ pdf.setInputPrompt("Pick a day");
+ pdf.setValue(new Date(2003 - 1900, 2 - 1, 27, 7, 15));
+ pdf.setTextFieldEnabled(false);
+ pdf.setAssistiveText("at");
+ return pdf;
+ }
+
+ @Test
+ public void readBasic() throws Exception {
+ testRead(getBasicDesign(), getBasicExpected());
+ }
+
+ @Test
+ public void writeBasic() throws Exception {
+ testRead(getBasicDesign(), getBasicExpected());
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/datefield/ResolutionTest.java b/server/src/test/java/com/vaadin/tests/server/component/datefield/ResolutionTest.java
new file mode 100644
index 0000000000..ae72f9c743
--- /dev/null
+++ b/server/src/test/java/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.shared.ui.datefield.Resolution;
+import com.vaadin.tests.util.TestUtil;
+
+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/src/test/java/com/vaadin/tests/server/component/embedded/EmbeddedListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/embedded/EmbeddedListenersTest.java
new file mode 100644
index 0000000000..b41d5e9e13
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/embedded/EmbeddedListenersTest.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.AbstractListenerMethodsTestBase;
+import com.vaadin.ui.Embedded;
+
+public class EmbeddedListenersTest extends AbstractListenerMethodsTestBase {
+ public void testClickListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Embedded.class, ClickEvent.class,
+ ClickListener.class);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/fieldgroup/BeanFieldGroupTest.java b/server/src/test/java/com/vaadin/tests/server/component/fieldgroup/BeanFieldGroupTest.java
new file mode 100644
index 0000000000..90c079b35c
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/fieldgroup/BeanFieldGroupTest.java
@@ -0,0 +1,171 @@
+package com.vaadin.tests.server.component.fieldgroup;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.Item;
+import com.vaadin.data.fieldgroup.BeanFieldGroup;
+import com.vaadin.data.fieldgroup.FieldGroup.CommitException;
+import com.vaadin.data.fieldgroup.PropertyId;
+import com.vaadin.data.util.BeanItem;
+import com.vaadin.ui.Field;
+import com.vaadin.ui.RichTextArea;
+import com.vaadin.ui.TextField;
+
+public class BeanFieldGroupTest {
+
+ private static final String DEFAULT_FOR_BASIC_FIELD = "default";
+
+ public static class MyBean {
+
+ private String basicField = DEFAULT_FOR_BASIC_FIELD;
+
+ private String anotherField;
+
+ private MyNestedBean nestedBean = new MyNestedBean();
+
+ public MyNestedBean getNestedBean() {
+ return nestedBean;
+ }
+
+ /**
+ * @return the basicField
+ */
+ public String getBasicField() {
+ return basicField;
+ }
+
+ /**
+ * @param basicField
+ * the basicField to set
+ */
+ public void setBasicField(String basicField) {
+ this.basicField = basicField;
+ }
+
+ /**
+ * @return the anotherField
+ */
+ public String getAnotherField() {
+ return anotherField;
+ }
+
+ /**
+ * @param anotherField
+ * the anotherField to set
+ */
+ public void setAnotherField(String anotherField) {
+ this.anotherField = anotherField;
+ }
+ }
+
+ public static class MyNestedBean {
+
+ private String hello = "Hello world";
+
+ public String getHello() {
+ return hello;
+ }
+ }
+
+ public static class ViewStub {
+
+ TextField basicField = new TextField();
+
+ @PropertyId("anotherField")
+ TextField boundWithAnnotation = new TextField();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testStaticBindingHelper() {
+ MyBean myBean = new MyBean();
+
+ ViewStub viewStub = new ViewStub();
+ BeanFieldGroup<MyBean> bindFields = BeanFieldGroup
+ .bindFieldsUnbuffered(myBean, viewStub);
+
+ Field<String> field = (Field<String>) bindFields.getField("basicField");
+ Assert.assertEquals(DEFAULT_FOR_BASIC_FIELD, myBean.basicField);
+ field.setValue("Foo");
+ Assert.assertEquals("Foo", myBean.basicField);
+
+ field = (Field<String>) bindFields.getField("anotherField");
+ field.setValue("Foo");
+ Assert.assertEquals("Foo", myBean.anotherField);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testStaticBufferedBindingHelper() throws CommitException {
+ MyBean myBean = new MyBean();
+
+ ViewStub viewStub = new ViewStub();
+ BeanFieldGroup<MyBean> bindFields = BeanFieldGroup.bindFieldsBuffered(
+ myBean, viewStub);
+
+ Field<String> basicField = (Field<String>) bindFields
+ .getField("basicField");
+ basicField.setValue("Foo");
+ Assert.assertEquals(DEFAULT_FOR_BASIC_FIELD, myBean.basicField);
+
+ Field<String> anotherField = (Field<String>) bindFields
+ .getField("anotherField");
+ anotherField.setValue("Foo");
+ Assert.assertNull(myBean.anotherField);
+
+ bindFields.commit();
+
+ Assert.assertEquals("Foo", myBean.basicField);
+ Assert.assertEquals("Foo", myBean.anotherField);
+
+ }
+
+ @Test
+ public void buildAndBindNestedProperty() {
+
+ MyBean bean = new MyBean();
+
+ BeanFieldGroup<MyBean> bfg = new BeanFieldGroup<MyBean>(MyBean.class);
+ bfg.setItemDataSource(bean);
+
+ com.vaadin.ui.Field<?> helloField = bfg.buildAndBind("Hello string",
+ "nestedBean.hello");
+ assertEquals(bean.nestedBean.hello, helloField.getValue().toString());
+ }
+
+ @Test
+ public void buildAndBindNestedRichTextAreaProperty() {
+
+ MyBean bean = new MyBean();
+
+ BeanFieldGroup<MyBean> bfg = new BeanFieldGroup<MyBean>(MyBean.class);
+ bfg.setItemDataSource(bean);
+
+ RichTextArea helloField = bfg.buildAndBind("Hello string",
+ "nestedBean.hello", RichTextArea.class);
+ assertEquals(bean.nestedBean.hello, helloField.getValue().toString());
+ }
+
+ @Test
+ public void setDataSource_nullBean_nullBeanIsSetInDataSource() {
+ BeanFieldGroup<MyBean> group = new BeanFieldGroup<MyBean>(MyBean.class);
+
+ group.setItemDataSource((MyBean) null);
+
+ BeanItem<MyBean> dataSource = group.getItemDataSource();
+ Assert.assertNull("Data source is null for null bean", dataSource);
+ }
+
+ @Test
+ public void setDataSource_nullItem_nullDataSourceIsSet() {
+ BeanFieldGroup<MyBean> group = new BeanFieldGroup<MyBean>(MyBean.class);
+
+ group.setItemDataSource((Item) null);
+ BeanItem<MyBean> dataSource = group.getItemDataSource();
+ Assert.assertNull("Group returns not null data source", dataSource);
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/fieldgroup/CaseInsensitiveBindingTest.java b/server/src/test/java/com/vaadin/tests/server/component/fieldgroup/CaseInsensitiveBindingTest.java
new file mode 100644
index 0000000000..cb29a84aa8
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/fieldgroup/CaseInsensitiveBindingTest.java
@@ -0,0 +1,85 @@
+package com.vaadin.tests.server.component.fieldgroup;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import com.vaadin.data.fieldgroup.FieldGroup;
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.data.util.PropertysetItem;
+import com.vaadin.ui.FormLayout;
+import com.vaadin.ui.TextField;
+
+public class CaseInsensitiveBindingTest {
+
+ @Test
+ public void caseInsensitivityAndUnderscoreRemoval() {
+ PropertysetItem item = new PropertysetItem();
+ item.addItemProperty("LastName", new ObjectProperty<String>("Sparrow"));
+
+ class MyForm extends FormLayout {
+ TextField lastName = new TextField("Last name");
+
+ public MyForm() {
+
+ // Should bind to the LastName property
+ addComponent(lastName);
+ }
+ }
+
+ MyForm form = new MyForm();
+
+ FieldGroup binder = new FieldGroup(item);
+ binder.bindMemberFields(form);
+
+ assertTrue("Sparrow".equals(form.lastName.getValue()));
+ }
+
+ @Test
+ public void UnderscoreRemoval() {
+ PropertysetItem item = new PropertysetItem();
+ item.addItemProperty("first_name", new ObjectProperty<String>("Jack"));
+
+ class MyForm extends FormLayout {
+ TextField firstName = new TextField("First name");
+
+ public MyForm() {
+ // Should bind to the first_name property
+ addComponent(firstName);
+ }
+ }
+
+ MyForm form = new MyForm();
+
+ FieldGroup binder = new FieldGroup(item);
+ binder.bindMemberFields(form);
+
+ assertTrue("Jack".equals(form.firstName.getValue()));
+ }
+
+ @Test
+ public void perfectMatchPriority() {
+ PropertysetItem item = new PropertysetItem();
+ item.addItemProperty("first_name", new ObjectProperty<String>(
+ "Not this"));
+ item.addItemProperty("firstName", new ObjectProperty<String>("This"));
+
+ class MyForm extends FormLayout {
+ TextField firstName = new TextField("First name");
+
+ public MyForm() {
+ // should bind to the firstName property, not first_name
+ // property
+ addComponent(firstName);
+ }
+ }
+
+ MyForm form = new MyForm();
+
+ FieldGroup binder = new FieldGroup(item);
+ binder.bindMemberFields(form);
+
+ assertTrue("This".equals(form.firstName.getValue()));
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/fieldgroup/FieldGroupTest.java b/server/src/test/java/com/vaadin/tests/server/component/fieldgroup/FieldGroupTest.java
new file mode 100644
index 0000000000..d77a2e190b
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/fieldgroup/FieldGroupTest.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2000-2014 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.fieldgroup;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.Item;
+import com.vaadin.data.Property;
+import com.vaadin.data.Validator.InvalidValueException;
+import com.vaadin.data.fieldgroup.FieldGroup;
+import com.vaadin.data.fieldgroup.FieldGroup.CommitException;
+import com.vaadin.data.util.AbstractProperty;
+import com.vaadin.ui.Field;
+import com.vaadin.ui.TextField;
+
+/**
+ *
+ * Tests for {@link FieldGroup}.
+ *
+ * @author Vaadin Ltd
+ */
+public class FieldGroupTest {
+
+ @Test
+ public void setReadOnly_readOnlyAndNoDataSource_fieldIsReadOnly() {
+ FieldGroup fieldGroup = new FieldGroup();
+
+ TextField field = new TextField();
+ fieldGroup.bind(field, "property");
+
+ fieldGroup.setReadOnly(true);
+
+ Assert.assertTrue("Field is not read only", field.isReadOnly());
+ }
+
+ @Test
+ public void setReadOnly_writableAndNoDataSource_fieldIsWritable() {
+ FieldGroup fieldGroup = new FieldGroup();
+
+ TextField field = new TextField();
+ fieldGroup.bind(field, "property");
+
+ fieldGroup.setReadOnly(false);
+
+ Assert.assertFalse("Field is not writable", field.isReadOnly());
+ }
+
+ @Test
+ public void commit_validationFailed_allValidationFailuresAvailable()
+ throws CommitException {
+ FieldGroup fieldGroup = new FieldGroup();
+
+ fieldGroup.setItemDataSource(new TestItem());
+
+ TextField field1 = new TextField();
+ field1.setRequired(true);
+ fieldGroup.bind(field1, "prop1");
+
+ TextField field2 = new TextField();
+ field2.setRequired(true);
+ fieldGroup.bind(field2, "prop2");
+
+ Set<TextField> set = new HashSet<TextField>(Arrays.asList(field1,
+ field2));
+
+ try {
+ fieldGroup.commit();
+ Assert.fail("No commit exception is thrown");
+ } catch (CommitException exception) {
+ Map<Field<?>, ? extends InvalidValueException> invalidFields = exception
+ .getInvalidFields();
+ for (Entry<Field<?>, ? extends InvalidValueException> entry : invalidFields
+ .entrySet()) {
+ set.remove(entry.getKey());
+ }
+ Assert.assertEquals(
+ "Some fields are not found in the invalid fields map", 0,
+ set.size());
+ Assert.assertEquals(
+ "Invalid value exception should be thrown for each field",
+ 2, invalidFields.size());
+ }
+ }
+
+ private static class TestItem implements Item {
+
+ @Override
+ public Property<String> getItemProperty(Object id) {
+ return new StringProperty();
+ }
+
+ @Override
+ public Collection<?> getItemPropertyIds() {
+ return Arrays.asList("prop1", "prop2");
+ }
+
+ @Override
+ public boolean addItemProperty(Object id, Property property)
+ throws UnsupportedOperationException {
+ return false;
+ }
+
+ @Override
+ public boolean removeItemProperty(Object id)
+ throws UnsupportedOperationException {
+ return false;
+ }
+
+ }
+
+ private static class StringProperty extends AbstractProperty<String> {
+
+ @Override
+ public String getValue() {
+ return null;
+ }
+
+ @Override
+ public void setValue(String newValue) throws Property.ReadOnlyException {
+ }
+
+ @Override
+ public Class<? extends String> getType() {
+ return String.class;
+ }
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/fieldgroup/FieldGroupWithReadOnlyPropertiesTest.java b/server/src/test/java/com/vaadin/tests/server/component/fieldgroup/FieldGroupWithReadOnlyPropertiesTest.java
new file mode 100644
index 0000000000..60a92d7d73
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/fieldgroup/FieldGroupWithReadOnlyPropertiesTest.java
@@ -0,0 +1,51 @@
+package com.vaadin.tests.server.component.fieldgroup;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import com.vaadin.data.fieldgroup.FieldGroup;
+import com.vaadin.data.util.BeanItem;
+import com.vaadin.tests.data.bean.BeanWithReadOnlyField;
+import com.vaadin.ui.TextField;
+
+public class FieldGroupWithReadOnlyPropertiesTest {
+
+ private TextField readOnlyField = new TextField();
+ private TextField writableField = new TextField();
+
+ @Test
+ public void bindReadOnlyPropertyToFieldGroup() {
+ BeanWithReadOnlyField bean = new BeanWithReadOnlyField();
+ BeanItem<BeanWithReadOnlyField> beanItem = new BeanItem<BeanWithReadOnlyField>(
+ bean);
+ beanItem.getItemProperty("readOnlyField").setReadOnly(true);
+
+ FieldGroup fieldGroup = new FieldGroup(beanItem);
+ fieldGroup.bindMemberFields(this);
+
+ assertTrue(readOnlyField.isReadOnly());
+ assertFalse(writableField.isReadOnly());
+ }
+
+ @Test
+ public void fieldGroupSetReadOnlyTest() {
+ BeanWithReadOnlyField bean = new BeanWithReadOnlyField();
+ BeanItem<BeanWithReadOnlyField> beanItem = new BeanItem<BeanWithReadOnlyField>(
+ bean);
+ beanItem.getItemProperty("readOnlyField").setReadOnly(true);
+
+ FieldGroup fieldGroup = new FieldGroup(beanItem);
+ fieldGroup.bindMemberFields(this);
+
+ fieldGroup.setReadOnly(true);
+ assertTrue(readOnlyField.isReadOnly());
+ assertTrue(writableField.isReadOnly());
+
+ fieldGroup.setReadOnly(false);
+ assertTrue(readOnlyField.isReadOnly());
+ assertFalse(writableField.isReadOnly());
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/fieldgroup/FieldNamedDescriptionTest.java b/server/src/test/java/com/vaadin/tests/server/component/fieldgroup/FieldNamedDescriptionTest.java
new file mode 100644
index 0000000000..029dcc66a3
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/fieldgroup/FieldNamedDescriptionTest.java
@@ -0,0 +1,53 @@
+package com.vaadin.tests.server.component.fieldgroup;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import com.vaadin.data.fieldgroup.FieldGroup;
+import com.vaadin.data.fieldgroup.PropertyId;
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.data.util.PropertysetItem;
+import com.vaadin.ui.FormLayout;
+import com.vaadin.ui.TextField;
+
+public class FieldNamedDescriptionTest {
+
+ @Test
+ public void bindReadOnlyPropertyToFieldGroup() {
+ // Create an item
+ PropertysetItem item = new PropertysetItem();
+ item.addItemProperty("name", new ObjectProperty<String>("Zaphod"));
+ item.addItemProperty("description", new ObjectProperty<String>(
+ "This is a description"));
+
+ // Define a form as a class that extends some layout
+ class MyForm extends FormLayout {
+ // Member that will bind to the "name" property
+ TextField name = new TextField("Name");
+
+ // This member will not bind to the desctiptionProperty as the name
+ // description conflicts with something in the binding process
+ @PropertyId("description")
+ TextField description = new TextField("Description");
+
+ public MyForm() {
+
+ // Add the fields
+ addComponent(name);
+ addComponent(description);
+ }
+ }
+
+ // Create one
+ MyForm form = new MyForm();
+
+ // Now create a binder that can also creates the fields
+ // using the default field factory
+ FieldGroup binder = new FieldGroup(item);
+ binder.bindMemberFields(form);
+
+ assertTrue(form.description.getValue().equals("This is a description"));
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/flash/FlashDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/flash/FlashDeclarativeTest.java
new file mode 100644
index 0000000000..0c2deaaf0a
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/flash/FlashDeclarativeTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2000-2014 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.flash;
+
+import org.junit.Test;
+
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.AbstractEmbedded;
+import com.vaadin.ui.Embedded;
+import com.vaadin.ui.Flash;
+
+/**
+ * Tests declarative support for implementations of {@link AbstractEmbedded} and
+ * {@link Embedded}.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class FlashDeclarativeTest extends DeclarativeTestBase<Flash> {
+
+ protected Flash getExpectedResult() {
+ Flash f = new Flash();
+ f.setArchive("arch");
+ f.setCodebase("foo");
+ f.setCodetype("bar");
+ f.setStandby("Please wait");
+ f.setParameter("foo", "bar");
+ f.setParameter("baz", "foo");
+ return f;
+ };
+
+ protected String getDesign() {
+ return "<vaadin-flash standby='Please wait' archive='arch' codebase='foo' codetype='bar' >"
+ + " <parameter name='baz' value='foo' />\n" //
+ + " <parameter name='foo' value='bar' />\n" //
+ + "</vaadin-flash>"; //
+ }
+
+ @Test
+ public void read() {
+ testRead(getDesign(), getExpectedResult());
+ }
+
+ @Test
+ public void write() {
+ testWrite(getDesign(), getExpectedResult());
+ }
+
+ @Test
+ public void testEmpty() {
+ testRead("<vaadin-flash />", new Flash());
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/form/FormTest.java b/server/src/test/java/com/vaadin/tests/server/component/form/FormTest.java
new file mode 100644
index 0000000000..2075f7b115
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/form/FormTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2000-2014 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.form;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.ui.Form;
+import com.vaadin.ui.TextField;
+
+/**
+ * Test for {@link Form}.
+ *
+ * @author Vaadin Ltd
+ */
+public class FormTest {
+
+ @Test
+ public void testFocus() {
+ Form form = new Form();
+ final boolean firstFieldIsFocused[] = new boolean[1];
+ TextField field1 = new TextField() {
+ @Override
+ public boolean isConnectorEnabled() {
+ return false;
+ }
+
+ @Override
+ public void focus() {
+ firstFieldIsFocused[0] = true;
+ }
+ };
+
+ final boolean secondFieldIsFocused[] = new boolean[1];
+ TextField field2 = new TextField() {
+ @Override
+ public boolean isConnectorEnabled() {
+ return true;
+ }
+
+ @Override
+ public void focus() {
+ secondFieldIsFocused[0] = true;
+ }
+ };
+ form.addField("a", field1);
+ form.addField("b", field2);
+ form.focus();
+
+ Assert.assertTrue("Field with enabled connector is not focused",
+ secondFieldIsFocused[0]);
+ Assert.assertFalse("Field with disabled connector is focused",
+ firstFieldIsFocused[0]);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/GridAddRowBuiltinContainerTest.java b/server/src/test/java/com/vaadin/tests/server/component/grid/GridAddRowBuiltinContainerTest.java
new file mode 100644
index 0000000000..70c73eb516
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/grid/GridAddRowBuiltinContainerTest.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright 2000-2014 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.grid;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.Container;
+import com.vaadin.data.Item;
+import com.vaadin.data.util.BeanItem;
+import com.vaadin.data.util.BeanItemContainer;
+import com.vaadin.data.util.MethodProperty.MethodException;
+import com.vaadin.tests.data.bean.Person;
+import com.vaadin.ui.Grid;
+
+public class GridAddRowBuiltinContainerTest {
+ Grid grid = new Grid();
+ Container.Indexed container;
+
+ @Before
+ public void setUp() {
+ container = grid.getContainerDataSource();
+
+ grid.addColumn("myColumn");
+ }
+
+ @Test
+ public void testSimpleCase() {
+ Object itemId = grid.addRow("Hello");
+
+ Assert.assertEquals(Integer.valueOf(1), itemId);
+
+ Assert.assertEquals("There should be one item in the container", 1,
+ container.size());
+
+ Assert.assertEquals("Hello",
+ container.getItem(itemId).getItemProperty("myColumn")
+ .getValue());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testNullParameter() {
+ // cast to Object[] to distinguish from one null varargs value
+ grid.addRow((Object[]) null);
+ }
+
+ @Test
+ public void testNullValue() {
+ // cast to Object to distinguish from a null varargs array
+ Object itemId = grid.addRow((Object) null);
+
+ Assert.assertEquals(null,
+ container.getItem(itemId).getItemProperty("myColumn")
+ .getValue());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testAddInvalidType() {
+ grid.addRow(Integer.valueOf(5));
+ }
+
+ @Test
+ public void testMultipleProperties() {
+ grid.addColumn("myOther", Integer.class);
+
+ Object itemId = grid.addRow("Hello", Integer.valueOf(3));
+
+ Item item = container.getItem(itemId);
+ Assert.assertEquals("Hello", item.getItemProperty("myColumn")
+ .getValue());
+ Assert.assertEquals(Integer.valueOf(3), item.getItemProperty("myOther")
+ .getValue());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testInvalidPropertyAmount() {
+ grid.addRow("Hello", Integer.valueOf(3));
+ }
+
+ @Test
+ public void testRemovedColumn() {
+ grid.addColumn("myOther", Integer.class);
+ grid.removeColumn("myColumn");
+
+ grid.addRow(Integer.valueOf(3));
+
+ Item item = container.getItem(Integer.valueOf(1));
+ Assert.assertEquals("Default value should be used for removed column",
+ "", item.getItemProperty("myColumn").getValue());
+ Assert.assertEquals(Integer.valueOf(3), item.getItemProperty("myOther")
+ .getValue());
+ }
+
+ @Test
+ public void testMultiplePropertiesAfterReorder() {
+ grid.addColumn("myOther", Integer.class);
+
+ grid.setColumnOrder("myOther", "myColumn");
+
+ grid.addRow(Integer.valueOf(3), "Hello");
+
+ Item item = container.getItem(Integer.valueOf(1));
+ Assert.assertEquals("Hello", item.getItemProperty("myColumn")
+ .getValue());
+ Assert.assertEquals(Integer.valueOf(3), item.getItemProperty("myOther")
+ .getValue());
+ }
+
+ @Test
+ public void testInvalidType_NothingAdded() {
+ try {
+ grid.addRow(Integer.valueOf(5));
+
+ // Can't use @Test(expect = Foo.class) since we also want to verify
+ // state after exception was thrown
+ Assert.fail("Adding wrong type should throw ClassCastException");
+ } catch (IllegalArgumentException e) {
+ Assert.assertEquals("No row should have been added", 0,
+ container.size());
+ }
+ }
+
+ @Test
+ public void testUnsupportingContainer() {
+ setContainerRemoveColumns(new BeanItemContainer<Person>(Person.class));
+ try {
+
+ grid.addRow("name");
+
+ // Can't use @Test(expect = Foo.class) since we also want to verify
+ // state after exception was thrown
+ Assert.fail("Adding to BeanItemContainer container should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ Assert.assertEquals("No row should have been added", 0,
+ container.size());
+ }
+ }
+
+ @Test
+ public void testCustomContainer() {
+ BeanItemContainer<Person> container = new BeanItemContainer<Person>(
+ Person.class) {
+ @Override
+ public Object addItem() {
+ BeanItem<Person> item = addBean(new Person());
+ return getBeanIdResolver().getIdForBean(item.getBean());
+ }
+ };
+
+ setContainerRemoveColumns(container);
+
+ grid.addRow("name");
+
+ Assert.assertEquals(1, container.size());
+
+ Assert.assertEquals("name", container.getIdByIndex(0).getFirstName());
+ }
+
+ @Test
+ public void testSetterThrowing() {
+ BeanItemContainer<Person> container = new BeanItemContainer<Person>(
+ Person.class) {
+ @Override
+ public Object addItem() {
+ BeanItem<Person> item = addBean(new Person() {
+ @Override
+ public void setFirstName(String firstName) {
+ if ("name".equals(firstName)) {
+ throw new RuntimeException(firstName);
+ } else {
+ super.setFirstName(firstName);
+ }
+ }
+ });
+ return getBeanIdResolver().getIdForBean(item.getBean());
+ }
+ };
+
+ setContainerRemoveColumns(container);
+
+ try {
+
+ grid.addRow("name");
+
+ // Can't use @Test(expect = Foo.class) since we also want to verify
+ // state after exception was thrown
+ Assert.fail("Adding row should throw MethodException");
+ } catch (MethodException e) {
+ Assert.assertEquals("Got the wrong exception", "name", e.getCause()
+ .getMessage());
+
+ Assert.assertEquals("There should be no rows in the container", 0,
+ container.size());
+ }
+ }
+
+ private void setContainerRemoveColumns(BeanItemContainer<Person> container) {
+ // Remove predefined column so we can change container
+ grid.removeAllColumns();
+ grid.setContainerDataSource(container);
+ grid.removeAllColumns();
+ grid.addColumn("firstName");
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/GridChildren.java b/server/src/test/java/com/vaadin/tests/server/component/grid/GridChildren.java
new file mode 100644
index 0000000000..7af1cfef69
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/grid/GridChildren.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2000-2014 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.grid;
+
+import java.util.Iterator;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.ui.Component;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.FooterCell;
+import com.vaadin.ui.Grid.HeaderCell;
+import com.vaadin.ui.Label;
+
+public class GridChildren {
+
+ @Test
+ public void componentsInMergedHeader() {
+ Grid grid = new Grid();
+ grid.addColumn("foo");
+ grid.addColumn("bar");
+ grid.addColumn("baz");
+ HeaderCell merged = grid.getDefaultHeaderRow()
+ .join("foo", "bar", "baz");
+ Label label = new Label();
+ merged.setComponent(label);
+ Iterator<Component> i = grid.iterator();
+ Assert.assertEquals(label, i.next());
+ Assert.assertFalse(i.hasNext());
+ }
+
+ @Test
+ public void componentsInMergedFooter() {
+ Grid grid = new Grid();
+ grid.addColumn("foo");
+ grid.addColumn("bar");
+ grid.addColumn("baz");
+ FooterCell merged = grid.addFooterRowAt(0).join("foo", "bar", "baz");
+ Label label = new Label();
+ merged.setComponent(label);
+ Iterator<Component> i = grid.iterator();
+ Assert.assertEquals(label, i.next());
+ Assert.assertFalse(i.hasNext());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/GridColumnAddingAndRemovingTest.java b/server/src/test/java/com/vaadin/tests/server/component/grid/GridColumnAddingAndRemovingTest.java
new file mode 100644
index 0000000000..97f0355b4b
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/grid/GridColumnAddingAndRemovingTest.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2000-2014 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.grid;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.Container;
+import com.vaadin.data.Property;
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.ui.Grid;
+
+public class GridColumnAddingAndRemovingTest {
+
+ Grid grid = new Grid();
+ Container.Indexed container;
+
+ @Before
+ public void setUp() {
+ container = grid.getContainerDataSource();
+ container.addItem();
+ }
+
+ @Test
+ public void testAddColumn() {
+ grid.addColumn("foo");
+
+ Property<?> property = container.getContainerProperty(
+ container.firstItemId(), "foo");
+ assertEquals(property.getType(), String.class);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testAddColumnTwice() {
+ grid.addColumn("foo");
+ grid.addColumn("foo");
+ }
+
+ @Test
+ public void testAddRemoveAndAddAgainColumn() {
+ grid.addColumn("foo");
+ grid.removeColumn("foo");
+
+ // Removing a column, doesn't remove the property
+ Property<?> property = container.getContainerProperty(
+ container.firstItemId(), "foo");
+ assertEquals(property.getType(), String.class);
+ grid.addColumn("foo");
+ }
+
+ @Test
+ public void testAddNumberColumns() {
+ grid.addColumn("bar", Integer.class);
+ grid.addColumn("baz", Double.class);
+
+ Property<?> property = container.getContainerProperty(
+ container.firstItemId(), "bar");
+ assertEquals(property.getType(), Integer.class);
+ assertEquals(null, property.getValue());
+ property = container.getContainerProperty(container.firstItemId(),
+ "baz");
+ assertEquals(property.getType(), Double.class);
+ assertEquals(null, property.getValue());
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testAddDifferentTypeColumn() {
+ grid.addColumn("foo");
+ grid.removeColumn("foo");
+ grid.addColumn("foo", Integer.class);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testAddColumnToNonDefaultContainer() {
+ grid.setContainerDataSource(new IndexedContainer());
+ grid.addColumn("foo");
+ }
+
+ @Test
+ public void testAddColumnForExistingProperty() {
+ grid.addColumn("bar");
+ IndexedContainer container2 = new IndexedContainer();
+ container2.addContainerProperty("foo", Integer.class, 0);
+ container2.addContainerProperty("bar", String.class, "");
+ grid.setContainerDataSource(container2);
+ assertNull("Grid should not have a column for property foo",
+ grid.getColumn("foo"));
+ assertNotNull("Grid did should have a column for property bar",
+ grid.getColumn("bar"));
+ for (Grid.Column column : grid.getColumns()) {
+ assertNotNull("Grid getColumns returned a null value", column);
+ }
+
+ grid.removeAllColumns();
+ grid.addColumn("foo");
+ assertNotNull("Grid should now have a column for property foo",
+ grid.getColumn("foo"));
+ assertNull("Grid should not have a column for property bar anymore",
+ grid.getColumn("bar"));
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testAddIncompatibleColumnProperty() {
+ grid.addColumn("bar");
+ grid.removeAllColumns();
+ grid.addColumn("bar", Integer.class);
+ }
+
+ @Test
+ public void testAddBooleanColumnProperty() {
+ grid.addColumn("foo", Boolean.class);
+ Property<?> property = container.getContainerProperty(
+ container.firstItemId(), "foo");
+ assertEquals(property.getType(), Boolean.class);
+ assertEquals(property.getValue(), null);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/GridColumns.java b/server/src/test/java/com/vaadin/tests/server/component/grid/GridColumns.java
new file mode 100644
index 0000000000..83e9f21756
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/grid/GridColumns.java
@@ -0,0 +1,414 @@
+/*
+ * Copyright 2000-2014 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.grid;
+
+import static org.easymock.EasyMock.and;
+import static org.easymock.EasyMock.capture;
+import static org.easymock.EasyMock.isA;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.easymock.Capture;
+import org.easymock.EasyMock;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.server.KeyMapper;
+import com.vaadin.shared.ui.grid.GridColumnState;
+import com.vaadin.shared.ui.grid.GridState;
+import com.vaadin.shared.util.SharedUtil;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.Column;
+import com.vaadin.ui.Grid.ColumnResizeEvent;
+import com.vaadin.ui.Grid.ColumnResizeListener;
+import com.vaadin.ui.TextField;
+
+public class GridColumns {
+
+ private Grid grid;
+
+ private GridState state;
+
+ private Method getStateMethod;
+
+ private Field columnIdGeneratorField;
+
+ private KeyMapper<Object> columnIdMapper;
+
+ @Before
+ @SuppressWarnings("unchecked")
+ public void setup() throws Exception {
+ IndexedContainer ds = new IndexedContainer();
+ for (int c = 0; c < 10; c++) {
+ ds.addContainerProperty("column" + c, String.class, "");
+ }
+ ds.addContainerProperty("noSort", Object.class, null);
+ grid = new Grid(ds);
+
+ getStateMethod = Grid.class.getDeclaredMethod("getState");
+ getStateMethod.setAccessible(true);
+
+ state = (GridState) getStateMethod.invoke(grid);
+
+ columnIdGeneratorField = Grid.class.getDeclaredField("columnKeys");
+ columnIdGeneratorField.setAccessible(true);
+
+ columnIdMapper = (KeyMapper<Object>) columnIdGeneratorField.get(grid);
+ }
+
+ @Test
+ public void testColumnGeneration() throws Exception {
+
+ for (Object propertyId : grid.getContainerDataSource()
+ .getContainerPropertyIds()) {
+
+ // All property ids should get a column
+ Column column = grid.getColumn(propertyId);
+ assertNotNull(column);
+
+ // Humanized property id should be the column header by default
+ assertEquals(
+ SharedUtil.camelCaseToHumanFriendly(propertyId.toString()),
+ grid.getDefaultHeaderRow().getCell(propertyId).getText());
+ }
+ }
+
+ @Test
+ public void testModifyingColumnProperties() throws Exception {
+
+ // Modify first column
+ Column column = grid.getColumn("column1");
+ assertNotNull(column);
+
+ column.setHeaderCaption("CustomHeader");
+ assertEquals("CustomHeader", column.getHeaderCaption());
+ assertEquals(column.getHeaderCaption(), grid.getDefaultHeaderRow()
+ .getCell("column1").getText());
+
+ column.setWidth(100);
+ assertEquals(100, column.getWidth(), 0.49d);
+ assertEquals(column.getWidth(), getColumnState("column1").width, 0.49d);
+
+ try {
+ column.setWidth(-1);
+ fail("Setting width to -1 should throw exception");
+ } catch (IllegalArgumentException iae) {
+ // expected
+ }
+
+ assertEquals(100, column.getWidth(), 0.49d);
+ assertEquals(100, getColumnState("column1").width, 0.49d);
+ }
+
+ @Test
+ public void testRemovingColumnByRemovingPropertyFromContainer()
+ throws Exception {
+
+ Column column = grid.getColumn("column1");
+ assertNotNull(column);
+
+ // Remove column
+ grid.getContainerDataSource().removeContainerProperty("column1");
+
+ try {
+ column.setHeaderCaption("asd");
+
+ fail("Succeeded in modifying a detached column");
+ } catch (IllegalStateException ise) {
+ // Detached state should throw exception
+ }
+
+ try {
+ column.setWidth(123);
+ fail("Succeeded in modifying a detached column");
+ } catch (IllegalStateException ise) {
+ // Detached state should throw exception
+ }
+
+ assertNull(grid.getColumn("column1"));
+ assertNull(getColumnState("column1"));
+ }
+
+ @Test
+ public void testAddingColumnByAddingPropertyToContainer() throws Exception {
+ grid.getContainerDataSource().addContainerProperty("columnX",
+ String.class, "");
+ Column column = grid.getColumn("columnX");
+ assertNotNull(column);
+ }
+
+ @Test
+ public void testHeaderVisiblility() throws Exception {
+
+ assertTrue(grid.isHeaderVisible());
+ assertTrue(state.header.visible);
+
+ grid.setHeaderVisible(false);
+ assertFalse(grid.isHeaderVisible());
+ assertFalse(state.header.visible);
+
+ grid.setHeaderVisible(true);
+ assertTrue(grid.isHeaderVisible());
+ assertTrue(state.header.visible);
+ }
+
+ @Test
+ public void testFooterVisibility() throws Exception {
+
+ assertTrue(grid.isFooterVisible());
+ assertTrue(state.footer.visible);
+
+ grid.setFooterVisible(false);
+ assertFalse(grid.isFooterVisible());
+ assertFalse(state.footer.visible);
+
+ grid.setFooterVisible(true);
+ assertTrue(grid.isFooterVisible());
+ assertTrue(state.footer.visible);
+ }
+
+ @Test
+ public void testSetFrozenColumnCount() {
+ assertEquals("Grid should not start with a frozen column", 0,
+ grid.getFrozenColumnCount());
+ grid.setFrozenColumnCount(2);
+ assertEquals("Freezing two columns should freeze two columns", 2,
+ grid.getFrozenColumnCount());
+ }
+
+ @Test
+ public void testSetFrozenColumnCountThroughColumn() {
+ assertEquals("Grid should not start with a frozen column", 0,
+ grid.getFrozenColumnCount());
+ grid.getColumns().get(2).setLastFrozenColumn();
+ assertEquals(
+ "Setting the third column as last frozen should freeze three columns",
+ 3, grid.getFrozenColumnCount());
+ }
+
+ @Test
+ public void testFrozenColumnRemoveColumn() {
+ assertEquals("Grid should not start with a frozen column", 0,
+ grid.getFrozenColumnCount());
+
+ int containerSize = grid.getContainerDataSource()
+ .getContainerPropertyIds().size();
+ grid.setFrozenColumnCount(containerSize);
+
+ Object propertyId = grid.getContainerDataSource()
+ .getContainerPropertyIds().iterator().next();
+
+ grid.getContainerDataSource().removeContainerProperty(propertyId);
+ assertEquals(
+ "Frozen column count should update when removing last row",
+ containerSize - 1, grid.getFrozenColumnCount());
+ }
+
+ @Test
+ public void testReorderColumns() {
+ Set<?> containerProperties = new LinkedHashSet<Object>(grid
+ .getContainerDataSource().getContainerPropertyIds());
+ Object[] properties = new Object[] { "column3", "column2", "column6" };
+ grid.setColumnOrder(properties);
+
+ int i = 0;
+ // Test sorted columns are first in order
+ for (Object property : properties) {
+ containerProperties.remove(property);
+ assertEquals(columnIdMapper.key(property),
+ state.columnOrder.get(i++));
+ }
+
+ // Test remaining columns are in original order
+ for (Object property : containerProperties) {
+ assertEquals(columnIdMapper.key(property),
+ state.columnOrder.get(i++));
+ }
+
+ try {
+ grid.setColumnOrder("foo", "bar", "baz");
+ fail("Grid allowed sorting with non-existent properties");
+ } catch (IllegalArgumentException e) {
+ // All ok
+ }
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testRemoveColumnThatDoesNotExist() {
+ grid.removeColumn("banana phone");
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testSetNonSortableColumnSortable() {
+ Column noSortColumn = grid.getColumn("noSort");
+ assertFalse("Object property column should not be sortable.",
+ noSortColumn.isSortable());
+ noSortColumn.setSortable(true);
+ }
+
+ @Test
+ public void testColumnsEditableByDefault() {
+ for (Column c : grid.getColumns()) {
+ assertTrue(c + " should be editable", c.isEditable());
+ }
+ }
+
+ @Test
+ public void testPropertyAndColumnEditorFieldsMatch() {
+ Column column1 = grid.getColumn("column1");
+ column1.setEditorField(new TextField());
+ assertSame(column1.getEditorField(), grid.getColumn("column1")
+ .getEditorField());
+
+ Column column2 = grid.getColumn("column2");
+ column2.setEditorField(new TextField());
+ assertSame(column2.getEditorField(), column2.getEditorField());
+ }
+
+ @Test
+ public void testUneditableColumnHasNoField() {
+ Column col = grid.getColumn("column1");
+
+ col.setEditable(false);
+
+ assertFalse("Column should be uneditable", col.isEditable());
+ assertNull("Uneditable column should not be auto-assigned a Field",
+ col.getEditorField());
+ }
+
+ private GridColumnState getColumnState(Object propertyId) {
+ String columnId = columnIdMapper.key(propertyId);
+ for (GridColumnState columnState : state.columns) {
+ if (columnState.id.equals(columnId)) {
+ return columnState;
+ }
+ }
+ return null;
+ }
+
+ @Test
+ public void testAddAndRemoveSortableColumn() {
+ boolean sortable = grid.getColumn("column1").isSortable();
+ grid.removeColumn("column1");
+ grid.addColumn("column1");
+ assertEquals("Column sortability changed when re-adding", sortable,
+ grid.getColumn("column1").isSortable());
+ }
+
+ @Test
+ public void testSetColumns() {
+ grid.setColumns("column7", "column0", "column9");
+ Iterator<Column> it = grid.getColumns().iterator();
+ assertEquals(it.next().getPropertyId(), "column7");
+ assertEquals(it.next().getPropertyId(), "column0");
+ assertEquals(it.next().getPropertyId(), "column9");
+ assertFalse(it.hasNext());
+ }
+
+ @Test
+ public void testAddingColumnsWithSetColumns() {
+ Grid g = new Grid();
+ g.setColumns("c1", "c2", "c3");
+ Iterator<Column> it = g.getColumns().iterator();
+ assertEquals(it.next().getPropertyId(), "c1");
+ assertEquals(it.next().getPropertyId(), "c2");
+ assertEquals(it.next().getPropertyId(), "c3");
+ assertFalse(it.hasNext());
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testAddingColumnsWithSetColumnsNonDefaultContainer() {
+ grid.setColumns("column1", "column2", "column50");
+ }
+
+ @Test
+ public void testDefaultColumnHidingToggleCaption() {
+ Column firstColumn = grid.getColumns().get(0);
+ firstColumn.setHeaderCaption("headerCaption");
+ assertEquals(null, firstColumn.getHidingToggleCaption());
+ }
+
+ @Test
+ public void testOverriddenColumnHidingToggleCaption() {
+ Column firstColumn = grid.getColumns().get(0);
+ firstColumn.setHidingToggleCaption("hidingToggleCaption");
+ firstColumn.setHeaderCaption("headerCaption");
+ assertEquals("hidingToggleCaption",
+ firstColumn.getHidingToggleCaption());
+ }
+
+ @Test
+ public void testColumnSetWidthFiresResizeEvent() {
+ final Column firstColumn = grid.getColumns().get(0);
+
+ // prepare a listener mock that captures the argument
+ ColumnResizeListener mock = EasyMock
+ .createMock(ColumnResizeListener.class);
+ Capture<ColumnResizeEvent> capturedEvent = new Capture<ColumnResizeEvent>();
+ mock.columnResize(and(capture(capturedEvent),
+ isA(ColumnResizeEvent.class)));
+ EasyMock.expectLastCall().once();
+
+ // Tell it to wait for the call
+ EasyMock.replay(mock);
+
+ // Cause a resize event
+ grid.addColumnResizeListener(mock);
+ firstColumn.setWidth(firstColumn.getWidth() + 10);
+
+ // Verify the method was called
+ EasyMock.verify(mock);
+
+ // Asserts on the captured event
+ ColumnResizeEvent event = capturedEvent.getValue();
+ assertEquals("Event column was not first column.", firstColumn,
+ event.getColumn());
+ assertFalse("Event should not be userOriginated",
+ event.isUserOriginated());
+ }
+
+ @Test
+ public void textHeaderCaptionIsReturned() {
+ Column firstColumn = grid.getColumns().get(0);
+
+ firstColumn.setHeaderCaption("text");
+
+ assertThat(firstColumn.getHeaderCaption(), is("text"));
+ }
+
+ @Test
+ public void defaultCaptionIsReturnedForHtml() {
+ Column firstColumn = grid.getColumns().get(0);
+
+ grid.getDefaultHeaderRow().getCell("column0").setHtml("<b>html</b>");
+
+ assertThat(firstColumn.getHeaderCaption(), is("Column0"));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/GridContainerNotSortableTest.java b/server/src/test/java/com/vaadin/tests/server/component/grid/GridContainerNotSortableTest.java
new file mode 100644
index 0000000000..cdfd2328dc
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/grid/GridContainerNotSortableTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2000-2014 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.grid;
+
+import static org.junit.Assert.assertFalse;
+
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.junit.Test;
+
+import com.vaadin.data.Item;
+import com.vaadin.data.Property;
+import com.vaadin.data.util.AbstractInMemoryContainer;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.Column;
+
+public class GridContainerNotSortableTest {
+
+ final AbstractInMemoryContainer<Object, Object, Item> notSortableDataSource = new AbstractInMemoryContainer<Object, Object, Item>() {
+
+ private Map<Object, Property<?>> properties = new LinkedHashMap<Object, Property<?>>();
+
+ {
+ properties.put("Foo", new Property<String>() {
+
+ @Override
+ public String getValue() {
+ return "foo";
+ }
+
+ @Override
+ public void setValue(String newValue) throws ReadOnlyException {
+ throw new ReadOnlyException();
+ }
+
+ @Override
+ public Class<? extends String> getType() {
+ return String.class;
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return true;
+ }
+
+ @Override
+ public void setReadOnly(boolean newStatus) {
+ throw new UnsupportedOperationException();
+ }
+ });
+ }
+
+ @Override
+ public Collection<?> getContainerPropertyIds() {
+ return properties.keySet();
+ }
+
+ @Override
+ public Property getContainerProperty(Object itemId, Object propertyId) {
+ return properties.get(propertyId);
+ }
+
+ @Override
+ public Class<?> getType(Object propertyId) {
+ return properties.get(propertyId).getType();
+ }
+
+ @Override
+ protected Item getUnfilteredItem(Object itemId) {
+ return null;
+ }
+ };
+
+ @Test
+ public void testGridWithNotSortableContainer() {
+ new Grid(notSortableDataSource);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testNotSortableGridSetColumnSortable() {
+ Grid grid = new Grid();
+ grid.setContainerDataSource(notSortableDataSource);
+ Column column = grid.getColumn("Foo");
+ assertFalse("Column should not be sortable initially.",
+ column.isSortable());
+ column.setSortable(true);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/GridContainerTest.java b/server/src/test/java/com/vaadin/tests/server/component/grid/GridContainerTest.java
new file mode 100644
index 0000000000..079487d01f
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/grid/GridContainerTest.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2000-2014 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.grid;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.DetailsGenerator;
+import com.vaadin.ui.Grid.RowReference;
+import com.vaadin.ui.Label;
+
+public class GridContainerTest {
+
+ @Test
+ public void testDetailsGeneratorDoesNotResetOnContainerChange() {
+ Grid grid = new Grid();
+ DetailsGenerator detGen = new DetailsGenerator() {
+
+ @Override
+ public Component getDetails(RowReference rowReference) {
+ return new Label("Empty details");
+ }
+ };
+ grid.setDetailsGenerator(detGen);
+
+ grid.setContainerDataSource(createContainer());
+
+ Assert.assertEquals("DetailsGenerator changed", detGen,
+ grid.getDetailsGenerator());
+ }
+
+ @Test
+ public void testSetContainerTwice() throws Exception {
+
+ TestGrid grid = new TestGrid();
+
+ grid.setContainerDataSource(createContainer());
+
+ // Simulate initial response to ensure "lazy" state changes are done
+ // before resetting the datasource
+ grid.beforeClientResponse(true);
+ grid.getDataProvider().beforeClientResponse(true);
+
+ grid.setContainerDataSource(createContainer());
+ }
+
+ @SuppressWarnings("unchecked")
+ private IndexedContainer createContainer() {
+ IndexedContainer container = new IndexedContainer();
+ container.addContainerProperty("x", String.class, null);
+ container.addItem(0).getItemProperty("x").setValue("y");
+ return container;
+ }
+
+ @Test
+ public void setColumnsOrder() {
+ Grid grid = new Grid();
+ IndexedContainer ic = new IndexedContainer();
+ ic.addContainerProperty("foo", String.class, "");
+ ic.addContainerProperty("baz", String.class, "");
+ ic.addContainerProperty("bar", String.class, "");
+ grid.setContainerDataSource(ic);
+ grid.setColumns("foo", "baz", "bar");
+
+ Assert.assertEquals("foo", grid.getColumns().get(0).getPropertyId());
+ Assert.assertEquals("baz", grid.getColumns().get(1).getPropertyId());
+ Assert.assertEquals("bar", grid.getColumns().get(2).getPropertyId());
+ }
+
+ @Test
+ public void addColumnNotInContainer() {
+ Grid grid = new Grid();
+ grid.setContainerDataSource(new IndexedContainer());
+ try {
+ grid.addColumn("notInContainer");
+ Assert.fail("Adding a property id not in the container should throw an exception");
+ } catch (IllegalStateException e) {
+ Assert.assertTrue(e.getMessage().contains("notInContainer"));
+ Assert.assertTrue(e.getMessage().contains(
+ "does not exist in the container"));
+ }
+ }
+
+ @Test
+ public void setColumnsForPropertyIdNotInContainer() {
+ Grid grid = new Grid();
+ grid.setContainerDataSource(new IndexedContainer());
+ try {
+ grid.setColumns("notInContainer", "notThereEither");
+ Assert.fail("Setting columns for property ids not in the container should throw an exception");
+ } catch (IllegalStateException e) {
+ // addColumn is run in random order..
+ Assert.assertTrue(e.getMessage().contains("notInContainer")
+ || e.getMessage().contains("notThereEither"));
+ Assert.assertTrue(e.getMessage().contains(
+ "does not exist in the container"));
+ }
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void multipleAddColumnsForDefaultContainer() {
+ Grid grid = new Grid();
+ grid.addColumn("foo");
+ grid.addColumn("foo");
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/GridEditorTest.java b/server/src/test/java/com/vaadin/tests/server/component/grid/GridEditorTest.java
new file mode 100644
index 0000000000..b70f17779a
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/grid/GridEditorTest.java
@@ -0,0 +1,294 @@
+/*
+ * Copyright 2000-2014 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.grid;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Method;
+
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.Item;
+import com.vaadin.data.Property;
+import com.vaadin.data.fieldgroup.FieldGroup;
+import com.vaadin.data.fieldgroup.FieldGroup.CommitException;
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.server.MockVaadinSession;
+import com.vaadin.server.VaadinService;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.ui.Field;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.TextField;
+
+public class GridEditorTest {
+
+ private static final Object PROPERTY_NAME = "name";
+ private static final Object PROPERTY_AGE = "age";
+ private static final String DEFAULT_NAME = "Some Valid Name";
+ private static final Integer DEFAULT_AGE = 25;
+ private static final Object ITEM_ID = new Object();
+
+ // Explicit field for the test session to save it from GC
+ private VaadinSession session;
+
+ private final Grid grid = new Grid();
+ private Method doEditMethod;
+
+ @Before
+ @SuppressWarnings("unchecked")
+ public void setup() throws SecurityException, NoSuchMethodException {
+ IndexedContainer container = new IndexedContainer();
+ container.addContainerProperty(PROPERTY_NAME, String.class, "[name]");
+ container.addContainerProperty(PROPERTY_AGE, Integer.class,
+ Integer.valueOf(-1));
+
+ Item item = container.addItem(ITEM_ID);
+ item.getItemProperty(PROPERTY_NAME).setValue(DEFAULT_NAME);
+ item.getItemProperty(PROPERTY_AGE).setValue(DEFAULT_AGE);
+ grid.setContainerDataSource(container);
+
+ // VaadinSession needed for ConverterFactory
+ VaadinService mockService = EasyMock
+ .createNiceMock(VaadinService.class);
+ session = new MockVaadinSession(mockService);
+ VaadinSession.setCurrent(session);
+ session.lock();
+
+ // Access to method for actual editing.
+ doEditMethod = Grid.class.getDeclaredMethod("doEditItem");
+ doEditMethod.setAccessible(true);
+ }
+
+ @After
+ public void tearDown() {
+ session.unlock();
+ session = null;
+ VaadinSession.setCurrent(null);
+ }
+
+ @Test
+ public void testInitAssumptions() throws Exception {
+ assertFalse(grid.isEditorEnabled());
+ assertNull(grid.getEditedItemId());
+ assertNotNull(grid.getEditorFieldGroup());
+ }
+
+ @Test
+ public void testSetEnabled() throws Exception {
+ assertFalse(grid.isEditorEnabled());
+ grid.setEditorEnabled(true);
+ assertTrue(grid.isEditorEnabled());
+ }
+
+ @Test
+ public void testSetDisabled() throws Exception {
+ assertFalse(grid.isEditorEnabled());
+ grid.setEditorEnabled(true);
+ grid.setEditorEnabled(false);
+ assertFalse(grid.isEditorEnabled());
+ }
+
+ @Test
+ public void testSetReEnabled() throws Exception {
+ assertFalse(grid.isEditorEnabled());
+ grid.setEditorEnabled(true);
+ grid.setEditorEnabled(false);
+ grid.setEditorEnabled(true);
+ assertTrue(grid.isEditorEnabled());
+ }
+
+ @Test
+ public void testDetached() throws Exception {
+ FieldGroup oldFieldGroup = grid.getEditorFieldGroup();
+ grid.removeAllColumns();
+ grid.setContainerDataSource(new IndexedContainer());
+ assertFalse(oldFieldGroup == grid.getEditorFieldGroup());
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testDisabledEditItem() throws Exception {
+ grid.editItem(ITEM_ID);
+ }
+
+ @Test
+ public void testEditItem() throws Exception {
+ startEdit();
+ assertEquals(ITEM_ID, grid.getEditedItemId());
+ assertEquals(getEditedItem(), grid.getEditorFieldGroup()
+ .getItemDataSource());
+
+ assertEquals(DEFAULT_NAME, grid.getColumn(PROPERTY_NAME)
+ .getEditorField().getValue());
+ assertEquals(String.valueOf(DEFAULT_AGE), grid.getColumn(PROPERTY_AGE)
+ .getEditorField().getValue());
+ }
+
+ @Test
+ public void testSaveEditor() throws Exception {
+ startEdit();
+ TextField field = (TextField) grid.getColumn(PROPERTY_NAME)
+ .getEditorField();
+
+ field.setValue("New Name");
+ assertEquals(DEFAULT_NAME, field.getPropertyDataSource().getValue());
+
+ grid.saveEditor();
+ assertTrue(grid.isEditorActive());
+ assertFalse(field.isModified());
+ assertEquals("New Name", field.getValue());
+ assertEquals("New Name", getEditedProperty(PROPERTY_NAME).getValue());
+ }
+
+ @Test
+ public void testSaveEditorCommitFail() throws Exception {
+ startEdit();
+
+ ((TextField) grid.getColumn(PROPERTY_AGE).getEditorField())
+ .setValue("Invalid");
+ try {
+ // Manual fail instead of @Test(expected=...) to check it is
+ // saveEditor that fails and not setValue
+ grid.saveEditor();
+ Assert.fail("CommitException expected when saving an invalid field value");
+ } catch (CommitException e) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testCancelEditor() throws Exception {
+ startEdit();
+ TextField field = (TextField) grid.getColumn(PROPERTY_NAME)
+ .getEditorField();
+ field.setValue("New Name");
+
+ Property<?> datasource = field.getPropertyDataSource();
+
+ grid.cancelEditor();
+ assertFalse(grid.isEditorActive());
+ assertNull(grid.getEditedItemId());
+ assertFalse(field.isModified());
+ assertEquals("", field.getValue());
+ assertEquals(DEFAULT_NAME, datasource.getValue());
+ assertNull(field.getPropertyDataSource());
+ assertNull(grid.getEditorFieldGroup().getItemDataSource());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testNonexistentEditItem() throws Exception {
+ grid.setEditorEnabled(true);
+ grid.editItem(new Object());
+ }
+
+ @Test
+ public void testGetField() throws Exception {
+ startEdit();
+
+ assertNotNull(grid.getColumn(PROPERTY_NAME).getEditorField());
+ }
+
+ @Test
+ public void testGetFieldWithoutItem() throws Exception {
+ grid.setEditorEnabled(true);
+ assertNotNull(grid.getColumn(PROPERTY_NAME).getEditorField());
+ }
+
+ @Test
+ public void testCustomBinding() {
+ TextField textField = new TextField();
+ grid.getColumn(PROPERTY_NAME).setEditorField(textField);
+
+ startEdit();
+
+ assertSame(textField, grid.getColumn(PROPERTY_NAME).getEditorField());
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testDisableWhileEditing() {
+ startEdit();
+ grid.setEditorEnabled(false);
+ }
+
+ @Test
+ public void testFieldIsNotReadonly() {
+ startEdit();
+
+ Field<?> field = grid.getColumn(PROPERTY_NAME).getEditorField();
+ assertFalse(field.isReadOnly());
+ }
+
+ @Test
+ public void testFieldIsReadonlyWhenFieldGroupIsReadonly() {
+ startEdit();
+
+ grid.getEditorFieldGroup().setReadOnly(true);
+ Field<?> field = grid.getColumn(PROPERTY_NAME).getEditorField();
+ assertTrue(field.isReadOnly());
+ }
+
+ @Test
+ public void testColumnRemoved() {
+ Field<?> field = grid.getColumn(PROPERTY_NAME).getEditorField();
+
+ assertSame("field should be attached to ", grid, field.getParent());
+
+ grid.removeColumn(PROPERTY_NAME);
+
+ assertNull("field should be detached from ", field.getParent());
+ }
+
+ @Test
+ public void testSetFieldAgain() {
+ TextField field = new TextField();
+ grid.getColumn(PROPERTY_NAME).setEditorField(field);
+
+ field = new TextField();
+ grid.getColumn(PROPERTY_NAME).setEditorField(field);
+
+ assertSame("new field should be used.", field,
+ grid.getColumn(PROPERTY_NAME).getEditorField());
+ }
+
+ private void startEdit() {
+ grid.setEditorEnabled(true);
+ grid.editItem(ITEM_ID);
+ // Simulate succesful client response to actually start the editing.
+ try {
+ doEditMethod.invoke(grid);
+ } catch (Exception e) {
+ Assert.fail("Editing item " + ITEM_ID + " failed. Cause: "
+ + e.getCause().toString());
+ }
+ }
+
+ private Item getEditedItem() {
+ assertNotNull(grid.getEditedItemId());
+ return grid.getContainerDataSource().getItem(grid.getEditedItemId());
+ }
+
+ private Property<?> getEditedProperty(Object propertyId) {
+ return getEditedItem().getItemProperty(PROPERTY_NAME);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/GridExtensionTest.java b/server/src/test/java/com/vaadin/tests/server/component/grid/GridExtensionTest.java
new file mode 100644
index 0000000000..d9db217aa3
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/grid/GridExtensionTest.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2000-2014 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.grid;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.AbstractGridExtension;
+
+public class GridExtensionTest {
+
+ public static class DummyGridExtension extends AbstractGridExtension {
+
+ public DummyGridExtension(Grid grid) {
+ super(grid);
+ }
+ }
+
+ @Test
+ public void testCreateExtension() {
+ Grid grid = new Grid();
+ DummyGridExtension dummy = new DummyGridExtension(grid);
+ assertTrue("DummyGridExtension never made it to Grid", grid
+ .getExtensions().contains(dummy));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/GridSelection.java b/server/src/test/java/com/vaadin/tests/server/component/grid/GridSelection.java
new file mode 100644
index 0000000000..dc641965ba
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/grid/GridSelection.java
@@ -0,0 +1,374 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.server.component.grid;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collection;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.event.SelectionEvent;
+import com.vaadin.event.SelectionEvent.SelectionListener;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.SelectionMode;
+import com.vaadin.ui.Grid.SelectionModel;
+
+public class GridSelection {
+
+ private static class MockSelectionChangeListener implements
+ SelectionListener {
+ private SelectionEvent event;
+
+ @Override
+ public void select(final SelectionEvent event) {
+ this.event = event;
+ }
+
+ public Collection<?> getAdded() {
+ return event.getAdded();
+ }
+
+ public Collection<?> getRemoved() {
+ return event.getRemoved();
+ }
+
+ public void clearEvent() {
+ /*
+ * This method is not strictly needed as the event will simply be
+ * overridden, but it's good practice, and makes the code more
+ * obvious.
+ */
+ event = null;
+ }
+
+ public boolean eventHasHappened() {
+ return event != null;
+ }
+ }
+
+ private Grid grid;
+ private MockSelectionChangeListener mockListener;
+
+ private final Object itemId1Present = "itemId1Present";
+ private final Object itemId2Present = "itemId2Present";
+
+ private final Object itemId1NotPresent = "itemId1NotPresent";
+ private final Object itemId2NotPresent = "itemId2NotPresent";
+
+ @Before
+ public void setup() {
+ final IndexedContainer container = new IndexedContainer();
+ container.addItem(itemId1Present);
+ container.addItem(itemId2Present);
+ for (int i = 2; i < 10; i++) {
+ container.addItem(new Object());
+ }
+
+ assertEquals("init size", 10, container.size());
+ assertTrue("itemId1Present", container.containsId(itemId1Present));
+ assertTrue("itemId2Present", container.containsId(itemId2Present));
+ assertFalse("itemId1NotPresent",
+ container.containsId(itemId1NotPresent));
+ assertFalse("itemId2NotPresent",
+ container.containsId(itemId2NotPresent));
+
+ grid = new Grid(container);
+
+ mockListener = new MockSelectionChangeListener();
+ grid.addSelectionListener(mockListener);
+
+ assertFalse("eventHasHappened", mockListener.eventHasHappened());
+ }
+
+ @Test
+ public void defaultSelectionModeIsSingle() {
+ assertTrue(grid.getSelectionModel() instanceof SelectionModel.Single);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void getSelectedRowThrowsExceptionMulti() {
+ grid.setSelectionMode(SelectionMode.MULTI);
+ grid.getSelectedRow();
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void getSelectedRowThrowsExceptionNone() {
+ grid.setSelectionMode(SelectionMode.NONE);
+ grid.getSelectedRow();
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void selectThrowsExceptionNone() {
+ grid.setSelectionMode(SelectionMode.NONE);
+ grid.select(itemId1Present);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void deselectRowThrowsExceptionNone() {
+ grid.setSelectionMode(SelectionMode.NONE);
+ grid.deselect(itemId1Present);
+ }
+
+ @Test
+ public void selectionModeMapsToMulti() {
+ assertTrue(grid.setSelectionMode(SelectionMode.MULTI) instanceof SelectionModel.Multi);
+ }
+
+ @Test
+ public void selectionModeMapsToSingle() {
+ assertTrue(grid.setSelectionMode(SelectionMode.SINGLE) instanceof SelectionModel.Single);
+ }
+
+ @Test
+ public void selectionModeMapsToNone() {
+ assertTrue(grid.setSelectionMode(SelectionMode.NONE) instanceof SelectionModel.None);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void selectionModeNullThrowsException() {
+ grid.setSelectionMode(null);
+ }
+
+ @Test
+ public void noSelectModel_isSelected() {
+ grid.setSelectionMode(SelectionMode.NONE);
+ assertFalse("itemId1Present", grid.isSelected(itemId1Present));
+ assertFalse("itemId1NotPresent", grid.isSelected(itemId1NotPresent));
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void noSelectModel_getSelectedRow() {
+ grid.setSelectionMode(SelectionMode.NONE);
+ grid.getSelectedRow();
+ }
+
+ @Test
+ public void noSelectModel_getSelectedRows() {
+ grid.setSelectionMode(SelectionMode.NONE);
+ assertTrue(grid.getSelectedRows().isEmpty());
+ }
+
+ @Test
+ public void selectionCallsListenerMulti() {
+ grid.setSelectionMode(SelectionMode.MULTI);
+ selectionCallsListener();
+ }
+
+ @Test
+ public void selectionCallsListenerSingle() {
+ grid.setSelectionMode(SelectionMode.SINGLE);
+ selectionCallsListener();
+ }
+
+ private void selectionCallsListener() {
+ grid.select(itemId1Present);
+ assertEquals("added size", 1, mockListener.getAdded().size());
+ assertEquals("added item", itemId1Present, mockListener.getAdded()
+ .iterator().next());
+ assertEquals("removed size", 0, mockListener.getRemoved().size());
+ }
+
+ @Test
+ public void deselectionCallsListenerMulti() {
+ grid.setSelectionMode(SelectionMode.MULTI);
+ deselectionCallsListener();
+ }
+
+ @Test
+ public void deselectionCallsListenerSingle() {
+ grid.setSelectionMode(SelectionMode.SINGLE);
+ deselectionCallsListener();
+ }
+
+ private void deselectionCallsListener() {
+ grid.select(itemId1Present);
+ mockListener.clearEvent();
+
+ grid.deselect(itemId1Present);
+ assertEquals("removed size", 1, mockListener.getRemoved().size());
+ assertEquals("removed item", itemId1Present, mockListener.getRemoved()
+ .iterator().next());
+ assertEquals("removed size", 0, mockListener.getAdded().size());
+ }
+
+ @Test
+ public void deselectPresentButNotSelectedItemIdShouldntFireListenerMulti() {
+ grid.setSelectionMode(SelectionMode.MULTI);
+ deselectPresentButNotSelectedItemIdShouldntFireListener();
+ }
+
+ @Test
+ public void deselectPresentButNotSelectedItemIdShouldntFireListenerSingle() {
+ grid.setSelectionMode(SelectionMode.SINGLE);
+ deselectPresentButNotSelectedItemIdShouldntFireListener();
+ }
+
+ private void deselectPresentButNotSelectedItemIdShouldntFireListener() {
+ grid.deselect(itemId1Present);
+ assertFalse(mockListener.eventHasHappened());
+ }
+
+ @Test
+ public void deselectNotPresentItemIdShouldNotThrowExceptionMulti() {
+ grid.setSelectionMode(SelectionMode.MULTI);
+ grid.deselect(itemId1NotPresent);
+ }
+
+ @Test
+ public void deselectNotPresentItemIdShouldNotThrowExceptionSingle() {
+ grid.setSelectionMode(SelectionMode.SINGLE);
+ grid.deselect(itemId1NotPresent);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void selectNotPresentItemIdShouldThrowExceptionMulti() {
+ grid.setSelectionMode(SelectionMode.MULTI);
+ grid.select(itemId1NotPresent);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void selectNotPresentItemIdShouldThrowExceptionSingle() {
+ grid.setSelectionMode(SelectionMode.SINGLE);
+ grid.select(itemId1NotPresent);
+ }
+
+ @Test
+ public void selectAllMulti() {
+ grid.setSelectionMode(SelectionMode.MULTI);
+ final SelectionModel.Multi select = (SelectionModel.Multi) grid
+ .getSelectionModel();
+ select.selectAll();
+ assertEquals("added size", 10, mockListener.getAdded().size());
+ assertEquals("removed size", 0, mockListener.getRemoved().size());
+ assertTrue("itemId1Present",
+ mockListener.getAdded().contains(itemId1Present));
+ assertTrue("itemId2Present",
+ mockListener.getAdded().contains(itemId2Present));
+ }
+
+ @Test
+ public void deselectAllMulti() {
+ grid.setSelectionMode(SelectionMode.MULTI);
+ final SelectionModel.Multi select = (SelectionModel.Multi) grid
+ .getSelectionModel();
+ select.selectAll();
+ mockListener.clearEvent();
+
+ select.deselectAll();
+ assertEquals("removed size", 10, mockListener.getRemoved().size());
+ assertEquals("added size", 0, mockListener.getAdded().size());
+ assertTrue("itemId1Present",
+ mockListener.getRemoved().contains(itemId1Present));
+ assertTrue("itemId2Present",
+ mockListener.getRemoved().contains(itemId2Present));
+ assertTrue("selectedRows is empty", grid.getSelectedRows().isEmpty());
+ }
+
+ @Test
+ public void gridDeselectAllMultiAllSelected() {
+ grid.setSelectionMode(SelectionMode.MULTI);
+ final SelectionModel.Multi select = (SelectionModel.Multi) grid
+ .getSelectionModel();
+ select.selectAll();
+ mockListener.clearEvent();
+
+ assertTrue(grid.deselectAll());
+ assertEquals("removed size", 10, mockListener.getRemoved().size());
+ assertEquals("added size", 0, mockListener.getAdded().size());
+ assertTrue("itemId1Present",
+ mockListener.getRemoved().contains(itemId1Present));
+ assertTrue("itemId2Present",
+ mockListener.getRemoved().contains(itemId2Present));
+ assertTrue("selectedRows is empty", grid.getSelectedRows().isEmpty());
+
+ }
+
+ @Test
+ public void gridDeselectAllMultiOneSelected() {
+ grid.setSelectionMode(SelectionMode.MULTI);
+ final SelectionModel.Multi select = (SelectionModel.Multi) grid
+ .getSelectionModel();
+ select.select(itemId2Present);
+ mockListener.clearEvent();
+
+ assertTrue(grid.deselectAll());
+ assertEquals("removed size", 1, mockListener.getRemoved().size());
+ assertEquals("added size", 0, mockListener.getAdded().size());
+ assertFalse("itemId1Present",
+ mockListener.getRemoved().contains(itemId1Present));
+ assertTrue("itemId2Present",
+ mockListener.getRemoved().contains(itemId2Present));
+ assertTrue("selectedRows is empty", grid.getSelectedRows().isEmpty());
+
+ }
+
+ @Test
+ public void gridDeselectAllSingleNoneSelected() {
+ grid.setSelectionMode(SelectionMode.SINGLE);
+ assertFalse(grid.deselectAll());
+ assertTrue("selectedRows is empty", grid.getSelectedRows().isEmpty());
+ }
+
+ @Test
+ public void gridDeselectAllSingleOneSelected() {
+ grid.setSelectionMode(SelectionMode.SINGLE);
+ final SelectionModel.Single select = (SelectionModel.Single) grid
+ .getSelectionModel();
+ select.select(itemId2Present);
+ mockListener.clearEvent();
+
+ assertTrue(grid.deselectAll());
+ assertEquals("removed size", 1, mockListener.getRemoved().size());
+ assertEquals("added size", 0, mockListener.getAdded().size());
+ assertFalse("itemId1Present",
+ mockListener.getRemoved().contains(itemId1Present));
+ assertTrue("itemId2Present",
+ mockListener.getRemoved().contains(itemId2Present));
+ assertTrue("selectedRows is empty", grid.getSelectedRows().isEmpty());
+
+ }
+
+ @Test
+ public void gridDeselectAllMultiNoneSelected() {
+ grid.setSelectionMode(SelectionMode.MULTI);
+
+ assertFalse(grid.deselectAll());
+ assertTrue("selectedRows is empty", grid.getSelectedRows().isEmpty());
+
+ }
+
+ @Test
+ public void reselectionDeselectsPreviousSingle() {
+ grid.setSelectionMode(SelectionMode.SINGLE);
+ grid.select(itemId1Present);
+ mockListener.clearEvent();
+
+ grid.select(itemId2Present);
+ assertEquals("added size", 1, mockListener.getAdded().size());
+ assertEquals("removed size", 1, mockListener.getRemoved().size());
+ assertEquals("added item", itemId2Present, mockListener.getAdded()
+ .iterator().next());
+ assertEquals("removed item", itemId1Present, mockListener.getRemoved()
+ .iterator().next());
+ assertEquals("selectedRows is correct", itemId2Present,
+ grid.getSelectedRow());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/GridStateTest.java b/server/src/test/java/com/vaadin/tests/server/component/grid/GridStateTest.java
new file mode 100644
index 0000000000..567fad52af
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/grid/GridStateTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2000-2014 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.grid;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.shared.ui.grid.GridState;
+import com.vaadin.ui.Grid;
+
+/**
+ * Tests for Grid State.
+ *
+ */
+public class GridStateTest {
+
+ @Test
+ public void getPrimaryStyleName_gridHasCustomPrimaryStyleName() {
+ Grid grid = new Grid();
+ GridState state = new GridState();
+ Assert.assertEquals("Unexpected primary style name",
+ state.primaryStyleName, grid.getPrimaryStyleName());
+ }
+
+ @Test
+ public void gridStateHasCustomPrimaryStyleName() {
+ GridState state = new GridState();
+ Assert.assertEquals("Unexpected primary style name", "v-grid",
+ state.primaryStyleName);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/GridStaticSectionTest.java b/server/src/test/java/com/vaadin/tests/server/component/grid/GridStaticSectionTest.java
new file mode 100644
index 0000000000..4031886e7a
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/grid/GridStaticSectionTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2000-2014 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.grid;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.lang.reflect.Method;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.Container.Indexed;
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.ui.Grid;
+
+public class GridStaticSectionTest extends Grid {
+
+ private Indexed dataSource = new IndexedContainer();
+
+ @Before
+ public void setUp() {
+ dataSource.addContainerProperty("firstName", String.class, "");
+ dataSource.addContainerProperty("lastName", String.class, "");
+ dataSource.addContainerProperty("streetAddress", String.class, "");
+ dataSource.addContainerProperty("zipCode", Integer.class, null);
+ setContainerDataSource(dataSource);
+ }
+
+ @Test
+ public void testAddAndRemoveHeaders() {
+ assertEquals(1, getHeaderRowCount());
+ prependHeaderRow();
+ assertEquals(2, getHeaderRowCount());
+ removeHeaderRow(0);
+ assertEquals(1, getHeaderRowCount());
+ removeHeaderRow(0);
+ assertEquals(0, getHeaderRowCount());
+ assertEquals(null, getDefaultHeaderRow());
+ HeaderRow row = appendHeaderRow();
+ assertEquals(1, getHeaderRowCount());
+ assertEquals(null, getDefaultHeaderRow());
+ setDefaultHeaderRow(row);
+ assertEquals(row, getDefaultHeaderRow());
+ }
+
+ @Test
+ public void testAddAndRemoveFooters() {
+ // By default there are no footer rows
+ assertEquals(0, getFooterRowCount());
+ FooterRow row = appendFooterRow();
+
+ assertEquals(1, getFooterRowCount());
+ prependFooterRow();
+ assertEquals(2, getFooterRowCount());
+ assertEquals(row, getFooterRow(1));
+ removeFooterRow(0);
+ assertEquals(1, getFooterRowCount());
+ removeFooterRow(0);
+ assertEquals(0, getFooterRowCount());
+ }
+
+ @Test
+ public void testUnusedPropertyNotInCells() {
+ removeColumn("firstName");
+ assertNull("firstName cell was not removed from existing row",
+ getDefaultHeaderRow().getCell("firstName"));
+ HeaderRow newRow = appendHeaderRow();
+ assertNull("firstName cell was created when it should not.",
+ newRow.getCell("firstName"));
+ addColumn("firstName");
+ assertNotNull(
+ "firstName cell was not created for default row when added again",
+ getDefaultHeaderRow().getCell("firstName"));
+ assertNotNull(
+ "firstName cell was not created for new row when added again",
+ newRow.getCell("firstName"));
+
+ }
+
+ @Test
+ public void testJoinHeaderCells() {
+ HeaderRow mergeRow = prependHeaderRow();
+ mergeRow.join("firstName", "lastName").setText("Name");
+ mergeRow.join(mergeRow.getCell("streetAddress"),
+ mergeRow.getCell("zipCode"));
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testJoinHeaderCellsIncorrectly() throws Throwable {
+ HeaderRow mergeRow = prependHeaderRow();
+ mergeRow.join("firstName", "zipCode").setText("Name");
+ sanityCheck();
+ }
+
+ @Test
+ public void testJoinAllFooterCells() {
+ FooterRow mergeRow = prependFooterRow();
+ mergeRow.join(dataSource.getContainerPropertyIds().toArray()).setText(
+ "All the stuff.");
+ }
+
+ private void sanityCheck() throws Throwable {
+ Method sanityCheckHeader;
+ try {
+ sanityCheckHeader = Grid.Header.class
+ .getDeclaredMethod("sanityCheck");
+ sanityCheckHeader.setAccessible(true);
+ Method sanityCheckFooter = Grid.Footer.class
+ .getDeclaredMethod("sanityCheck");
+ sanityCheckFooter.setAccessible(true);
+ sanityCheckHeader.invoke(getHeader());
+ sanityCheckFooter.invoke(getFooter());
+ } catch (Exception e) {
+ throw e.getCause();
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/MultiSelectionModelTest.java b/server/src/test/java/com/vaadin/tests/server/component/grid/MultiSelectionModelTest.java
new file mode 100644
index 0000000000..9b327a2f22
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/grid/MultiSelectionModelTest.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2000-2014 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.grid;
+
+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;
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.event.SelectionEvent;
+import com.vaadin.event.SelectionEvent.SelectionListener;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.MultiSelectionModel;
+import com.vaadin.ui.Grid.SelectionMode;
+
+public class MultiSelectionModelTest {
+
+ private Object itemId1Present = "itemId1Present";
+ private Object itemId2Present = "itemId2Present";
+ private Object itemId3Present = "itemId3Present";
+
+ private Object itemIdNotPresent = "itemIdNotPresent";
+ private Container.Indexed dataSource;
+ private MultiSelectionModel model;
+ private Grid grid;
+
+ private boolean expectingEvent = false;
+ private boolean expectingDeselectEvent;
+ private List<Object> select = new ArrayList<Object>();
+ private List<Object> deselect = new ArrayList<Object>();
+
+ @Before
+ public void setUp() {
+ dataSource = createDataSource();
+ grid = new Grid(dataSource);
+ grid.setSelectionMode(SelectionMode.MULTI);
+ model = (MultiSelectionModel) grid.getSelectionModel();
+ }
+
+ @After
+ public void tearDown() {
+ Assert.assertFalse("Some expected select event did not happen.",
+ expectingEvent);
+ Assert.assertFalse("Some expected deselect event did not happen.",
+ expectingDeselectEvent);
+ }
+
+ private IndexedContainer createDataSource() {
+ final IndexedContainer container = new IndexedContainer();
+ container.addItem(itemId1Present);
+ container.addItem(itemId2Present);
+ container.addItem(itemId3Present);
+ for (int i = 3; i < 10; i++) {
+ container.addItem(new Object());
+ }
+
+ return container;
+ }
+
+ @Test
+ public void testSelectAndDeselectRow() throws Throwable {
+ try {
+ expectSelectEvent(itemId1Present);
+ model.select(itemId1Present);
+ expectDeselectEvent(itemId1Present);
+ model.deselect(itemId1Present);
+ } catch (Exception e) {
+ throw e.getCause();
+ }
+
+ verifyCurrentSelection();
+ }
+
+ @Test
+ public void testAddSelection() throws Throwable {
+ try {
+ expectSelectEvent(itemId1Present);
+ model.select(itemId1Present);
+ expectSelectEvent(itemId2Present);
+ model.select(itemId2Present);
+ } catch (Exception e) {
+ throw e.getCause();
+ }
+
+ verifyCurrentSelection(itemId1Present, itemId2Present);
+ }
+
+ @Test
+ public void testSettingSelection() throws Throwable {
+ try {
+ expectSelectEvent(itemId2Present, itemId1Present);
+ model.setSelected(Arrays.asList(new Object[] { itemId1Present,
+ itemId2Present }));
+ verifyCurrentSelection(itemId1Present, itemId2Present);
+
+ expectDeselectEvent(itemId1Present);
+ expectSelectEvent(itemId3Present);
+ model.setSelected(Arrays.asList(new Object[] { itemId3Present,
+ itemId2Present }));
+ verifyCurrentSelection(itemId3Present, itemId2Present);
+ } catch (Exception e) {
+ throw e.getCause();
+ }
+ }
+
+ private void expectSelectEvent(Object... selectArray) {
+ select = Arrays.asList(selectArray);
+ addListener();
+ }
+
+ private void expectDeselectEvent(Object... deselectArray) {
+ deselect = Arrays.asList(deselectArray);
+ addListener();
+ }
+
+ private void addListener() {
+ if (expectingEvent) {
+ return;
+ }
+
+ expectingEvent = true;
+ grid.addSelectionListener(new SelectionListener() {
+
+ @Override
+ public void select(SelectionEvent event) {
+ Assert.assertTrue("Selection did not contain expected items",
+ event.getAdded().containsAll(select));
+ Assert.assertTrue("Selection contained unexpected items",
+ select.containsAll(event.getAdded()));
+ select = new ArrayList<Object>();
+
+ Assert.assertTrue("Deselection did not contain expected items",
+ event.getRemoved().containsAll(deselect));
+ Assert.assertTrue("Deselection contained unexpected items",
+ deselect.containsAll(event.getRemoved()));
+ deselect = new ArrayList<Object>();
+
+ grid.removeSelectionListener(this);
+ expectingEvent = false;
+ }
+ });
+ }
+
+ private void verifyCurrentSelection(Object... selection) {
+ final List<Object> selected = Arrays.asList(selection);
+ if (model.getSelectedRows().containsAll(selected)
+ && selected.containsAll(model.getSelectedRows())) {
+ return;
+ }
+ Assert.fail("Not all items were correctly selected");
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/SingleSelectionModelTest.java b/server/src/test/java/com/vaadin/tests/server/component/grid/SingleSelectionModelTest.java
new file mode 100644
index 0000000000..c217efb935
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/grid/SingleSelectionModelTest.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2000-2014 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.grid;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.Container;
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.event.SelectionEvent;
+import com.vaadin.event.SelectionEvent.SelectionListener;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.SelectionMode;
+import com.vaadin.ui.Grid.SingleSelectionModel;
+
+public class SingleSelectionModelTest {
+
+ private Object itemId1Present = "itemId1Present";
+ private Object itemId2Present = "itemId2Present";
+
+ private Object itemIdNotPresent = "itemIdNotPresent";
+ private Container.Indexed dataSource;
+ private SingleSelectionModel model;
+ private Grid grid;
+
+ private boolean expectingEvent = false;
+
+ @Before
+ public void setUp() {
+ dataSource = createDataSource();
+ grid = new Grid(dataSource);
+ grid.setSelectionMode(SelectionMode.SINGLE);
+ model = (SingleSelectionModel) grid.getSelectionModel();
+ }
+
+ @After
+ public void tearDown() {
+ Assert.assertFalse("Some expected event did not happen.",
+ expectingEvent);
+ }
+
+ private IndexedContainer createDataSource() {
+ final IndexedContainer container = new IndexedContainer();
+ container.addItem(itemId1Present);
+ container.addItem(itemId2Present);
+ for (int i = 2; i < 10; i++) {
+ container.addItem(new Object());
+ }
+
+ return container;
+ }
+
+ @Test
+ public void testSelectAndDeselctRow() throws Throwable {
+ try {
+ expectEvent(itemId1Present, null);
+ model.select(itemId1Present);
+ expectEvent(null, itemId1Present);
+ model.select(null);
+ } catch (Exception e) {
+ throw e.getCause();
+ }
+ }
+
+ @Test
+ public void testSelectAndChangeSelectedRow() throws Throwable {
+ try {
+ expectEvent(itemId1Present, null);
+ model.select(itemId1Present);
+ expectEvent(itemId2Present, itemId1Present);
+ model.select(itemId2Present);
+ } catch (Exception e) {
+ throw e.getCause();
+ }
+ }
+
+ @Test
+ public void testRemovingSelectedRowAndThenDeselecting() throws Throwable {
+ try {
+ expectEvent(itemId2Present, null);
+ model.select(itemId2Present);
+ dataSource.removeItem(itemId2Present);
+ expectEvent(null, itemId2Present);
+ model.select(null);
+ } catch (Exception e) {
+ throw e.getCause();
+ }
+ }
+
+ @Test
+ public void testSelectAndReSelectRow() throws Throwable {
+ try {
+ expectEvent(itemId1Present, null);
+ model.select(itemId1Present);
+ expectEvent(null, null);
+ // This is no-op. Nothing should happen.
+ model.select(itemId1Present);
+ } catch (Exception e) {
+ throw e.getCause();
+ }
+ Assert.assertTrue("Should still wait for event", expectingEvent);
+ expectingEvent = false;
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testSelectNonExistentRow() {
+ model.select(itemIdNotPresent);
+ }
+
+ private void expectEvent(final Object selected, final Object deselected) {
+ expectingEvent = true;
+ grid.addSelectionListener(new SelectionListener() {
+
+ @Override
+ public void select(SelectionEvent event) {
+ if (selected != null) {
+ Assert.assertTrue(
+ "Selection did not contain expected item", event
+ .getAdded().contains(selected));
+ } else {
+ Assert.assertTrue("Unexpected selection", event.getAdded()
+ .isEmpty());
+ }
+
+ if (deselected != null) {
+ Assert.assertTrue(
+ "DeSelection did not contain expected item", event
+ .getRemoved().contains(deselected));
+ } else {
+ Assert.assertTrue("Unexpected selection", event
+ .getRemoved().isEmpty());
+ }
+
+ grid.removeSelectionListener(this);
+ expectingEvent = false;
+ }
+ });
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/TestGrid.java b/server/src/test/java/com/vaadin/tests/server/component/grid/TestGrid.java
new file mode 100644
index 0000000000..97fb2d8309
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/grid/TestGrid.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2000-2014 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.grid;
+
+import java.lang.reflect.Field;
+
+import org.easymock.EasyMock;
+
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.server.communication.data.RpcDataProviderExtension;
+import com.vaadin.ui.ConnectorTracker;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.UI;
+
+/**
+ * A Grid attached to a mock UI with a mock ConnectorTracker.
+ *
+ * @since 7.4
+ * @author Vaadin Ltd
+ */
+public class TestGrid extends Grid {
+
+ public TestGrid() {
+ super();
+ init();
+ }
+
+ public TestGrid(IndexedContainer c) {
+ super(c);
+ init();
+ }
+
+ public RpcDataProviderExtension getDataProvider() throws Exception {
+ Field dseField = Grid.class.getDeclaredField("datasourceExtension");
+ dseField.setAccessible(true);
+ return (RpcDataProviderExtension) dseField.get(this);
+ }
+
+ private void init() {
+ UI mockUI = EasyMock.createNiceMock(UI.class);
+ ConnectorTracker mockCT = EasyMock
+ .createNiceMock(ConnectorTracker.class);
+ EasyMock.expect(mockUI.getConnectorTracker()).andReturn(mockCT)
+ .anyTimes();
+ EasyMock.replay(mockUI, mockCT);
+
+ setParent(mockUI);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/declarative/GridColumnDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/grid/declarative/GridColumnDeclarativeTest.java
new file mode 100644
index 0000000000..21892634a0
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/grid/declarative/GridColumnDeclarativeTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2000-2014 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.grid.declarative;
+
+import org.junit.Test;
+
+import com.vaadin.ui.Grid;
+
+public class GridColumnDeclarativeTest extends GridDeclarativeTestBase {
+
+ @Test
+ public void testSimpleGridColumns() {
+ String design = "<vaadin-grid><table>"//
+ + "<colgroup>"
+ + " <col sortable width='100' property-id='Column1'>"
+ + " <col sortable=false max-width='200' expand='2' property-id='Column2'>"
+ + " <col sortable editable=false resizable=false min-width='15' expand='1' property-id='Column3'>"
+ + " <col sortable hidable hiding-toggle-caption='col 4' property-id='Column4'>"
+ + " <col sortable hidden property-id='Column5'>"
+ + "</colgroup>" //
+ + "<thead />" //
+ + "</table></vaadin-grid>";
+ Grid grid = new Grid();
+ grid.addColumn("Column1", String.class).setWidth(100);
+ grid.addColumn("Column2", String.class).setMaximumWidth(200)
+ .setExpandRatio(2).setSortable(false);
+ grid.addColumn("Column3", String.class).setMinimumWidth(15)
+ .setExpandRatio(1).setEditable(false).setResizable(false);
+ grid.addColumn("Column4", String.class).setHidable(true)
+ .setHidingToggleCaption("col 4").setResizable(true);
+ grid.addColumn("Column5", String.class).setHidden(true);
+
+ // Remove the default header
+ grid.removeHeaderRow(grid.getDefaultHeaderRow());
+
+ // Use the read grid component to do another pass on write.
+ testRead(design, grid, true);
+ testWrite(design, grid);
+ }
+
+ @Test
+ public void testReadColumnsWithoutPropertyId() {
+ String design = "<vaadin-grid><table>"//
+ + "<colgroup>"
+ + " <col sortable=true width='100' property-id='Column1'>"
+ + " <col sortable=true max-width='200' expand='2'>" // property-id="property-1"
+ + " <col sortable=true min-width='15' expand='1' property-id='Column3'>"
+ + " <col sortable=true hidden=true hidable=true hiding-toggle-caption='col 4'>" // property-id="property-3"
+ + "</colgroup>" //
+ + "</table></vaadin-grid>";
+ Grid grid = new Grid();
+ grid.addColumn("Column1", String.class).setWidth(100);
+ grid.addColumn("property-1", String.class).setMaximumWidth(200)
+ .setExpandRatio(2);
+ grid.addColumn("Column3", String.class).setMinimumWidth(15)
+ .setExpandRatio(1);
+ grid.addColumn("property-3", String.class).setHidable(true)
+ .setHidden(true).setHidingToggleCaption("col 4");
+
+ testRead(design, grid);
+ }
+
+ @Test
+ public void testReadEmptyExpand() {
+ String design = "<vaadin-grid><table>"//
+ + "<colgroup>"
+ + " <col sortable=true expand />"
+ + "</colgroup>" //
+ + "</table></vaadin-grid>";
+
+ Grid grid = new Grid();
+ grid.addColumn("property-0", String.class).setExpandRatio(1);
+
+ testRead(design, grid);
+ }
+
+ @Test
+ public void testReadColumnWithNoAttributes() {
+ String design = "<vaadin-grid><table>"//
+ + "<colgroup>" //
+ + " <col />" //
+ + "</colgroup>" //
+ + "</table></vaadin-grid>";
+
+ Grid grid = new Grid();
+ grid.addColumn("property-0", String.class);
+
+ testRead(design, grid);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/declarative/GridDeclarativeAttributeTest.java b/server/src/test/java/com/vaadin/tests/server/component/grid/declarative/GridDeclarativeAttributeTest.java
new file mode 100644
index 0000000000..41f967ac16
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/grid/declarative/GridDeclarativeAttributeTest.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2000-2014 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.grid.declarative;
+
+import static org.junit.Assert.assertSame;
+
+import org.junit.Test;
+
+import com.vaadin.shared.ui.grid.HeightMode;
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.MultiSelectionModel;
+import com.vaadin.ui.Grid.NoSelectionModel;
+import com.vaadin.ui.Grid.SingleSelectionModel;
+
+/**
+ * Tests declarative support for {@link Grid} properties.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class GridDeclarativeAttributeTest extends DeclarativeTestBase<Grid> {
+
+ @Test
+ public void testBasicAttributes() {
+
+ String design = "<vaadin-grid editable rows=20 frozen-columns=-1 "
+ + "editor-save-caption='Tallenna' editor-cancel-caption='Peruuta' column-reordering-allowed>";
+
+ Grid grid = new Grid();
+ grid.setEditorEnabled(true);
+ grid.setHeightMode(HeightMode.ROW);
+ grid.setHeightByRows(20);
+ grid.setFrozenColumnCount(-1);
+ grid.setEditorSaveCaption("Tallenna");
+ grid.setEditorCancelCaption("Peruuta");
+ grid.setColumnReorderingAllowed(true);
+
+ testRead(design, grid);
+ testWrite(design, grid);
+ }
+
+ @Test
+ public void testFrozenColumnsAttributes() {
+ String design = "<vaadin-grid frozen-columns='2'><table>" //
+ + "<colgroup><col><col><col></colgroup></table></vaadin-grid>";
+
+ Grid grid = new Grid();
+ grid.addColumn("property-0", String.class);
+ grid.addColumn("property-1", String.class);
+ grid.addColumn("property-2", String.class);
+ grid.setFrozenColumnCount(2);
+
+ testRead(design, grid);
+ }
+
+ @Test
+ public void testSelectionMode() {
+ String design = "<vaadin-grid selection-mode='none'>";
+ assertSame(NoSelectionModel.class, read(design).getSelectionModel()
+ .getClass());
+
+ design = "<vaadin-grid selection-mode='single'>";
+ assertSame(SingleSelectionModel.class, read(design).getSelectionModel()
+ .getClass());
+
+ design = "<vaadin-grid selection-mode='multi'>";
+ assertSame(MultiSelectionModel.class, read(design).getSelectionModel()
+ .getClass());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/declarative/GridDeclarativeTestBase.java b/server/src/test/java/com/vaadin/tests/server/component/grid/declarative/GridDeclarativeTestBase.java
new file mode 100644
index 0000000000..9424d89ecf
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/grid/declarative/GridDeclarativeTestBase.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2000-2014 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.grid.declarative;
+
+import java.util.List;
+
+import org.junit.Assert;
+
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.Column;
+import com.vaadin.ui.Grid.FooterCell;
+import com.vaadin.ui.Grid.FooterRow;
+import com.vaadin.ui.Grid.HeaderCell;
+import com.vaadin.ui.Grid.HeaderRow;
+
+public class GridDeclarativeTestBase extends DeclarativeTestBase<Grid> {
+
+ @Override
+ public Grid testRead(String design, Grid expected) {
+ return testRead(design, expected, false);
+ }
+
+ public Grid testRead(String design, Grid expected, boolean retestWrite) {
+ return testRead(design, expected, retestWrite, false);
+ }
+
+ public Grid testRead(String design, Grid expected, boolean retestWrite,
+ boolean writeData) {
+ Grid actual = super.testRead(design, expected);
+
+ compareGridColumns(expected, actual);
+ compareHeaders(expected, actual);
+ compareFooters(expected, actual);
+
+ if (retestWrite) {
+ testWrite(design, actual, writeData);
+ }
+
+ return actual;
+ }
+
+ private void compareHeaders(Grid expected, Grid actual) {
+ Assert.assertEquals("Different header row count",
+ expected.getHeaderRowCount(), actual.getHeaderRowCount());
+ for (int i = 0; i < expected.getHeaderRowCount(); ++i) {
+ HeaderRow expectedRow = expected.getHeaderRow(i);
+ HeaderRow actualRow = actual.getHeaderRow(i);
+
+ if (expectedRow.equals(expected.getDefaultHeaderRow())) {
+ Assert.assertEquals("Different index for default header row",
+ actual.getDefaultHeaderRow(), actualRow);
+ }
+
+ for (Column c : expected.getColumns()) {
+ String baseError = "Difference when comparing cell for "
+ + c.toString() + " on header row " + i + ": ";
+ Object propertyId = c.getPropertyId();
+ HeaderCell expectedCell = expectedRow.getCell(propertyId);
+ HeaderCell actualCell = actualRow.getCell(propertyId);
+
+ switch (expectedCell.getCellType()) {
+ case TEXT:
+ Assert.assertEquals(baseError + "Text content",
+ expectedCell.getText(), actualCell.getText());
+ break;
+ case HTML:
+ Assert.assertEquals(baseError + "HTML content",
+ expectedCell.getHtml(), actualCell.getHtml());
+ break;
+ case WIDGET:
+ assertEquals(baseError + "Component content",
+ expectedCell.getComponent(),
+ actualCell.getComponent());
+ break;
+ }
+ }
+ }
+ }
+
+ private void compareFooters(Grid expected, Grid actual) {
+ Assert.assertEquals("Different footer row count",
+ expected.getFooterRowCount(), actual.getFooterRowCount());
+ for (int i = 0; i < expected.getFooterRowCount(); ++i) {
+ FooterRow expectedRow = expected.getFooterRow(i);
+ FooterRow actualRow = actual.getFooterRow(i);
+
+ for (Column c : expected.getColumns()) {
+ String baseError = "Difference when comparing cell for "
+ + c.toString() + " on footer row " + i + ": ";
+ Object propertyId = c.getPropertyId();
+ FooterCell expectedCell = expectedRow.getCell(propertyId);
+ FooterCell actualCell = actualRow.getCell(propertyId);
+
+ switch (expectedCell.getCellType()) {
+ case TEXT:
+ Assert.assertEquals(baseError + "Text content",
+ expectedCell.getText(), actualCell.getText());
+ break;
+ case HTML:
+ Assert.assertEquals(baseError + "HTML content",
+ expectedCell.getHtml(), actualCell.getHtml());
+ break;
+ case WIDGET:
+ assertEquals(baseError + "Component content",
+ expectedCell.getComponent(),
+ actualCell.getComponent());
+ break;
+ }
+ }
+ }
+ }
+
+ private void compareGridColumns(Grid expected, Grid actual) {
+ List<Column> columns = expected.getColumns();
+ List<Column> actualColumns = actual.getColumns();
+ Assert.assertEquals("Different amount of columns", columns.size(),
+ actualColumns.size());
+ for (int i = 0; i < columns.size(); ++i) {
+ Column col1 = columns.get(i);
+ Column col2 = actualColumns.get(i);
+ String baseError = "Error when comparing columns for property "
+ + col1.getPropertyId() + ": ";
+ assertEquals(baseError + "Property id", col1.getPropertyId(),
+ col2.getPropertyId());
+ assertEquals(baseError + "Width", col1.getWidth(), col2.getWidth());
+ assertEquals(baseError + "Maximum width", col1.getMaximumWidth(),
+ col2.getMaximumWidth());
+ assertEquals(baseError + "Minimum width", col1.getMinimumWidth(),
+ col2.getMinimumWidth());
+ assertEquals(baseError + "Expand ratio", col1.getExpandRatio(),
+ col2.getExpandRatio());
+ assertEquals(baseError + "Sortable", col1.isSortable(),
+ col2.isSortable());
+ assertEquals(baseError + "Editable", col1.isEditable(),
+ col2.isEditable());
+ assertEquals(baseError + "Hidable", col1.isHidable(),
+ col2.isHidable());
+ assertEquals(baseError + "Hidden", col1.isHidden(), col2.isHidden());
+ assertEquals(baseError + "HidingToggleCaption",
+ col1.getHidingToggleCaption(),
+ col2.getHidingToggleCaption());
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/declarative/GridHeaderFooterDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/grid/declarative/GridHeaderFooterDeclarativeTest.java
new file mode 100644
index 0000000000..d64a877d81
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/grid/declarative/GridHeaderFooterDeclarativeTest.java
@@ -0,0 +1,356 @@
+/*
+ * Copyright 2000-2014 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.grid.declarative;
+
+import org.jsoup.nodes.Element;
+import org.jsoup.parser.Tag;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.shared.ui.label.ContentMode;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.Column;
+import com.vaadin.ui.Grid.FooterRow;
+import com.vaadin.ui.Grid.HeaderRow;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.declarative.DesignContext;
+
+public class GridHeaderFooterDeclarativeTest extends GridDeclarativeTestBase {
+
+ @Test
+ public void testSingleDefaultHeader() {
+ //@formatter:off
+ String design = "<vaadin-grid><table>"
+ + "<colgroup>"
+ + " <col sortable property-id='Column1'>"
+ + " <col sortable property-id='Column2'>"
+ + " <col sortable property-id='Column3'>"
+ + "</colgroup>"
+ + "<thead>"
+ + " <tr default><th plain-text>Column1<th plain-text>Column2<th plain-text>Column3</tr>"
+ + "</thead>"
+ + "</table></vaadin-grid>";
+ //@formatter:on
+ Grid grid = new Grid();
+ grid.addColumn("Column1", String.class);
+ grid.addColumn("Column2", String.class);
+ grid.addColumn("Column3", String.class);
+
+ testWrite(design, grid);
+ testRead(design, grid, true);
+ }
+
+ @Test
+ public void testSingleDefaultHTMLHeader() {
+ //@formatter:off
+ String design = "<vaadin-grid><table>"
+ + "<colgroup>"
+ + " <col sortable property-id='Column1'>"
+ + " <col sortable property-id='Column2'>"
+ + " <col sortable property-id='Column3'>" + "</colgroup>"
+ + "<thead>"
+ + " <tr default><th>Column1<th>Column2<th>Column3</tr>"
+ + "</thead>"
+ + "</table></vaadin-grid>";
+ //@formatter:on
+ Grid grid = new Grid();
+ grid.addColumn("Column1", String.class);
+ grid.addColumn("Column2", String.class);
+ grid.addColumn("Column3", String.class);
+
+ HeaderRow row = grid.getDefaultHeaderRow();
+ for (Column c : grid.getColumns()) {
+ row.getCell(c.getPropertyId()).setHtml(c.getHeaderCaption());
+ }
+
+ testWrite(design, grid);
+ testRead(design, grid, true);
+ }
+
+ @Test
+ public void testNoHeaderRows() {
+ //@formatter:off
+ String design = "<vaadin-grid><table>"
+ + "<colgroup>"
+ + " <col sortable property-id='Column1'>"
+ + "</colgroup>"
+ + "<thead />"
+ + "</table></vaadin-grid>";
+ //@formatter:on
+ Grid grid = new Grid();
+ grid.addColumn("Column1", String.class);
+ grid.removeHeaderRow(grid.getDefaultHeaderRow());
+
+ testWrite(design, grid);
+ testRead(design, grid, true);
+ }
+
+ @Test
+ public void testMultipleHeadersWithColSpans() {
+ //@formatter:off
+ String design = "<vaadin-grid><table>"
+ + "<colgroup>"
+ + " <col sortable property-id='Column1'>"
+ + " <col sortable property-id='Column2'>"
+ + " <col sortable property-id='Column3'>"
+ + "</colgroup>"
+ + "<thead>"
+ + " <tr><th colspan=3>Baz</tr>"
+ + " <tr default><th>Column1<th>Column2<th>Column3</tr>"
+ + " <tr><th>Foo<th colspan=2>Bar</tr>"
+ + "</thead>"
+ + "</table></vaadin-grid>";
+ //@formatter:on
+ Grid grid = new Grid();
+ grid.addColumn("Column1", String.class);
+ grid.addColumn("Column2", String.class);
+ grid.addColumn("Column3", String.class);
+
+ HeaderRow row = grid.getDefaultHeaderRow();
+ for (Column c : grid.getColumns()) {
+ row.getCell(c.getPropertyId()).setHtml(c.getHeaderCaption());
+ }
+
+ grid.prependHeaderRow().join("Column1", "Column2", "Column3")
+ .setHtml("Baz");
+ row = grid.appendHeaderRow();
+ row.getCell("Column1").setHtml("Foo");
+ row.join("Column2", "Column3").setHtml("Bar");
+
+ testWrite(design, grid);
+ testRead(design, grid, true);
+ }
+
+ @Test
+ public void testSingleDefaultFooter() {
+ //@formatter:off
+ String design = "<vaadin-grid><table>"
+ + "<colgroup>"
+ + " <col sortable property-id='Column1'>"
+ + " <col sortable property-id='Column2'>"
+ + " <col sortable property-id='Column3'>"
+ + "</colgroup>"
+ + "<thead />" // No headers read or written
+ + "<tfoot>"
+ + " <tr><td plain-text>Column1<td plain-text>Column2<td plain-text>Column3</tr>"
+ + "</tfoot>"
+ + "</table></vaadin-grid>";
+ //@formatter:on
+ Grid grid = new Grid();
+ grid.addColumn("Column1", String.class);
+ grid.addColumn("Column2", String.class);
+ grid.addColumn("Column3", String.class);
+
+ FooterRow row = grid.appendFooterRow();
+ for (Column c : grid.getColumns()) {
+ row.getCell(c.getPropertyId()).setText(c.getHeaderCaption());
+ }
+
+ grid.removeHeaderRow(grid.getDefaultHeaderRow());
+
+ testWrite(design, grid);
+ testRead(design, grid, true);
+ }
+
+ @Test
+ public void testSingleDefaultHTMLFooter() {
+ //@formatter:off
+ String design = "<vaadin-grid><table>"
+ + "<colgroup>"
+ + " <col sortable property-id='Column1'>"
+ + " <col sortable property-id='Column2'>"
+ + " <col sortable property-id='Column3'>" + "</colgroup>"
+ + "<thead />" // No headers read or written
+ + "<tfoot>"
+ + " <tr><td>Column1<td>Column2<td>Column3</tr>"
+ + "</tfoot>"
+ + "</table></vaadin-grid>";
+ //@formatter:on
+
+ Grid grid = new Grid();
+ grid.addColumn("Column1", String.class);
+ grid.addColumn("Column2", String.class);
+ grid.addColumn("Column3", String.class);
+
+ FooterRow row = grid.appendFooterRow();
+ for (Column c : grid.getColumns()) {
+ row.getCell(c.getPropertyId()).setHtml(c.getHeaderCaption());
+ }
+
+ grid.removeHeaderRow(grid.getDefaultHeaderRow());
+
+ testWrite(design, grid);
+ testRead(design, grid, true);
+ }
+
+ @Test
+ public void testMultipleFootersWithColSpans() {
+ //@formatter:off
+ String design = "<vaadin-grid><table>"
+ + "<colgroup>"
+ + " <col sortable property-id='Column1'>"
+ + " <col sortable property-id='Column2'>"
+ + " <col sortable property-id='Column3'>"
+ + "</colgroup>"
+ + "<thead />" // No headers read or written.
+ + "<tfoot>"
+ + " <tr><td colspan=3>Baz</tr>"
+ + " <tr><td>Column1<td>Column2<td>Column3</tr>"
+ + " <tr><td>Foo<td colspan=2>Bar</tr>"
+ + "</tfoot>"
+ + "</table></vaadin-grid>";
+ //@formatter:on
+
+ Grid grid = new Grid();
+ grid.addColumn("Column1", String.class);
+ grid.addColumn("Column2", String.class);
+ grid.addColumn("Column3", String.class);
+
+ FooterRow row = grid.appendFooterRow();
+ for (Column c : grid.getColumns()) {
+ row.getCell(c.getPropertyId()).setHtml(c.getHeaderCaption());
+ }
+
+ grid.prependFooterRow().join("Column1", "Column2", "Column3")
+ .setHtml("Baz");
+ row = grid.appendFooterRow();
+ row.getCell("Column1").setHtml("Foo");
+ row.join("Column2", "Column3").setHtml("Bar");
+
+ grid.removeHeaderRow(grid.getDefaultHeaderRow());
+
+ testWrite(design, grid);
+ testRead(design, grid, true);
+ }
+
+ @Test
+ public void testComponentInGridHeader() {
+ //@formatter:off
+ String design = "<vaadin-grid><table>"
+ + "<colgroup>"
+ + " <col sortable property-id='Column1'>"
+ + "</colgroup>"
+ + "<thead>"
+ + "<tr default><th><vaadin-label><b>Foo</b></vaadin-label></tr>"
+ + "</thead>"
+ + "</table></vaadin-grid>";
+ //@formatter:on
+ Label component = new Label("<b>Foo</b>");
+ component.setContentMode(ContentMode.HTML);
+
+ Grid grid = new Grid();
+ grid.addColumn("Column1", String.class);
+ grid.getDefaultHeaderRow().getCell("Column1").setComponent(component);
+
+ testRead(design, grid, true);
+ testWrite(design, grid);
+ }
+
+ @Test
+ public void testComponentInGridFooter() {
+ //@formatter:off
+ String design = "<vaadin-grid><table>"
+ + "<colgroup>"
+ + " <col sortable property-id='Column1'>"
+ + "</colgroup>"
+ + "<thead />" // No headers read or written
+ + "<tfoot>"
+ + "<tr><td><vaadin-label><b>Foo</b></vaadin-label></tr>"
+ + "</tfoot>"
+ + "</table></vaadin-grid>";
+ //@formatter:on
+
+ Label component = new Label("<b>Foo</b>");
+ component.setContentMode(ContentMode.HTML);
+
+ Grid grid = new Grid();
+ grid.addColumn("Column1", String.class);
+ grid.prependFooterRow().getCell("Column1").setComponent(component);
+ grid.removeHeaderRow(grid.getDefaultHeaderRow());
+
+ testRead(design, grid, true);
+ testWrite(design, grid);
+ }
+
+ @Test
+ public void testHtmlEntitiesinGridHeaderFooter() {
+ //@formatter:off
+ String design = "<vaadin-grid><table>"
+ + "<colgroup>"
+ + " <col sortable=\"true\" property-id=\"> test\">"
+ + "</colgroup>"
+ + "<thead>"
+ + " <tr><th plain-text=\"true\">&gt; Test</th></tr>"
+ + "</thead>"
+ + "<tfoot>"
+ + " <tr><td plain-text=\"true\">&gt; Test</td></tr>"
+ + "</tfoot>"
+ + "<tbody />"
+ + "</table></vaadin-grid>";
+ //@formatter:on
+
+ Grid grid = read(design);
+ String actualHeader = grid.getHeaderRow(0).getCell("> test").getText();
+ String actualFooter = grid.getFooterRow(0).getCell("> test").getText();
+ String expected = "> Test";
+
+ Assert.assertEquals(expected, actualHeader);
+ Assert.assertEquals(expected, actualFooter);
+
+ design = design.replace("plain-text=\"true\"", "");
+ grid = read(design);
+ actualHeader = grid.getHeaderRow(0).getCell("> test").getHtml();
+ actualFooter = grid.getFooterRow(0).getCell("> test").getHtml();
+ expected = "&gt; Test";
+
+ Assert.assertEquals(expected, actualHeader);
+ Assert.assertEquals(expected, actualFooter);
+
+ grid = new Grid();
+ grid.setColumns("test");
+ HeaderRow header = grid.addHeaderRowAt(0);
+ FooterRow footer = grid.addFooterRowAt(0);
+ grid.removeHeaderRow(grid.getDefaultHeaderRow());
+
+ // entities should be encoded when writing back, not interpreted as HTML
+ header.getCell("test").setText("&amp; Test");
+ footer.getCell("test").setText("&amp; Test");
+
+ Element root = new Element(Tag.valueOf("vaadin-grid"), "");
+ grid.writeDesign(root, new DesignContext());
+
+ Assert.assertEquals("&amp;amp; Test", root.getElementsByTag("th")
+ .get(0).html());
+ Assert.assertEquals("&amp;amp; Test", root.getElementsByTag("td")
+ .get(0).html());
+
+ header = grid.addHeaderRowAt(0);
+ footer = grid.addFooterRowAt(0);
+
+ // entities should not be encoded, this is already given as HTML
+ header.getCell("test").setHtml("&amp; Test");
+ footer.getCell("test").setHtml("&amp; Test");
+
+ root = new Element(Tag.valueOf("vaadin-grid"), "");
+ grid.writeDesign(root, new DesignContext());
+
+ Assert.assertEquals("&amp; Test", root.getElementsByTag("th").get(0)
+ .html());
+ Assert.assertEquals("&amp; Test", root.getElementsByTag("td").get(0)
+ .html());
+
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/declarative/GridInlineDataDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/grid/declarative/GridInlineDataDeclarativeTest.java
new file mode 100644
index 0000000000..df8e864309
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/grid/declarative/GridInlineDataDeclarativeTest.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2000-2014 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.grid.declarative;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.Container;
+import com.vaadin.ui.Grid;
+
+public class GridInlineDataDeclarativeTest extends GridDeclarativeTestBase {
+
+ @Test
+ public void testSimpleInlineData() {
+ String design = "<vaadin-grid><table>"//
+ + "<colgroup>"
+ + " <col sortable property-id='Col1' />"
+ + "</colgroup>" //
+ + "<thead />" // No headers read or written
+ + "<tbody>" //
+ + "<tr><td>Foo</tr>" //
+ + "<tr><td>Bar</tr>" //
+ + "<tr><td>Baz</tr>" //
+ + "</tbody>" //
+ + "</table></vaadin-grid>";
+
+ Grid grid = new Grid();
+ grid.addColumn("Col1", String.class);
+ grid.addRow("Foo");
+ grid.addRow("Bar");
+ grid.addRow("Baz");
+
+ // Remove default header
+ grid.removeHeaderRow(grid.getDefaultHeaderRow());
+
+ testWrite(design, grid, true);
+ testRead(design, grid, true, true);
+ }
+
+ @Test
+ public void testMultipleColumnsInlineData() {
+ String design = "<vaadin-grid><table>"//
+ + "<colgroup>"
+ + " <col sortable property-id='Col1' />"
+ + " <col sortable property-id='Col2' />"
+ + " <col sortable property-id='Col3' />" //
+ + "</colgroup>" //
+ + "<thead />" // No headers read or written
+ + "<tbody>" //
+ + "<tr><td>Foo<td>Bar<td>Baz</tr>" //
+ + "<tr><td>My<td>Summer<td>Car</tr>" //
+ + "</tbody>" //
+ + "</table></vaadin-grid>";
+
+ Grid grid = new Grid();
+ grid.addColumn("Col1", String.class);
+ grid.addColumn("Col2", String.class);
+ grid.addColumn("Col3", String.class);
+ grid.addRow("Foo", "Bar", "Baz");
+ grid.addRow("My", "Summer", "Car");
+
+ // Remove default header
+ grid.removeHeaderRow(grid.getDefaultHeaderRow());
+
+ testWrite(design, grid, true);
+ testRead(design, grid, true, true);
+ }
+
+ @Test
+ public void testMultipleColumnsInlineDataReordered() {
+ String design = "<vaadin-grid><table>"//
+ + "<colgroup>"
+ + " <col sortable property-id='Col2' />"
+ + " <col sortable property-id='Col3' />"
+ + " <col sortable property-id='Col1' />" //
+ + "</colgroup>" //
+ + "<thead />" // No headers read or written
+ + "<tbody>" //
+ + "<tr><td>Bar<td>Baz<td>Foo</tr>" //
+ + "<tr><td>Summer<td>Car<td>My</tr>" //
+ + "</tbody>" //
+ + "</table></vaadin-grid>";
+
+ Grid grid = new Grid();
+ grid.addColumn("Col1", String.class);
+ grid.addColumn("Col2", String.class);
+ grid.addColumn("Col3", String.class);
+ grid.addRow("Foo", "Bar", "Baz");
+ grid.addRow("My", "Summer", "Car");
+ grid.setColumnOrder("Col2", "Col3", "Col1");
+
+ // Remove default header
+ grid.removeHeaderRow(grid.getDefaultHeaderRow());
+
+ testWrite(design, grid, true);
+ testRead(design, grid, true, true);
+ }
+
+ @Test
+ public void testHtmlEntities() {
+ String design = "<vaadin-grid><table>"//
+ + "<colgroup>"
+ + " <col property-id='test' />"
+ + "</colgroup>" //
+ + "<thead />" // No headers read or written
+ + "<tbody>" //
+ + " <tr><td>&amp;Test</tr></td>"
+ + "</tbody>"
+ + "</table></vaadin-grid>";
+
+ Grid read = read(design);
+ Container cds = read.getContainerDataSource();
+ Assert.assertEquals("&amp;Test",
+ cds.getItem(cds.getItemIds().iterator().next())
+ .getItemProperty("test").getValue());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/declarative/GridStructureDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/grid/declarative/GridStructureDeclarativeTest.java
new file mode 100644
index 0000000000..d60df4c23b
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/grid/declarative/GridStructureDeclarativeTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2000-2014 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.grid.declarative;
+
+import org.junit.Test;
+
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.declarative.DesignException;
+
+public class GridStructureDeclarativeTest extends GridDeclarativeTestBase {
+
+ @Test
+ public void testReadEmptyGrid() {
+ String design = "<vaadin-grid />";
+ testRead(design, new Grid(), false);
+ }
+
+ @Test
+ public void testEmptyGrid() {
+ String design = "<vaadin-grid></vaadin-grid>";
+ Grid expected = new Grid();
+ testWrite(design, expected);
+ testRead(design, expected, true);
+ }
+
+ @Test(expected = DesignException.class)
+ public void testMalformedGrid() {
+ String design = "<vaadin-grid><vaadin-label /></vaadin-grid>";
+ testRead(design, new Grid());
+ }
+
+ @Test(expected = DesignException.class)
+ public void testGridWithNoColGroup() {
+ String design = "<vaadin-grid><table><thead><tr><th>Foo</tr></thead></table></vaadin-grid>";
+ testRead(design, new Grid());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/sort/SortTest.java b/server/src/test/java/com/vaadin/tests/server/component/grid/sort/SortTest.java
new file mode 100644
index 0000000000..2a682df2e5
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/grid/sort/SortTest.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2000-2014 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.grid.sort;
+
+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.sort.Sort;
+import com.vaadin.data.sort.SortOrder;
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.event.SortEvent;
+import com.vaadin.event.SortEvent.SortListener;
+import com.vaadin.shared.data.sort.SortDirection;
+import com.vaadin.ui.Grid;
+
+public class SortTest {
+
+ class DummySortingIndexedContainer extends IndexedContainer {
+
+ private Object[] expectedProperties;
+ private boolean[] expectedAscending;
+ private boolean sorted = true;
+
+ @Override
+ public void sort(Object[] propertyId, boolean[] ascending) {
+ Assert.assertEquals(
+ "Different amount of expected and actual properties,",
+ expectedProperties.length, propertyId.length);
+ Assert.assertEquals(
+ "Different amount of expected and actual directions",
+ expectedAscending.length, ascending.length);
+ for (int i = 0; i < propertyId.length; ++i) {
+ Assert.assertEquals("Sorting properties differ",
+ expectedProperties[i], propertyId[i]);
+ Assert.assertEquals("Sorting directions differ",
+ expectedAscending[i], ascending[i]);
+ }
+ sorted = true;
+ }
+
+ public void expectedSort(Object[] properties, SortDirection[] directions) {
+ assert directions.length == properties.length : "Array dimensions differ";
+ expectedProperties = properties;
+ expectedAscending = new boolean[directions.length];
+ for (int i = 0; i < directions.length; ++i) {
+ expectedAscending[i] = (directions[i] == SortDirection.ASCENDING);
+ }
+ sorted = false;
+ }
+
+ public boolean isSorted() {
+ return sorted;
+ }
+ }
+
+ class RegisteringSortChangeListener implements SortListener {
+ private List<SortOrder> order;
+
+ @Override
+ public void sort(SortEvent event) {
+ assert order == null : "The same listener was notified multipe times without checking";
+
+ order = event.getSortOrder();
+ }
+
+ public void assertEventFired(SortOrder... expectedOrder) {
+ Assert.assertEquals(Arrays.asList(expectedOrder), order);
+
+ // Reset for nest test
+ order = null;
+ }
+
+ }
+
+ private DummySortingIndexedContainer container;
+ private RegisteringSortChangeListener listener;
+ private Grid grid;
+
+ @Before
+ public void setUp() {
+ container = createContainer();
+ container.expectedSort(new Object[] {}, new SortDirection[] {});
+
+ listener = new RegisteringSortChangeListener();
+
+ grid = new Grid(container);
+ grid.addSortListener(listener);
+ }
+
+ @After
+ public void tearDown() {
+ Assert.assertTrue("Container was not sorted after the test.",
+ container.isSorted());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testInvalidSortDirection() {
+ Sort.by("foo", null);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testSortOneColumnMultipleTimes() {
+ Sort.by("foo").then("bar").then("foo");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testSortingByUnexistingProperty() {
+ grid.sort("foobar");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testSortingByUnsortableProperty() {
+ container.addContainerProperty("foobar", Object.class, null);
+ grid.sort("foobar");
+ }
+
+ @Test
+ public void testGridDirectSortAscending() {
+ container.expectedSort(new Object[] { "foo" },
+ new SortDirection[] { SortDirection.ASCENDING });
+ grid.sort("foo");
+
+ listener.assertEventFired(new SortOrder("foo", SortDirection.ASCENDING));
+ }
+
+ @Test
+ public void testGridDirectSortDescending() {
+ container.expectedSort(new Object[] { "foo" },
+ new SortDirection[] { SortDirection.DESCENDING });
+ grid.sort("foo", SortDirection.DESCENDING);
+
+ listener.assertEventFired(new SortOrder("foo", SortDirection.DESCENDING));
+ }
+
+ @Test
+ public void testGridSortBy() {
+ container.expectedSort(new Object[] { "foo", "bar", "baz" },
+ new SortDirection[] { SortDirection.ASCENDING,
+ SortDirection.ASCENDING, SortDirection.DESCENDING });
+ grid.sort(Sort.by("foo").then("bar")
+ .then("baz", SortDirection.DESCENDING));
+
+ listener.assertEventFired(
+ new SortOrder("foo", SortDirection.ASCENDING), new SortOrder(
+ "bar", SortDirection.ASCENDING), new SortOrder("baz",
+ SortDirection.DESCENDING));
+
+ }
+
+ @Test
+ public void testChangeContainerAfterSorting() {
+ class Person {
+ }
+
+ container.expectedSort(new Object[] { "foo", "bar", "baz" },
+ new SortDirection[] { SortDirection.ASCENDING,
+ SortDirection.ASCENDING, SortDirection.DESCENDING });
+ grid.sort(Sort.by("foo").then("bar")
+ .then("baz", SortDirection.DESCENDING));
+
+ listener.assertEventFired(
+ new SortOrder("foo", SortDirection.ASCENDING), new SortOrder(
+ "bar", SortDirection.ASCENDING), new SortOrder("baz",
+ SortDirection.DESCENDING));
+
+ container = new DummySortingIndexedContainer();
+ container.addContainerProperty("foo", Person.class, null);
+ container.addContainerProperty("baz", String.class, "");
+ container.addContainerProperty("bar", Person.class, null);
+ container.expectedSort(new Object[] { "baz" },
+ new SortDirection[] { SortDirection.DESCENDING });
+ grid.setContainerDataSource(container);
+
+ listener.assertEventFired(new SortOrder("baz", SortDirection.DESCENDING));
+
+ }
+
+ private DummySortingIndexedContainer createContainer() {
+ DummySortingIndexedContainer container = new DummySortingIndexedContainer();
+ container.addContainerProperty("foo", Integer.class, 0);
+ container.addContainerProperty("bar", Integer.class, 0);
+ container.addContainerProperty("baz", Integer.class, 0);
+ return container;
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/gridlayout/DefaultAlignmentTest.java b/server/src/test/java/com/vaadin/tests/server/component/gridlayout/DefaultAlignmentTest.java
new file mode 100644
index 0000000000..9b6368474f
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/gridlayout/DefaultAlignmentTest.java
@@ -0,0 +1,45 @@
+package com.vaadin.tests.server.component.gridlayout;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.GridLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.TextField;
+
+public class DefaultAlignmentTest {
+
+ private GridLayout gridLayout;
+
+ @Before
+ public void setup() {
+ gridLayout = new GridLayout(2, 2);
+ }
+
+ @Test
+ public void testDefaultAlignment() {
+ Label label = new Label("A label");
+ TextField tf = new TextField("A TextField");
+ gridLayout.addComponent(label);
+ gridLayout.addComponent(tf);
+ Assert.assertEquals(Alignment.TOP_LEFT,
+ gridLayout.getComponentAlignment(label));
+ Assert.assertEquals(Alignment.TOP_LEFT,
+ gridLayout.getComponentAlignment(tf));
+ }
+
+ @Test
+ public void testAlteredDefaultAlignment() {
+ Label label = new Label("A label");
+ TextField tf = new TextField("A TextField");
+ gridLayout.setDefaultComponentAlignment(Alignment.MIDDLE_CENTER);
+ gridLayout.addComponent(label);
+ gridLayout.addComponent(tf);
+ Assert.assertEquals(Alignment.MIDDLE_CENTER,
+ gridLayout.getComponentAlignment(label));
+ Assert.assertEquals(Alignment.MIDDLE_CENTER,
+ gridLayout.getComponentAlignment(tf));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/gridlayout/GridLayoutDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/gridlayout/GridLayoutDeclarativeTest.java
new file mode 100644
index 0000000000..0e4293481e
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/gridlayout/GridLayoutDeclarativeTest.java
@@ -0,0 +1,288 @@
+/*
+ * Copyright 2000-2014 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.gridlayout;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.shared.ui.label.ContentMode;
+import com.vaadin.tests.server.component.DeclarativeMarginTestBase;
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.GridLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.declarative.Design;
+import com.vaadin.ui.declarative.DesignContext;
+
+public class GridLayoutDeclarativeTest extends
+ DeclarativeMarginTestBase<GridLayout> {
+
+ @Test
+ public void testMargins() {
+ testMargins("vaadin-grid-layout");
+ }
+
+ @Test
+ public void testSimpleGridLayout() {
+ Button b1 = new Button("Button 0,0");
+ Button b2 = new Button("Button 0,1");
+ Button b3 = new Button("Button 1,0");
+ Button b4 = new Button("Button 1,1");
+ b1.setCaptionAsHtml(true);
+ b2.setCaptionAsHtml(true);
+ b3.setCaptionAsHtml(true);
+ b4.setCaptionAsHtml(true);
+ String design = "<vaadin-grid-layout><row>" //
+ + "<column expand=1>" + writeChild(b1) + "</column>" //
+ + "<column expand=3>" + writeChild(b2) + "</column>" //
+ + "</row><row>" //
+ + "<column>" + writeChild(b3) + "</column>" //
+ + "<column>" + writeChild(b4) + "</column>" //
+ + "</row></vaadin-grid-layout>";
+ GridLayout gl = new GridLayout(2, 2);
+ gl.addComponent(b1);
+ gl.addComponent(b2);
+ gl.addComponent(b3);
+ gl.addComponent(b4);
+ gl.setColumnExpandRatio(0, 1.0f);
+ gl.setColumnExpandRatio(1, 3.0f);
+ testWrite(design, gl);
+ testRead(design, gl);
+ }
+
+ @Test
+ public void testOneBigComponentGridLayout() {
+ Button b1 = new Button("Button 0,0 -> 1,1");
+ b1.setCaptionAsHtml(true);
+ String design = "<vaadin-grid-layout><row>" //
+ + "<column colspan=2 rowspan=2>" + writeChild(b1) + "</column>" //
+ + "</row><row expand=2>" //
+ + "</row></vaadin-grid-layout>";
+ GridLayout gl = new GridLayout(2, 2);
+ gl.addComponent(b1, 0, 0, 1, 1);
+ gl.setRowExpandRatio(1, 2);
+ testWrite(design, gl);
+ testRead(design, gl);
+ }
+
+ @Test
+ public void testMultipleSpannedComponentsGridLayout() {
+ GridLayout gl = new GridLayout(5, 5);
+ Button b1 = new Button("Button 0,0 -> 0,2");
+ b1.setCaptionAsHtml(true);
+ gl.addComponent(b1, 0, 0, 2, 0);
+
+ Button b2 = new Button("Button 0,3 -> 3,3");
+ b2.setCaptionAsHtml(true);
+ gl.addComponent(b2, 3, 0, 3, 3);
+
+ Button b3 = new Button("Button 0,4 -> 1,4");
+ b3.setCaptionAsHtml(true);
+ gl.addComponent(b3, 4, 0, 4, 1);
+
+ Button b4 = new Button("Button 1,0 -> 3,1");
+ b4.setCaptionAsHtml(true);
+ gl.addComponent(b4, 0, 1, 1, 3);
+
+ Button b5 = new Button("Button 2,2");
+ b5.setCaptionAsHtml(true);
+ gl.addComponent(b5, 2, 2);
+
+ Button b6 = new Button("Button 3,4 -> 4,4");
+ b6.setCaptionAsHtml(true);
+ gl.addComponent(b6, 4, 3, 4, 4);
+
+ Button b7 = new Button("Button 4,1 -> 4,2");
+ b7.setCaptionAsHtml(true);
+ gl.addComponent(b7, 2, 4, 3, 4);
+
+ /*
+ * Buttons in the GridLayout
+ */
+
+ // 1 1 1 2 3
+ // 4 4 - 2 3
+ // 4 4 5 2 -
+ // 4 4 - 2 6
+ // - - 7 7 6
+
+ String design = "<vaadin-grid-layout><row>" //
+ + "<column colspan=3>" + writeChild(b1) + "</column>" //
+ + "<column rowspan=4>" + writeChild(b2) + "</column>" //
+ + "<column rowspan=2>" + writeChild(b3) + "</column>" //
+ + "</row><row>" //
+ + "<column rowspan=3 colspan=2>" + writeChild(b4) + "</column>" //
+ + "</row><row>" //
+ + "<column>" + writeChild(b5) + "</column>" //
+ + "</row><row>" //
+ + "<column />" // Empty placeholder
+ + "<column rowspan=2>" + writeChild(b6) + "</column>" //
+ + "</row><row>" //
+ + "<column colspan=2 />" // Empty placeholder
+ + "<column colspan=2>" + writeChild(b7) + "</column>" //
+ + "</row></vaadin-grid-layout>";
+ testWrite(design, gl);
+ testRead(design, gl);
+ }
+
+ @Test
+ public void testManyExtraGridLayoutSlots() {
+ GridLayout gl = new GridLayout(5, 5);
+ Button b1 = new Button("Button 0,4 -> 4,4");
+ b1.setCaptionAsHtml(true);
+ gl.addComponent(b1, 4, 0, 4, 4);
+ gl.setColumnExpandRatio(2, 2.0f);
+
+ String design = "<vaadin-grid-layout><row>" //
+ + "<column colspan=4 rowspan=5 expand='0,0,2,0' />" //
+ + "<column rowspan=5>" + writeChild(b1) + "</column>" //
+ + "</row><row>" //
+ + "</row><row>" //
+ + "</row><row>" //
+ + "</row><row>" //
+ + "</row></vaadin-grid-layout>";
+ testWrite(design, gl);
+ testRead(design, gl);
+ }
+
+ @Test
+ public void testManyEmptyColumnsWithOneExpand() {
+ GridLayout gl = new GridLayout(5, 5);
+ Button b1 = new Button("Button 0,4 -> 4,4");
+ b1.setCaptionAsHtml(true);
+ gl.addComponent(b1, 0, 0, 0, 4);
+ gl.setColumnExpandRatio(4, 2.0f);
+
+ String design = "<vaadin-grid-layout><row>" //
+ + "<column rowspan=5>" + writeChild(b1) + "</column>" //
+ + "<column colspan=4 rowspan=5 expand='0,0,0,2' />" //
+ + "</row><row>" //
+ + "</row><row>" //
+ + "</row><row>" //
+ + "</row><row>" //
+ + "</row></vaadin-grid-layout>";
+ testWrite(design, gl);
+ testRead(design, gl);
+ }
+
+ @Test
+ public void testEmptyGridLayout() {
+ GridLayout gl = new GridLayout();
+ String design = "<vaadin-grid-layout />";
+ testWrite(design, gl);
+ testRead(design, gl);
+ }
+
+ private String writeChild(Component childComponent) {
+ return new DesignContext().createElement(childComponent).toString();
+ }
+
+ @Override
+ public GridLayout testRead(String design, GridLayout expected) {
+ expected.setCursorX(0);
+ expected.setCursorY(expected.getRows());
+
+ GridLayout result = super.testRead(design, expected);
+ for (int row = 0; row < expected.getRows(); ++row) {
+ Assert.assertTrue(Math.abs(expected.getRowExpandRatio(row)
+ - result.getRowExpandRatio(row)) < 0.00001);
+ }
+ for (int col = 0; col < expected.getColumns(); ++col) {
+ Assert.assertTrue(Math.abs(expected.getColumnExpandRatio(col)
+ - result.getColumnExpandRatio(col)) < 0.00001);
+ }
+ return result;
+ }
+
+ @Test
+ public void testNestedGridLayouts() {
+ String design = "<!DOCTYPE html>" + //
+ "<html>" + //
+ " <body> " + //
+ " <vaadin-grid-layout> " + //
+ " <row> " + //
+ " <column> " + //
+ " <vaadin-grid-layout> " + //
+ " <row> " + //
+ " <column> " + //
+ " <vaadin-button>" + //
+ " Button " + //
+ " </vaadin-button> " + //
+ " </column> " + //
+ " </row> " + //
+ " </vaadin-grid-layout> " + //
+ " </column> " + //
+ " </row> " + //
+ " </vaadin-grid-layout> " + //
+ " </body>" + //
+ "</html>";
+ GridLayout outer = new GridLayout();
+ GridLayout inner = new GridLayout();
+ Button b = new Button("Button");
+ b.setCaptionAsHtml(true);
+ inner.addComponent(b);
+ outer.addComponent(inner);
+ testRead(design, outer);
+ testWrite(design, outer);
+
+ }
+
+ @Test
+ public void testEmptyGridLayoutWithColsAndRowsSet() throws IOException {
+ GridLayout layout = new GridLayout();
+ layout.setRows(2);
+ layout.setColumns(2);
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ DesignContext context = new DesignContext();
+ context.setRootComponent(layout);
+ Design.write(context, out);
+
+ ByteArrayInputStream input = new ByteArrayInputStream(out.toByteArray());
+ Component component = Design.read(input);
+ GridLayout readLayout = (GridLayout) component;
+
+ Assert.assertEquals(layout.getRows(), readLayout.getRows());
+ }
+
+ @Test
+ public void testGridLayoutAlignments() {
+ String design = "<vaadin-grid-layout><row>" //
+ + "<column><vaadin-label :middle>0</label></column>"//
+ + "<column><vaadin-label :right>1</label>"//
+ + "</row><row>" //
+ + "<column><vaadin-label :bottom :center>2</label></column>"//
+ + "<column><vaadin-label :middle :center>3</label>" //
+ + "</row></vaadin-grid-layout>";
+ GridLayout gl = new GridLayout(2, 2);
+
+ Alignment[] alignments = { Alignment.MIDDLE_LEFT, Alignment.TOP_RIGHT,
+ Alignment.BOTTOM_CENTER, Alignment.MIDDLE_CENTER };
+ for (int i = 0; i < 4; i++) {
+ Label child = new Label("" + i, ContentMode.HTML);
+ gl.addComponent(child);
+ gl.setComponentAlignment(child, alignments[i]);
+ }
+
+ testWrite(design, gl);
+ testRead(design, gl);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/gridlayout/GridLayoutListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/gridlayout/GridLayoutListenersTest.java
new file mode 100644
index 0000000000..ed18a24608
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/gridlayout/GridLayoutListenersTest.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.AbstractListenerMethodsTestBase;
+import com.vaadin.ui.GridLayout;
+
+public class GridLayoutListenersTest extends AbstractListenerMethodsTestBase {
+ public void testLayoutClickListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(GridLayout.class, LayoutClickEvent.class,
+ LayoutClickListener.class);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/gridlayout/GridLayoutTest.java b/server/src/test/java/com/vaadin/tests/server/component/gridlayout/GridLayoutTest.java
new file mode 100644
index 0000000000..1eabf2fb62
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/gridlayout/GridLayoutTest.java
@@ -0,0 +1,108 @@
+package com.vaadin.tests.server.component.gridlayout;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.junit.Test;
+
+import com.vaadin.ui.Component;
+import com.vaadin.ui.GridLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Layout;
+
+public class GridLayoutTest {
+ Component[] children = new Component[] { new Label("A"), new Label("B"),
+ new Label("C"), new Label("D") };
+
+ @Test
+ public void testConstructorWithComponents() {
+ GridLayout grid = new GridLayout(2, 2, children);
+ assertContentPositions(grid);
+ assertOrder(grid, new int[] { 0, 1, 2, 3 });
+
+ grid = new GridLayout(1, 1, children);
+ assertContentPositions(grid);
+ assertOrder(grid, new int[] { 0, 1, 2, 3 });
+ }
+
+ @Test
+ public void testAddComponents() {
+ GridLayout grid = new GridLayout(2, 2);
+ grid.addComponents(children);
+ assertContentPositions(grid);
+ assertOrder(grid, new int[] { 0, 1, 2, 3 });
+
+ Label extra = new Label("Extra");
+ Label extra2 = new Label("Extra2");
+ grid.addComponents(extra, extra2);
+ assertSame(grid.getComponent(0, 2), extra);
+ assertSame(grid.getComponent(1, 2), extra2);
+
+ grid.removeAllComponents();
+ grid.addComponents(extra, extra2);
+ assertSame(grid.getComponent(0, 0), extra);
+ assertSame(grid.getComponent(1, 0), extra2);
+
+ grid.addComponents(children);
+ assertOrder(grid, new int[] { -1, -1, 0, 1, 2, 3 });
+
+ grid.removeComponent(extra);
+ grid.removeComponent(extra2);
+ assertOrder(grid, new int[] { 0, 1, 2, 3 });
+
+ grid.addComponents(extra2, extra);
+ assertSame(grid.getComponent(0, 3), extra2);
+ assertSame(grid.getComponent(1, 3), extra);
+ assertOrder(grid, new int[] { 0, 1, 2, 3, -1, -1 });
+
+ grid.removeComponent(extra2);
+ grid.removeComponent(extra);
+ grid.setCursorX(0);
+ grid.setCursorY(0);
+ grid.addComponents(extra, extra2);
+ assertSame(grid.getComponent(0, 0), extra);
+ assertSame(grid.getComponent(1, 0), extra2);
+ assertOrder(grid, new int[] { -1, -1, 0, 1, 2, 3 });
+
+ grid = new GridLayout();
+ grid.addComponents(children);
+ assertContentPositions(grid);
+ assertOrder(grid, new int[] { 0, 1, 2, 3 });
+ }
+
+ private void assertContentPositions(GridLayout grid) {
+ assertEquals(grid.getComponentCount(), children.length);
+ int c = 0;
+ for (int i = 0; i < grid.getRows(); i++) {
+ for (int j = 0; j < grid.getColumns(); j++) {
+ assertSame(grid.getComponent(j, i), children[c]);
+ c++;
+ }
+ }
+ }
+
+ /**
+ * Asserts that layout has the components in children in the order specified
+ * by indices.
+ */
+ private void assertOrder(Layout layout, int[] indices) {
+ Iterator<?> i = layout.iterator();
+ try {
+ for (int index : indices) {
+ if (index != -1) {
+ assertSame(children[index], i.next());
+ } else {
+ i.next();
+ }
+ }
+ assertFalse("Too many components in layout", i.hasNext());
+ } catch (NoSuchElementException e) {
+ fail("Too few components in layout");
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/image/ImageDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/image/ImageDeclarativeTest.java
new file mode 100644
index 0000000000..562c629209
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/image/ImageDeclarativeTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2000-2014 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.image;
+
+import org.junit.Test;
+
+import com.vaadin.server.ExternalResource;
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.Image;
+
+/**
+ * Tests declarative support for implementations of {@link Image}.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class ImageDeclarativeTest extends DeclarativeTestBase<Image> {
+
+ protected String getDesign() {
+ return "<vaadin-image source='http://foo.bar/img.png' alt='Some random image from the theme'></vaadin-image>";
+ }
+
+ protected Image getExpectedResult() {
+ Image i = new Image();
+ i.setSource(new ExternalResource("http://foo.bar/img.png"));
+ i.setAlternateText("Some random image from the theme");
+ return i;
+ };
+
+ @Test
+ public void read() {
+ testRead(getDesign(), getExpectedResult());
+ }
+
+ @Test
+ public void write() {
+ testWrite(getDesign(), getExpectedResult());
+ }
+
+ @Test
+ public void testEmpty() {
+ testRead("<vaadin-image />", new Image());
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/label/LabelConvertersTest.java b/server/src/test/java/com/vaadin/tests/server/component/label/LabelConvertersTest.java
new file mode 100644
index 0000000000..26961dc372
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/label/LabelConvertersTest.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2000-2014 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.Property;
+import com.vaadin.data.util.MethodProperty;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.tests.data.bean.Person;
+import com.vaadin.tests.util.AlwaysLockedVaadinSession;
+import com.vaadin.ui.Label;
+import com.vaadin.util.CurrentInstance;
+
+public class LabelConvertersTest {
+ @Before
+ public void clearExistingThreadLocals() {
+ // Ensure no previous test left some thread locals hanging
+ CurrentInstance.clearAll();
+ }
+
+ @Test
+ 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());
+ }
+
+ @Test
+ public void testIntegerDataSource() {
+ VaadinSession.setCurrent(new AlwaysLockedVaadinSession(null));
+ Label l = new Label("Foo");
+ Property ds = new MethodProperty<Integer>(Person.createTestPerson1(),
+ "age");
+ l.setPropertyDataSource(ds);
+ assertEquals(String.valueOf(Person.createTestPerson1().getAge()),
+ l.getValue());
+ }
+
+ @Test
+ 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) {
+ }
+
+ }
+
+ @Test
+ 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/src/test/java/com/vaadin/tests/server/component/label/LabelDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/label/LabelDeclarativeTest.java
new file mode 100644
index 0000000000..7a7f4bd844
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/label/LabelDeclarativeTest.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2000-2014 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 org.jsoup.nodes.Element;
+import org.jsoup.parser.Tag;
+import org.junit.Assert;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import com.vaadin.shared.ui.label.ContentMode;
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.declarative.DesignContext;
+import com.vaadin.ui.declarative.DesignFormatter;
+
+/**
+ * Tests declarative support for implementations of {@link Label}.
+ *
+ * @since 7.4
+ * @author Vaadin Ltd
+ */
+public class LabelDeclarativeTest extends DeclarativeTestBase<Label> {
+
+ @Test
+ public void testEmpty() {
+ String design = "<vaadin-label />";
+ Label l = new Label();
+ l.setContentMode(ContentMode.HTML);
+ testRead(design, l);
+ testWrite(design, l);
+ }
+
+ @Test
+ public void testDefault() {
+ String design = "<vaadin-label>Hello world!</vaadin-label>";
+ Label l = createLabel("Hello world!", null, true);
+ testRead(design, l);
+ testWrite(design, l);
+ }
+
+ @Test
+ public void testRich() {
+ String design = "<vaadin-label>This is <b><u>Rich</u></b> content!</vaadin-label>";
+ Label l = createLabel("This is \n<b><u>Rich</u></b> content!", null,
+ true);
+ testRead(design, l);
+ testWrite(design, l);
+ }
+
+ @Test
+ public void testPlainText() {
+ String design = "<vaadin-label plain-text>This is only &lt;b&gt;text&lt;/b&gt;"
+ + " and will contain visible tags</vaadin-label>";
+ Label l = createLabel(
+ "This is only <b>text</b> and will contain visible tags", null,
+ false);
+ testRead(design, l);
+ testWrite(design, l);
+ }
+
+ @Test
+ public void testContentAndCaption() {
+ String design = "<vaadin-label caption='This is a label'>This is <b><u>Rich</u></b> "
+ + "content!</vaadin-label>";
+ Label l = createLabel("This is \n<b><u>Rich</u></b> content!",
+ "This is a label", true);
+ testRead(design, l);
+ testWrite(design, l);
+ }
+
+ @Test
+ public void testCaption() {
+ String design = "<vaadin-label caption='This is a label' />";
+ Label l = createLabel(null, "This is a label", true);
+ testRead(design, l);
+ testWrite(design, l);
+ }
+
+ @Test
+ public void testHtmlEntities() {
+ String design = "<vaadin-label plain-text=\"true\">&gt; Test</vaadin-label>";
+ Label read = read(design);
+ Assert.assertEquals("> Test", read.getValue());
+
+ design = design.replace("plain-text=\"true\"", "");
+ read = read(design);
+ Assert.assertEquals("&gt; Test", read.getValue());
+
+ Label label = new Label("&amp; Test");
+ label.setContentMode(ContentMode.TEXT);
+
+ Element root = new Element(Tag.valueOf("vaadin-label"), "");
+ label.writeDesign(root, new DesignContext());
+ Assert.assertEquals("&amp;amp; Test", root.html());
+
+ label.setContentMode(ContentMode.HTML);
+ root = new Element(Tag.valueOf("vaadin-label"), "");
+ label.writeDesign(root, new DesignContext());
+ Assert.assertEquals("&amp; Test", root.html());
+ }
+
+ @Test
+ public void testNullValue() {
+ Label label = new Label();
+ label.setValue(null);
+
+ label.setContentMode(ContentMode.TEXT);
+ Element root = new Element(Tag.valueOf("vaadin-label"), "");
+ label.writeDesign(root, new DesignContext());
+ Assert.assertEquals("", root.html());
+
+ label.setContentMode(ContentMode.HTML);
+ root = new Element(Tag.valueOf("vaadin-label"), "");
+ label.writeDesign(root, new DesignContext());
+ Assert.assertEquals("", root.html());
+ }
+
+ /**
+ * FIXME Using another content mode than TEXT OR HTML is currently not
+ * supported and will cause the content mode to fallback without the users
+ * knowledge to HTML. This test can be enabled when
+ * https://dev.vaadin.com/ticket/19435 is fixed.
+ */
+ @Test
+ @Ignore("Test ignored due to https://dev.vaadin.com/ticket/19435")
+ public void testContentModes() {
+ String design = "<vaadin-label caption='This\n is a label' />";
+ Label l = createLabel(null, "This\n is a label", true);
+ l.setContentMode(ContentMode.PREFORMATTED);
+ testRead(design, l);
+ testWrite(design, l);
+ }
+
+ private Label createLabel(String content, String caption, boolean html) {
+ Label label = new Label();
+ label.setContentMode(html ? ContentMode.HTML : ContentMode.TEXT);
+ if (content != null) {
+ label.setValue(content);
+ }
+ if (caption != null) {
+ label.setCaption(DesignFormatter.encodeForTextNode(caption));
+ }
+ return label;
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/label/LabelListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/label/LabelListenersTest.java
new file mode 100644
index 0000000000..4287d58d9c
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/label/LabelListenersTest.java
@@ -0,0 +1,92 @@
+package com.vaadin.tests.server.component.label;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createStrictMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+import org.easymock.EasyMock;
+
+import com.vaadin.data.Property;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.tests.server.component.AbstractListenerMethodsTestBase;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Label.ValueChangeEvent;
+
+public class LabelListenersTest extends AbstractListenerMethodsTestBase {
+ public void testValueChangeListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Label.class, ValueChangeEvent.class,
+ ValueChangeListener.class);
+ }
+
+ public void testValueChangeFiredWhenSettingValue() {
+ Label underTest = new Label();
+
+ // setup the mock listener
+ ValueChangeListener mockListener = createStrictMock(ValueChangeListener.class);
+ // record
+ mockListener
+ .valueChange(anyObject(com.vaadin.data.Property.ValueChangeEvent.class));
+
+ // test
+ underTest.addValueChangeListener(mockListener);
+
+ replay(mockListener);
+ underTest.setValue("A new value");
+
+ verify(mockListener);
+
+ }
+
+ public void testValueChangeFiredWhenSettingPropertyDataSource() {
+ // setup
+ Label underTest = new Label();
+
+ Property mockProperty = EasyMock.createMock(Property.class);
+
+ ValueChangeListener mockListener = createStrictMock(ValueChangeListener.class);
+ // record
+ mockListener
+ .valueChange(anyObject(com.vaadin.data.Property.ValueChangeEvent.class));
+
+ expect(mockProperty.getType()).andReturn(String.class).atLeastOnce();
+ expect(mockProperty.getValue()).andReturn("Any").atLeastOnce();
+
+ // test
+
+ replay(mockListener, mockProperty);
+ underTest.addValueChangeListener(mockListener);
+ underTest.setPropertyDataSource(mockProperty);
+
+ verify(mockListener);
+
+ }
+
+ public void testValueChangeNotFiredWhenNotSettingValue() {
+ Label underTest = new Label();
+ // setup the mock listener
+ ValueChangeListener mockListener = createStrictMock(ValueChangeListener.class);
+ // record: nothing to record
+
+ // test
+ underTest.addValueChangeListener(mockListener);
+ replay(mockListener);
+ verify(mockListener);
+ }
+
+ public void testNoValueChangeFiredWhenSettingPropertyDataSourceToNull() {
+ Label underTest = new Label();
+ // setup the mock Listener
+ ValueChangeListener mockListener = createStrictMock(ValueChangeListener.class);
+ // record: nothing to record
+
+ // test
+ underTest.addValueChangeListener(mockListener);
+ underTest.setPropertyDataSource(null);
+
+ replay(mockListener);
+ verify(mockListener);
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/link/LinkDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/link/LinkDeclarativeTest.java
new file mode 100644
index 0000000000..da7227224d
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/link/LinkDeclarativeTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2000-2014 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.link;
+
+import org.junit.Test;
+
+import com.vaadin.server.ExternalResource;
+import com.vaadin.shared.ui.BorderStyle;
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.Link;
+
+/**
+ * Test cases for reading the properties of selection components.
+ *
+ * @author Vaadin Ltd
+ */
+public class LinkDeclarativeTest extends DeclarativeTestBase<Link> {
+ private String getBasicDesign() {
+ return "<vaadin-link href='http://vaadin.com' target='vaadin-window' target-height=500"
+ + " target-width=800 target-border='none' />";
+ }
+
+ private Link getBasicExpected() {
+ Link l = new Link();
+ l.setResource(new ExternalResource("http://vaadin.com"));
+ l.setTargetName("vaadin-window");
+ l.setTargetBorder(BorderStyle.NONE);
+ l.setTargetHeight(500);
+ l.setTargetWidth(800);
+ return l;
+ }
+
+ @Test
+ public void readBasic() throws Exception {
+ testRead(getBasicDesign(), getBasicExpected());
+ }
+
+ @Test
+ public void writeBasic() throws Exception {
+ testWrite(getBasicDesign(), getBasicExpected());
+ }
+
+ @Test
+ public void testReadEmpty() {
+ testRead("<vaadin-link />", new Link());
+ }
+
+ @Test
+ public void testWriteEmpty() {
+ testWrite("<vaadin-link />", new Link());
+ }
+
+} \ No newline at end of file
diff --git a/server/src/test/java/com/vaadin/tests/server/component/listselect/ListSelectDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/listselect/ListSelectDeclarativeTest.java
new file mode 100644
index 0000000000..d0fa400d31
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/listselect/ListSelectDeclarativeTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2000-2014 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.listselect;
+
+import org.junit.Test;
+
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.ListSelect;
+
+public class ListSelectDeclarativeTest extends DeclarativeTestBase<ListSelect> {
+
+ private ListSelect getWithOptionsExpected() {
+ ListSelect ls = new ListSelect();
+ ls.setRows(10);
+ ls.addItem("Male");
+ ls.addItem("Female");
+ return ls;
+ }
+
+ private String getWithOptionsDesign() {
+ return "<vaadin-list-select rows=10>\n" + " <option>Male</option>\n"
+ + " <option>Female</option>\n" + "</vaadin-list-select>\n"
+ + "";
+ }
+
+ @Test
+ public void testReadWithOptions() {
+ testRead(getWithOptionsDesign(), getWithOptionsExpected());
+ }
+
+ @Test
+ public void testWriteWithOptions() {
+ testWrite(stripOptionTags(getWithOptionsDesign()),
+ getWithOptionsExpected());
+ }
+
+ private ListSelect getBasicExpected() {
+ ListSelect ls = new ListSelect();
+ ls.setCaption("Hello");
+ return ls;
+ }
+
+ private String getBasicDesign() {
+ return "<vaadin-list-select caption='Hello' />";
+ }
+
+ @Test
+ public void testReadBasic() {
+ testRead(getBasicDesign(), getBasicExpected());
+ }
+
+ @Test
+ public void testWriteBasic() {
+ testWrite(getBasicDesign(), getBasicExpected());
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/listselect/ListSelectStateTest.java b/server/src/test/java/com/vaadin/tests/server/component/listselect/ListSelectStateTest.java
new file mode 100644
index 0000000000..01dc71d96a
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/listselect/ListSelectStateTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2000-2014 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.listselect;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.shared.ui.select.AbstractSelectState;
+import com.vaadin.ui.ListSelect;
+
+/**
+ * Tests for ListSelect State.
+ *
+ */
+public class ListSelectStateTest {
+
+ @Test
+ public void getState_listSelectHasCustomState() {
+ TestListSelect select = new TestListSelect();
+ AbstractSelectState state = select.getState();
+ Assert.assertEquals("Unexpected state class",
+ AbstractSelectState.class, state.getClass());
+ }
+
+ private static class TestListSelect extends ListSelect {
+ @Override
+ public AbstractSelectState getState() {
+ return super.getState();
+ }
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/loginform/LoginFormListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/loginform/LoginFormListenersTest.java
new file mode 100644
index 0000000000..1c06d2652a
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/loginform/LoginFormListenersTest.java
@@ -0,0 +1,13 @@
+package com.vaadin.tests.server.component.loginform;
+
+import com.vaadin.tests.server.component.AbstractListenerMethodsTestBase;
+import com.vaadin.ui.LoginForm;
+import com.vaadin.ui.LoginForm.LoginEvent;
+import com.vaadin.ui.LoginForm.LoginListener;
+
+public class LoginFormListenersTest extends AbstractListenerMethodsTestBase {
+ public void testLoginListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(LoginForm.class, LoginEvent.class,
+ LoginListener.class);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/menubar/MenuBarIdsTest.java b/server/src/test/java/com/vaadin/tests/server/component/menubar/MenuBarIdsTest.java
new file mode 100644
index 0000000000..68007bd870
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/menubar/MenuBarIdsTest.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 MenuBarIdsTest 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/src/test/java/com/vaadin/tests/server/component/nativeselect/NativeSelectDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/nativeselect/NativeSelectDeclarativeTest.java
new file mode 100644
index 0000000000..511f411a93
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/nativeselect/NativeSelectDeclarativeTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2000-2014 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.nativeselect;
+
+import org.junit.Test;
+
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.NativeSelect;
+
+/**
+ * Test cases for reading the properties of selection components.
+ *
+ * @author Vaadin Ltd
+ */
+public class NativeSelectDeclarativeTest extends
+ DeclarativeTestBase<NativeSelect> {
+
+ public String getBasicDesign() {
+ return "<vaadin-native-select><option>foo</option><option>bar</option></vaadin-native-select>";
+
+ }
+
+ public NativeSelect getBasicExpected() {
+ NativeSelect ns = new NativeSelect();
+ ns.addItem("foo");
+ ns.addItem("bar");
+ return ns;
+ }
+
+ @Test
+ public void testReadBasic() {
+ testRead(getBasicDesign(), getBasicExpected());
+ }
+
+ @Test
+ public void testWriteBasic() {
+ testWrite(stripOptionTags(getBasicDesign()), getBasicExpected());
+ }
+
+ @Test
+ public void testReadOnlyValue() {
+ String design = "<vaadin-native-select readonly><option selected>foo</option><option>bar</option></vaadin-native-select>";
+
+ NativeSelect ns = new NativeSelect();
+ ns.addItems("foo", "bar");
+ ns.setValue("foo");
+ ns.setReadOnly(true);
+
+ testRead(design, ns);
+
+ // Selects items are not written out by default
+ String design2 = "<vaadin-native-select readonly></vaadin-native-select>";
+ testWrite(design2, ns);
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/optiongroup/OptionGroupListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/optiongroup/OptionGroupListenersTest.java
new file mode 100644
index 0000000000..c2dc175c75
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/optiongroup/OptionGroupListenersTest.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.AbstractListenerMethodsTestBase;
+import com.vaadin.ui.OptionGroup;
+
+public class OptionGroupListenersTest extends AbstractListenerMethodsTestBase {
+ 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/src/test/java/com/vaadin/tests/server/component/optiongroup/OptionGroupStateTest.java b/server/src/test/java/com/vaadin/tests/server/component/optiongroup/OptionGroupStateTest.java
new file mode 100644
index 0000000000..59ff432cad
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/optiongroup/OptionGroupStateTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2014 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.optiongroup;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.shared.ui.optiongroup.OptionGroupState;
+import com.vaadin.ui.OptionGroup;
+
+/**
+ * Tests for OptionGroup state.
+ *
+ */
+public class OptionGroupStateTest {
+
+ @Test
+ public void getState_optionGroupHasCustomState() {
+ TestOptionGroup group = new TestOptionGroup();
+ OptionGroupState state = group.getState();
+ Assert.assertEquals("Unexpected state class", OptionGroupState.class,
+ state.getClass());
+ }
+
+ @Test
+ public void getPrimaryStyleName_optionGroupHasCustomPrimaryStyleName() {
+ OptionGroup layout = new OptionGroup();
+ OptionGroupState state = new OptionGroupState();
+ Assert.assertEquals("Unexpected primary style name",
+ state.primaryStyleName, layout.getPrimaryStyleName());
+ }
+
+ @Test
+ public void optionGroupStateHasCustomPrimaryStyleName() {
+ OptionGroupState state = new OptionGroupState();
+ Assert.assertEquals("Unexpected primary style name",
+ "v-select-optiongroup", state.primaryStyleName);
+ }
+
+ private static class TestOptionGroup extends OptionGroup {
+
+ @Override
+ public OptionGroupState getState() {
+ return super.getState();
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/orderedlayout/DefaultAlignmentTest.java b/server/src/test/java/com/vaadin/tests/server/component/orderedlayout/DefaultAlignmentTest.java
new file mode 100644
index 0000000000..7560c21adb
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/orderedlayout/DefaultAlignmentTest.java
@@ -0,0 +1,67 @@
+package com.vaadin.tests.server.component.orderedlayout;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.ui.AbstractOrderedLayout;
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.VerticalLayout;
+
+public class DefaultAlignmentTest {
+
+ private VerticalLayout verticalLayout;
+ private HorizontalLayout horizontalLayout;
+
+ @Before
+ public void setup() {
+ verticalLayout = new VerticalLayout();
+ horizontalLayout = new HorizontalLayout();
+ }
+
+ @Test
+ public void testDefaultAlignmentVerticalLayout() {
+ testDefaultAlignment(verticalLayout);
+ }
+
+ @Test
+ public void testDefaultAlignmentHorizontalLayout() {
+ testDefaultAlignment(horizontalLayout);
+ }
+
+ public void testDefaultAlignment(AbstractOrderedLayout layout) {
+ Label label = new Label("A label");
+ TextField tf = new TextField("A TextField");
+ layout.addComponent(label);
+ layout.addComponent(tf);
+ Assert.assertEquals(Alignment.TOP_LEFT,
+ layout.getComponentAlignment(label));
+ Assert.assertEquals(Alignment.TOP_LEFT,
+ layout.getComponentAlignment(tf));
+ }
+
+ @Test
+ public void testAlteredDefaultAlignmentVerticalLayout() {
+ testAlteredDefaultAlignment(verticalLayout);
+ }
+
+ @Test
+ public void testAlteredDefaultAlignmentHorizontalLayout() {
+ testAlteredDefaultAlignment(horizontalLayout);
+ }
+
+ public void testAlteredDefaultAlignment(AbstractOrderedLayout layout) {
+ Label label = new Label("A label");
+ TextField tf = new TextField("A TextField");
+ layout.setDefaultComponentAlignment(Alignment.MIDDLE_CENTER);
+ layout.addComponent(label);
+ layout.addComponent(tf);
+ Assert.assertEquals(Alignment.MIDDLE_CENTER,
+ layout.getComponentAlignment(label));
+ Assert.assertEquals(Alignment.MIDDLE_CENTER,
+ layout.getComponentAlignment(tf));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/orderedlayout/OrderedLayoutTest.java b/server/src/test/java/com/vaadin/tests/server/component/orderedlayout/OrderedLayoutTest.java
new file mode 100644
index 0000000000..3b3dfb94d8
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/orderedlayout/OrderedLayoutTest.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 OrderedLayoutTest 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/src/test/java/com/vaadin/tests/server/component/panel/PanelDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/panel/PanelDeclarativeTest.java
new file mode 100644
index 0000000000..39191f0665
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/panel/PanelDeclarativeTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2000-2014 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.panel;
+
+import org.junit.Test;
+
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.Panel;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.declarative.DesignException;
+
+/**
+ * Tests declarative support for Panel.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class PanelDeclarativeTest extends DeclarativeTestBase<Panel> {
+
+ @Test
+ public void testFeatures() {
+ String design = "<vaadin-panel id=panelId caption=\"A panel\" tabindex=2 scroll-left=10 "
+ + "scroll-top=20 width=200px height=150px> "
+ + "<vaadin-vertical-layout width=300px height=400px /> "
+ + "</vaadin-panel>";
+ Panel p = new Panel();
+ p.setId("panelId");
+ p.setCaption("A panel");
+ p.setTabIndex(2);
+ p.setScrollLeft(10);
+ p.setScrollTop(20);
+ p.setWidth("200px");
+ p.setHeight("150px");
+ VerticalLayout vl = new VerticalLayout();
+ vl.setWidth("300px");
+ vl.setHeight("400px");
+ p.setContent(vl);
+ testRead(design, p);
+ testWrite(design, p);
+ }
+
+ @Test(expected = DesignException.class)
+ public void testWithMoreThanOneChild() {
+ // Check that attempting to have two components in a panel causes a
+ // DesignException.
+ String design = "<vaadin-panel> <vaadin-vertical-layout/> <vaadin-horizontal-layout/> </vaadin-panel>";
+ testRead(design, null);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/panel/PanelListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/panel/PanelListenersTest.java
new file mode 100644
index 0000000000..929553a682
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/panel/PanelListenersTest.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.AbstractListenerMethodsTestBase;
+import com.vaadin.ui.Panel;
+
+public class PanelListenersTest extends AbstractListenerMethodsTestBase {
+ public void testClickListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Panel.class, ClickEvent.class,
+ ClickListener.class);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/passwordfield/PasswordFieldDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/passwordfield/PasswordFieldDeclarativeTest.java
new file mode 100644
index 0000000000..fcb2453057
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/passwordfield/PasswordFieldDeclarativeTest.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2014 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.passwordfield;
+
+import org.junit.Test;
+
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.PasswordField;
+
+/**
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class PasswordFieldDeclarativeTest extends
+ DeclarativeTestBase<PasswordField> {
+
+ @Test
+ public void testReadOnlyValue() {
+ String design = "<vaadin-password-field readonly value=\"test value\"/>";
+ PasswordField tf = new PasswordField();
+ tf.setValue("test value");
+ tf.setReadOnly(true);
+ testRead(design, tf);
+ testWrite(design, tf);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/popupview/PopupViewDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/popupview/PopupViewDeclarativeTest.java
new file mode 100644
index 0000000000..300a993064
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/popupview/PopupViewDeclarativeTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2000-2014 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.popupview;
+
+import org.junit.Test;
+
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.PopupView;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.declarative.DesignContext;
+
+public class PopupViewDeclarativeTest extends DeclarativeTestBase<PopupView> {
+
+ @Test
+ public void testEmptyPopupView() {
+ PopupView component = new PopupView();
+ Component popup = component.getContent().getPopupComponent();
+ String design = "<vaadin-popup-view><popup-content>"
+ + new DesignContext().createElement(popup)
+ + "</popup-content></vaadin-popup-view>";
+ testWrite(design, component);
+ testRead(design, component);
+ }
+
+ @Test
+ public void testVisiblePopupDesign() {
+ final VerticalLayout verticalLayout = new VerticalLayout();
+ verticalLayout.setWidth("300px");
+ verticalLayout.setHeight("400px");
+
+ PopupView component = new PopupView("Click <u>here</u> to open",
+ verticalLayout);
+ component.setHideOnMouseOut(true);
+ component.setPopupVisible(true);
+ // hide-on-mouse-out is true by default. not seen in design
+ String design = "<vaadin-popup-view popup-visible>" //
+ + "Click <u>here</u> to open"
+ + "<popup-content>"
+ + new DesignContext().createElement(verticalLayout)
+ + "</popup-content>" //
+ + "</vaadin-popup-view>";
+ testWrite(design, component);
+ testRead(design, component);
+ }
+
+ @Test
+ public void testHideOnMouseOutDisabled() {
+ final Label label = new Label("Foo");
+ PopupView component = new PopupView("Click Me!", label);
+ component.setHideOnMouseOut(false);
+ String design = "<vaadin-popup-view hide-on-mouse-out='false'>" //
+ + "Click Me!"
+ + "<popup-content>"
+ + new DesignContext().createElement(label) + "</popup-content>" //
+ + "</vaadin-popup-view>";
+ testWrite(design, component);
+ testRead(design, component);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/popupview/PopupViewListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/popupview/PopupViewListenersTest.java
new file mode 100644
index 0000000000..06782818a8
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/popupview/PopupViewListenersTest.java
@@ -0,0 +1,14 @@
+package com.vaadin.tests.server.component.popupview;
+
+import com.vaadin.tests.server.component.AbstractListenerMethodsTestBase;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.PopupView;
+import com.vaadin.ui.PopupView.PopupVisibilityEvent;
+import com.vaadin.ui.PopupView.PopupVisibilityListener;
+
+public class PopupViewListenersTest extends AbstractListenerMethodsTestBase {
+ public void testPopupVisibilityListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(PopupView.class, PopupVisibilityEvent.class,
+ PopupVisibilityListener.class, new PopupView("", new Label()));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/progressbar/ProgressBarDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/progressbar/ProgressBarDeclarativeTest.java
new file mode 100644
index 0000000000..36ede0a321
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/progressbar/ProgressBarDeclarativeTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2000-2014 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.progressbar;
+
+import org.junit.Test;
+
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.ProgressBar;
+
+/**
+ * Test cases for reading the properties of selection components.
+ *
+ * @author Vaadin Ltd
+ */
+public class ProgressBarDeclarativeTest extends
+ DeclarativeTestBase<ProgressBar> {
+
+ public String getBasicDesign() {
+ return "<vaadin-progress-bar value=0.5 indeterminate>";
+ }
+
+ public ProgressBar getBasicExpected() {
+ ProgressBar ns = new ProgressBar();
+ ns.setIndeterminate(true);
+ ns.setValue(0.5f);
+ return ns;
+ }
+
+ @Test
+ public void testReadBasic() {
+ testRead(getBasicDesign(), getBasicExpected());
+ }
+
+ @Test
+ public void testWriteBasic() {
+ testWrite(stripOptionTags(getBasicDesign()), getBasicExpected());
+ }
+
+ @Test
+ public void testReadEmpty() {
+ testRead("<vaadin-progress-bar>", new ProgressBar());
+ }
+
+ @Test
+ public void testWriteEmpty() {
+ testWrite("<vaadin-progress-bar>", new ProgressBar());
+ }
+
+ @Test
+ public void testReadOnlyValue() {
+ String design = "<vaadin-progress-bar readonly value=0.5 indeterminate>";
+ ProgressBar progressBar = new ProgressBar();
+ progressBar.setIndeterminate(true);
+ progressBar.setValue(0.5f);
+ progressBar.setReadOnly(true);
+
+ testRead(design, progressBar);
+ testWrite(design, progressBar);
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/richtextarea/RichTextAreaDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/richtextarea/RichTextAreaDeclarativeTest.java
new file mode 100644
index 0000000000..37d27af197
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/richtextarea/RichTextAreaDeclarativeTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2000-2014 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.richtextarea;
+
+import org.junit.Test;
+
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.RichTextArea;
+
+public class RichTextAreaDeclarativeTest extends
+ DeclarativeTestBase<RichTextArea> {
+
+ private String getBasicDesign() {
+ return "<vaadin-rich-text-area null-representation='' null-setting-allowed>\n"
+ + "\n <b>Header</b> <br/>Some text\n "
+ + "</vaadin-rich-text-area>";
+ }
+
+ private RichTextArea getBasicExpected() {
+ RichTextArea rta = new RichTextArea();
+ rta.setNullRepresentation("");
+ rta.setNullSettingAllowed(true);
+ rta.setValue("<b>Header</b> \n<br>Some text");
+ return rta;
+ }
+
+ @Test
+ public void testBasicRead() {
+ testRead(getBasicDesign(), getBasicExpected());
+ }
+
+ @Test
+ public void testBasicWrite() {
+ testWrite(getBasicDesign(), getBasicExpected());
+ }
+
+ @Test
+ public void testReadEmpty() {
+ testRead("<vaadin-rich-text-area />", new RichTextArea());
+ }
+
+ @Test
+ public void testWriteEmpty() {
+ testWrite("<vaadin-rich-text-area />", new RichTextArea());
+ }
+
+ @Test
+ public void testReadOnlyValue() {
+ String design = "<vaadin-rich-text-area readonly style-name='v-richtextarea-readonly'>Hello World!</vaadin-text-area>";
+ RichTextArea ta = new RichTextArea();
+ ta.setValue("Hello World!");
+ ta.setReadOnly(true);
+
+ testRead(design, ta);
+ testWrite(design, ta);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/richtextarea/RichTextAreaStateTest.java b/server/src/test/java/com/vaadin/tests/server/component/richtextarea/RichTextAreaStateTest.java
new file mode 100644
index 0000000000..d1c0f8fa1e
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/richtextarea/RichTextAreaStateTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2000-2014 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.richtextarea;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.shared.ui.textarea.RichTextAreaState;
+import com.vaadin.ui.RichTextArea;
+
+/**
+ * Tests for RichTextArea State.
+ *
+ */
+public class RichTextAreaStateTest {
+ @Test
+ public void getState_areaHasCustomState() {
+ TestRichTextArea area = new TestRichTextArea();
+ RichTextAreaState state = area.getState();
+ Assert.assertEquals("Unexpected state class", RichTextAreaState.class,
+ state.getClass());
+ }
+
+ @Test
+ public void getPrimaryStyleName_areaHasCustomPrimaryStyleName() {
+ RichTextArea area = new RichTextArea();
+ RichTextAreaState state = new RichTextAreaState();
+ Assert.assertEquals("Unexpected primary style name",
+ state.primaryStyleName, area.getPrimaryStyleName());
+ }
+
+ @Test
+ public void areaStateHasCustomPrimaryStyleName() {
+ RichTextAreaState state = new RichTextAreaState();
+ Assert.assertEquals("Unexpected primary style name", "v-richtextarea",
+ state.primaryStyleName);
+ }
+
+ private static class TestRichTextArea extends RichTextArea {
+
+ @Override
+ public RichTextAreaState getState() {
+ return super.getState();
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/select/SelectListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/select/SelectListenersTest.java
new file mode 100644
index 0000000000..9a2a5f1f50
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/select/SelectListenersTest.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.AbstractListenerMethodsTestBase;
+import com.vaadin.ui.Select;
+
+public class SelectListenersTest extends AbstractListenerMethodsTestBase {
+ public void testFocusListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Select.class, FocusEvent.class,
+ FocusListener.class);
+ }
+
+ public void testBlurListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(Select.class, BlurEvent.class,
+ BlurListener.class);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/slider/SliderDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/slider/SliderDeclarativeTest.java
new file mode 100644
index 0000000000..dcfb415810
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/slider/SliderDeclarativeTest.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2000-2014 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.slider;
+
+import org.junit.Test;
+
+import com.vaadin.shared.ui.slider.SliderOrientation;
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.Slider;
+
+/**
+ * Tests declarative support for implementations of {@link Slider}.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class SliderDeclarativeTest extends DeclarativeTestBase<Slider> {
+
+ @Test
+ public void testDefault() {
+ String design = "<vaadin-slider>";
+
+ Slider expected = new Slider();
+
+ testRead(design, expected);
+ testWrite(design, expected);
+ }
+
+ @Test
+ public void testHorizontal() {
+ String design = "<vaadin-slider min=10 max=20 resolution=1 value=12.3>";
+
+ Slider expected = new Slider();
+ expected.setMin(10.0);
+ expected.setMax(20.0);
+ expected.setResolution(1);
+ expected.setValue(12.3);
+
+ testRead(design, expected);
+ testWrite(design, expected);
+ }
+
+ @Test
+ public void testVertical() {
+ String design = "<vaadin-slider vertical>";
+
+ Slider expected = new Slider();
+ expected.setOrientation(SliderOrientation.VERTICAL);
+
+ testRead(design, expected);
+ testWrite(design, expected);
+ }
+
+ @Test
+ public void testReadOnlyValue() {
+ String design = "<vaadin-slider readonly min=10 max=20 resolution=1 value=12.3>";
+
+ Slider expected = new Slider();
+ expected.setMin(10.0);
+ expected.setMax(20.0);
+ expected.setResolution(1);
+ expected.setValue(12.3);
+ expected.setReadOnly(true);
+
+ testRead(design, expected);
+ testWrite(design, expected);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/slider/SliderTest.java b/server/src/test/java/com/vaadin/tests/server/component/slider/SliderTest.java
new file mode 100644
index 0000000000..8c093fdf72
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/slider/SliderTest.java
@@ -0,0 +1,135 @@
+package com.vaadin.tests.server.component.slider;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.ui.Slider;
+
+public class SliderTest {
+
+ @Test
+ public void minCannotBeLargerThanMax() {
+ Slider slider = new Slider();
+
+ slider.setMax(100);
+ slider.setMin(101);
+
+ assertThat(slider.getMin(), is(101.0));
+ assertThat(slider.getMax(), is(101.0));
+ }
+
+ @Test
+ public void maxCannotBeSmallerThanMin() {
+ Slider slider = new Slider();
+
+ slider.setMin(50);
+ slider.setMax(10);
+
+ assertThat(slider.getMax(), is(10.0));
+ assertThat(slider.getMin(), is(10.0));
+ }
+
+ @Test
+ public void valueOutOfBoundsExceptionMessageContainsBounds() {
+ Slider slider = new Slider();
+
+ try {
+
+ slider.setValue(-1.0);
+ } catch (Slider.ValueOutOfBoundsException e) {
+ assertThat(e.getMessage(),
+ containsString("Value -1.0 is out of bounds: [0.0, 100.0]"));
+ }
+ }
+
+ @Test
+ public void valueIsSet() {
+ Slider slider = new Slider();
+
+ slider.setValue(5.0);
+
+ assertThat(slider.getValue(), is(5.0));
+ }
+
+ @Test
+ public void valueCannotBeOutOfBounds() {
+ Slider s = new Slider(0, 10);
+
+ try {
+ s.setValue(20.0);
+ Assert.fail("Should throw out of bounds exception");
+ } catch (Slider.ValueOutOfBoundsException e) {
+ // TODO: handle exception
+ }
+ }
+
+ @Test
+ public void valueCanHaveLargePrecision() {
+ Slider slider = new Slider();
+ slider.setResolution(20);
+
+ slider.setValue(99.01234567891234567890123456789);
+
+ assertThat(slider.getValue(), is(99.01234567891234567890123456789));
+ }
+
+ @Test
+ public void doublesCanBeUsedAsLimits() {
+ Slider slider = new Slider(1.5, 2.5, 1);
+
+ assertThat(slider.getMin(), is(1.5));
+ assertThat(slider.getValue(), is(1.5));
+ assertThat(slider.getMax(), is(2.5));
+ }
+
+ @Test
+ public void valuesGreaterThanIntMaxValueCanBeUsed() {
+ double minValue = (double) Integer.MAX_VALUE + 1;
+
+ Slider s = new Slider(minValue, minValue + 1, 0);
+
+ assertThat(s.getValue(), is(minValue));
+ }
+
+ @Test
+ public void negativeValuesCanBeUsed() {
+ Slider slider = new Slider(-0.7, 1.0, 0);
+
+ slider.setValue(-0.4);
+
+ assertThat(slider.getValue(), is(-0.0));
+ }
+
+ @Test
+ public void boundariesAreRounded() {
+ Slider slider = new Slider(1.5, 2.5, 0);
+
+ slider.setValue(1.0);
+
+ assertThat(slider.getValue(), is(1.0));
+ assertThat(slider.getMin(), is(1.0));
+ assertThat(slider.getMax(), is(2.0));
+ }
+
+ @Test
+ public void valueWithSmallerPrecisionCanBeUsed() {
+ Slider slider = new Slider(0, 100, 10);
+
+ slider.setValue(1.2);
+
+ assertThat(slider.getValue(), is(1.2));
+ }
+
+ @Test
+ public void valueWithLargerPrecisionCanBeUsed() {
+ Slider slider = new Slider(0, 100, 2);
+
+ slider.setValue(1.2345);
+
+ assertThat(slider.getValue(), is(1.23));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/table/CacheUpdateExceptionCausesTest.java b/server/src/test/java/com/vaadin/tests/server/component/table/CacheUpdateExceptionCausesTest.java
new file mode 100644
index 0000000000..03f50c6b5f
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/table/CacheUpdateExceptionCausesTest.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2012 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.vaadin.tests.server.component.table;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.ui.Table;
+import com.vaadin.ui.Table.CacheUpdateException;
+
+public class CacheUpdateExceptionCausesTest {
+ @Test
+ public void testSingleCauseException() {
+ Table table = new Table();
+ Throwable[] causes = new Throwable[] { new RuntimeException(
+ "Broken in one way.") };
+
+ CacheUpdateException exception = new CacheUpdateException(table,
+ "Error during Table cache update.", causes);
+
+ Assert.assertSame(causes[0], exception.getCause());
+ Assert.assertEquals("Error during Table cache update.",
+ exception.getMessage());
+ }
+
+ @Test
+ public void testMultipleCauseException() {
+ Table table = new Table();
+ Throwable[] causes = new Throwable[] {
+ new RuntimeException("Broken in the first way."),
+ new RuntimeException("Broken in the second way.") };
+
+ CacheUpdateException exception = new CacheUpdateException(table,
+ "Error during Table cache update.", causes);
+
+ Assert.assertSame(causes[0], exception.getCause());
+ Assert.assertEquals(
+ "Error during Table cache update. Additional causes not shown.",
+ exception.getMessage());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/table/FooterTest.java b/server/src/test/java/com/vaadin/tests/server/component/table/FooterTest.java
new file mode 100644
index 0000000000..f9d373e864
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/table/FooterTest.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 FooterTest 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/src/test/java/com/vaadin/tests/server/component/table/MultipleSelectionTest.java b/server/src/test/java/com/vaadin/tests/server/component/table/MultipleSelectionTest.java
new file mode 100644
index 0000000000..ceb4c865d2
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/table/MultipleSelectionTest.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.shared.ui.MultiSelectMode;
+import com.vaadin.ui.Table;
+
+public class MultipleSelectionTest 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/src/test/java/com/vaadin/tests/server/component/table/TableColumnAlignmentsTest.java b/server/src/test/java/com/vaadin/tests/server/component/table/TableColumnAlignmentsTest.java
new file mode 100644
index 0000000000..69aaf2e3a9
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/table/TableColumnAlignmentsTest.java
@@ -0,0 +1,143 @@
+package com.vaadin.tests.server.component.table;
+
+import static org.junit.Assert.assertArrayEquals;
+
+import org.junit.Test;
+
+import com.vaadin.ui.Table;
+import com.vaadin.ui.Table.Align;
+
+public class TableColumnAlignmentsTest {
+
+ @Test
+ public void defaultColumnAlignments() {
+ for (int properties = 0; properties < 10; properties++) {
+ Table t = TableGeneratorTest.createTableWithDefaultContainer(
+ properties, 10);
+ Object[] expected = new Object[properties];
+ for (int i = 0; i < properties; i++) {
+ expected[i] = Align.LEFT;
+ }
+ org.junit.Assert.assertArrayEquals("getColumnAlignments", expected,
+ t.getColumnAlignments());
+ }
+ }
+
+ @Test
+ public void explicitColumnAlignments() {
+ int properties = 5;
+ Table t = TableGeneratorTest.createTableWithDefaultContainer(
+ properties, 10);
+ Align[] explicitAlignments = new Align[] { Align.CENTER, Align.LEFT,
+ Align.RIGHT, Align.RIGHT, Align.LEFT };
+
+ t.setColumnAlignments(explicitAlignments);
+
+ assertArrayEquals("Explicit visible columns, 5 properties",
+ explicitAlignments, t.getColumnAlignments());
+ }
+
+ @Test
+ public void invalidColumnAlignmentStrings() {
+ Table t = TableGeneratorTest.createTableWithDefaultContainer(3, 7);
+ Align[] defaultAlignments = new Align[] { Align.LEFT, Align.LEFT,
+ Align.LEFT };
+ try {
+ t.setColumnAlignments(new Align[] { Align.RIGHT, Align.RIGHT });
+ junit.framework.Assert
+ .fail("No exception thrown for invalid array length");
+ } catch (IllegalArgumentException e) {
+ // Ok, expected
+ }
+
+ assertArrayEquals("Invalid change affected alignments",
+ defaultAlignments, t.getColumnAlignments());
+
+ }
+
+ @Test
+ public void columnAlignmentForPropertyNotInContainer() {
+ Table t = TableGeneratorTest.createTableWithDefaultContainer(3, 7);
+ Align[] defaultAlignments = new Align[] { Align.LEFT, Align.LEFT,
+ Align.LEFT };
+ try {
+ t.setColumnAlignment("Property 1200", Align.LEFT);
+ // FIXME: Uncomment as there should be an exception (#6475)
+ // junit.framework.Assert
+ // .fail("No exception thrown for property not in container");
+ } catch (IllegalArgumentException e) {
+ // Ok, expected
+ }
+
+ assertArrayEquals("Invalid change affected alignments",
+ defaultAlignments, t.getColumnAlignments());
+
+ // FIXME: Uncomment as null should be returned (#6474)
+ // junit.framework.Assert.assertEquals(
+ // "Column alignment for property not in container returned",
+ // null, t.getColumnAlignment("Property 1200"));
+
+ }
+
+ @Test
+ public void invalidColumnAlignmentsLength() {
+ Table t = TableGeneratorTest.createTableWithDefaultContainer(7, 7);
+ Align[] defaultAlignments = new Align[] { Align.LEFT, Align.LEFT,
+ Align.LEFT, Align.LEFT, Align.LEFT, Align.LEFT, Align.LEFT };
+
+ try {
+ t.setColumnAlignments(new Align[] { Align.LEFT });
+ junit.framework.Assert
+ .fail("No exception thrown for invalid array length");
+ } catch (IllegalArgumentException e) {
+ // Ok, expected
+ }
+ assertArrayEquals("Invalid change affected alignments",
+ defaultAlignments, t.getColumnAlignments());
+
+ try {
+ t.setColumnAlignments(new Align[] {});
+ junit.framework.Assert
+ .fail("No exception thrown for invalid array length");
+ } catch (IllegalArgumentException e) {
+ // Ok, expected
+ }
+ assertArrayEquals("Invalid change affected alignments",
+ defaultAlignments, t.getColumnAlignments());
+
+ try {
+ t.setColumnAlignments(new Align[] { Align.LEFT, Align.LEFT,
+ Align.LEFT, Align.LEFT, Align.LEFT, Align.LEFT, Align.LEFT,
+ Align.LEFT });
+ junit.framework.Assert
+ .fail("No exception thrown for invalid array length");
+ } catch (IllegalArgumentException e) {
+ // Ok, expected
+ }
+ assertArrayEquals("Invalid change affected alignments",
+ defaultAlignments, t.getColumnAlignments());
+
+ }
+
+ @Test
+ public void explicitColumnAlignmentOneByOne() {
+ int properties = 5;
+ Table t = TableGeneratorTest.createTableWithDefaultContainer(
+ properties, 10);
+ Align[] explicitAlignments = new Align[] { Align.CENTER, Align.LEFT,
+ Align.RIGHT, Align.RIGHT, Align.LEFT };
+
+ Align[] currentAlignments = new Align[] { Align.LEFT, Align.LEFT,
+ Align.LEFT, Align.LEFT, Align.LEFT };
+
+ for (int i = 0; i < properties; i++) {
+ t.setColumnAlignment("Property " + i, explicitAlignments[i]);
+ currentAlignments[i] = explicitAlignments[i];
+
+ assertArrayEquals("Explicit visible columns, " + i
+ + " alignments set", currentAlignments,
+ t.getColumnAlignments());
+ }
+
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/table/TableContextClickTest.java b/server/src/test/java/com/vaadin/tests/server/component/table/TableContextClickTest.java
new file mode 100644
index 0000000000..d96a5d626a
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/table/TableContextClickTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.server.component.table;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.event.ContextClickEvent;
+import com.vaadin.event.ContextClickEvent.ContextClickListener;
+import com.vaadin.shared.ui.table.TableConstants.Section;
+import com.vaadin.ui.Table;
+
+public class TableContextClickTest extends Table {
+
+ private String error = null;
+ private boolean handled = false;
+
+ @Test
+ public void testContextClickListenerWithTableEvent() {
+ addContextClickListener(new ContextClickListener() {
+
+ @Override
+ public void contextClick(ContextClickEvent event) {
+ if (!(event instanceof TableContextClickEvent)) {
+ return;
+ }
+
+ TableContextClickEvent e = (TableContextClickEvent) event;
+ if (e.getSection() != Section.BODY) {
+ error = "Event section was not BODY.";
+ }
+ handled = true;
+ }
+ });
+ fireEvent(new TableContextClickEvent(this, null, null, null,
+ Section.BODY));
+
+ if (error != null) {
+ Assert.fail(error);
+ } else if (!handled) {
+ Assert.fail("Event was not handled by the ContextClickListener");
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/table/TableDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/table/TableDeclarativeTest.java
new file mode 100644
index 0000000000..7de6eaf2ef
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/table/TableDeclarativeTest.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.server.component.table;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.server.ExternalResource;
+import com.vaadin.shared.ui.MultiSelectMode;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.Table.Align;
+import com.vaadin.ui.Table.ColumnHeaderMode;
+import com.vaadin.ui.Table.RowHeaderMode;
+import com.vaadin.ui.Table.TableDragMode;
+import com.vaadin.ui.declarative.Design;
+
+/**
+ * Test declarative support for {@link Table}.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class TableDeclarativeTest extends TableDeclarativeTestBase {
+
+ @Test
+ public void testBasicAttributes() {
+
+ String design = "<"
+ + getTag()
+ + " page-length=30 cache-rate=3 selectable editable "
+ + "sortable=false sort-ascending=false sort-container-property-id=foo "
+ + "drag-mode=row multi-select-mode=simple column-header-mode=id row-header-mode=id "
+ + "column-reordering-allowed column-collapsing-allowed />";
+
+ Table table = getTable();
+ table.setPageLength(30);
+ table.setCacheRate(3);
+ table.setSelectable(true);
+ table.setEditable(true);
+
+ table.setSortEnabled(false);
+ table.setSortAscending(false);
+ table.setSortContainerPropertyId("foo");
+
+ table.setDragMode(TableDragMode.ROW);
+ table.setMultiSelectMode(MultiSelectMode.SIMPLE);
+ table.setColumnHeaderMode(ColumnHeaderMode.ID);
+ table.setRowHeaderMode(RowHeaderMode.ID);
+
+ table.setColumnReorderingAllowed(true);
+ table.setColumnCollapsingAllowed(true);
+
+ testRead(design, table);
+ testWrite(design, table);
+ }
+
+ @Test
+ public void testColumns() {
+ String design = "<"
+ + getTag()
+ + " column-collapsing-allowed>" //
+ + " <table>" //
+ + " <colgroup>"
+ + " <col property-id='foo' width=300>"
+ + " <col property-id='bar' center expand=1 collapsible=false>"
+ + " <col property-id='baz' right expand=2 collapsed>"
+ + " </colgroup>" //
+ + " </table>";
+
+ Table table = getTable();
+ table.setColumnCollapsingAllowed(true);
+
+ table.addContainerProperty("foo", String.class, null);
+ table.setColumnAlignment("foo", Align.LEFT);
+ table.setColumnWidth("foo", 300);
+
+ table.addContainerProperty("bar", String.class, null);
+ table.setColumnAlignment("bar", Align.CENTER);
+ table.setColumnExpandRatio("bar", 1);
+ table.setColumnCollapsible("bar", false);
+
+ table.addContainerProperty("baz", String.class, null);
+ table.setColumnAlignment("baz", Align.RIGHT);
+ table.setColumnExpandRatio("baz", 2);
+ table.setColumnCollapsed("baz", true);
+
+ testRead(design, table);
+ testWrite(design, table);
+ }
+
+ @Test
+ public void testHeadersFooters() {
+ String design = "<" + getTag()
+ + ">" //
+ + " <table>" //
+ + " <colgroup><col property-id=foo><col property-id=bar></colgroup>" //
+ + " <thead>" //
+ + " <tr><th icon='http://example.com/icon.png'>FOO<th>BAR" //
+ + " </thead>" //
+ + " <tfoot>" //
+ + " <tr><td>foo<td>bar" //
+ + " </tfoot>" //
+ + " </table>";
+
+ Table table = getTable();
+ table.setFooterVisible(true);
+
+ table.addContainerProperty("foo", String.class, null);
+ table.setColumnHeader("foo", "FOO");
+ table.setColumnIcon("foo", new ExternalResource(
+ "http://example.com/icon.png"));
+ table.setColumnFooter("foo", "foo");
+
+ table.addContainerProperty("bar", String.class, null);
+ table.setColumnHeader("bar", "BAR");
+ table.setColumnFooter("bar", "bar");
+
+ testRead(design, table);
+ testWrite(design, table);
+ }
+
+ @Test
+ public void testInlineData() {
+ String design = "<"
+ + getTag()
+ + ">" //
+ + " <table>" //
+ + " <colgroup>"
+ + " <col property-id='foo' />"
+ + " <col property-id='bar' />"
+ + " <col property-id='baz' />" //
+ + " </colgroup>" + " <thead>"
+ + " <tr><th>Description<th>Milestone<th>Status</tr>"
+ + " </thead>" + " <tbody>"
+ + " <tr item-id=1><td>r1c1</td><td>r1c2</td><td>r1c3</td>" //
+ + " <tr item-id=2><td>r2c1</td><td>r2c2</td><td>r2c3</td>" //
+ + " </tbody>" //
+ + " <tfoot>" //
+ + " <tr><td>F1<td>F2<td>F3</tr>" //
+ + " </tfoot>" //
+ + " </table>";
+
+ Table table = getTable();
+ table.addContainerProperty("foo", String.class, null);
+ table.addContainerProperty("bar", String.class, null);
+ table.addContainerProperty("baz", String.class, null);
+ table.setColumnHeaders("Description", "Milestone", "Status");
+ table.setColumnFooter("foo", "F1");
+ table.setColumnFooter("bar", "F2");
+ table.setColumnFooter("baz", "F3");
+ table.addItem(new Object[] { "r1c1", "r1c2", "r1c3" }, "1");
+ table.addItem(new Object[] { "r2c1", "r2c2", "r2c3" }, "2");
+ table.setFooterVisible(true);
+
+ testRead(design, table);
+ testWrite(design, table, true);
+ }
+
+ @Test
+ public void testHtmlEntities() {
+ String design = "<v-table>"
+ + "<table>"
+ + " <colgroup>"
+ + " <col property-id=\"test\""
+ + " </colgroup>"
+ + " <thead>"
+ + " <tr><th>&amp; Test</th></tr>"
+ + " </thead>"
+ + " <tbody>"
+ + " <tr item-id=\"test\"><td>&amp; Test</tr>"
+ + " </tbody>"
+ + " <tfoot>"
+ + " <tr><td>&amp; Test</td></tr>"
+ + " </tfoot>"
+ + "</table>"
+ + "</v-table>";
+ Table read = read(design);
+
+ Assert.assertEquals("& Test",
+ read.getContainerProperty("test", "test").getValue());
+ Assert.assertEquals("& Test", read.getColumnHeader("test"));
+ Assert.assertEquals("& Test", read.getColumnFooter("test"));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/table/TableDeclarativeTestBase.java b/server/src/test/java/com/vaadin/tests/server/component/table/TableDeclarativeTestBase.java
new file mode 100644
index 0000000000..1f0b3d924c
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/table/TableDeclarativeTestBase.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.server.component.table;
+
+import static org.junit.Assert.assertTrue;
+
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.Table;
+
+public abstract class TableDeclarativeTestBase extends
+ DeclarativeTestBase<Table> {
+
+ @Override
+ public Table testRead(String design, Table expected) {
+ Table read = super.testRead(design, expected);
+ compareColumns(read, expected);
+ compareBody(read, expected);
+ return read;
+ }
+
+ protected Table getTable() {
+ return new Table();
+ }
+
+ protected String getTag() {
+ return "vaadin-table";
+ }
+
+ protected void compareBody(Table read, Table expected) {
+ assertEquals("number of items", expected.getItemIds().size(), read
+ .getItemIds().size());
+ for (Object rowId : expected.getItemIds()) {
+ assertTrue(read.containsId(rowId));
+ for (Object propertyId : read.getVisibleColumns()) {
+ Object expectedItem = expected.getContainerProperty(rowId,
+ propertyId);
+ Object readItem = read.getContainerProperty(rowId, propertyId);
+ assertEquals("property '" + propertyId + "'", expectedItem,
+ readItem);
+ }
+ }
+ }
+
+ protected void compareColumns(Table read, Table expected) {
+ for (Object pid : expected.getVisibleColumns()) {
+ String col = "column '" + pid + "'";
+ assertEquals(col + " width", expected.getColumnWidth(pid),
+ read.getColumnWidth(pid));
+ assertEquals(col + " expand ratio",
+ expected.getColumnExpandRatio(pid),
+ read.getColumnExpandRatio(pid));
+ assertEquals(col + " collapsible",
+ expected.isColumnCollapsible(pid),
+ read.isColumnCollapsible(pid));
+ assertEquals(col + " collapsed", expected.isColumnCollapsed(pid),
+ read.isColumnCollapsed(pid));
+ assertEquals(col + " footer", expected.getColumnFooter(pid),
+ read.getColumnFooter(pid));
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/table/TableGeneratorTest.java b/server/src/test/java/com/vaadin/tests/server/component/table/TableGeneratorTest.java
new file mode 100644
index 0000000000..f3c2589f4a
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/table/TableGeneratorTest.java
@@ -0,0 +1,42 @@
+package com.vaadin.tests.server.component.table;
+
+import org.junit.Test;
+
+import com.vaadin.data.Item;
+import com.vaadin.ui.Table;
+
+public class TableGeneratorTest {
+ public static Table createTableWithDefaultContainer(int properties,
+ int items) {
+ Table t = new Table();
+
+ for (int i = 0; i < properties; i++) {
+ t.addContainerProperty("Property " + i, String.class, null);
+ }
+
+ for (int j = 0; j < items; j++) {
+ Item item = t.addItem("Item " + j);
+ for (int i = 0; i < properties; i++) {
+ item.getItemProperty("Property " + i).setValue(
+ "Item " + j + "/Property " + i);
+ }
+ }
+
+ return t;
+ }
+
+ @Test
+ public void testTableGenerator() {
+ Table t = createTableWithDefaultContainer(1, 1);
+ junit.framework.Assert.assertEquals(t.size(), 1);
+ junit.framework.Assert.assertEquals(t.getContainerPropertyIds().size(),
+ 1);
+
+ t = createTableWithDefaultContainer(100, 50);
+ junit.framework.Assert.assertEquals(t.size(), 50);
+ junit.framework.Assert.assertEquals(t.getContainerPropertyIds().size(),
+ 100);
+
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/table/TableListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/table/TableListenersTest.java
new file mode 100644
index 0000000000..fce514954a
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/table/TableListenersTest.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.AbstractListenerMethodsTestBase;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.Table.ColumnReorderEvent;
+import com.vaadin.ui.Table.ColumnReorderListener;
+import com.vaadin.ui.Table.ColumnResizeEvent;
+import com.vaadin.ui.Table.ColumnResizeListener;
+import com.vaadin.ui.Table.FooterClickEvent;
+import com.vaadin.ui.Table.FooterClickListener;
+import com.vaadin.ui.Table.HeaderClickEvent;
+import com.vaadin.ui.Table.HeaderClickListener;
+
+public class TableListenersTest extends AbstractListenerMethodsTestBase {
+ 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);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/table/TablePropertyValueConverterTest.java b/server/src/test/java/com/vaadin/tests/server/component/table/TablePropertyValueConverterTest.java
new file mode 100644
index 0000000000..7fd5bc67f6
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/table/TablePropertyValueConverterTest.java
@@ -0,0 +1,380 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.server.component.table;
+
+import java.lang.reflect.Field;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import org.junit.Test;
+
+import com.vaadin.data.Container;
+import com.vaadin.data.Item;
+import com.vaadin.data.Property;
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.data.util.converter.Converter;
+import com.vaadin.ui.Table;
+
+/**
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class TablePropertyValueConverterTest extends TestCase {
+ protected TestableTable table;
+ protected Collection<?> initialProperties;
+
+ @Test
+ public void testRemovePropertyId() {
+ Collection<Object> converters = table.getCurrentConverters();
+ assertTrue("Set of converters was empty at the start.",
+ converters.size() > 0);
+
+ Object firstId = converters.iterator().next();
+
+ table.removeContainerProperty(firstId);
+
+ Collection<Object> converters2 = table.getCurrentConverters();
+ assertTrue("FirstId was not removed", !converters2.contains(firstId));
+
+ assertTrue("The number of removed converters was not one.",
+ converters.size() - converters2.size() == 1);
+
+ for (Object originalId : converters) {
+ if (!originalId.equals(firstId)) {
+ assertTrue("The wrong converter was removed.",
+ converters2.contains(originalId));
+ }
+ }
+
+ }
+
+ @Test
+ public void testSetContainer() {
+ table.setContainerDataSource(createContainer(new String[] { "col1",
+ "col3", "col4", "col5" }));
+ Collection<Object> converters = table.getCurrentConverters();
+ assertTrue("There should only have been one converter left.",
+ converters.size() == 1);
+ Object onlyKey = converters.iterator().next();
+ assertTrue("The incorrect key was left.", onlyKey.equals("col1"));
+
+ }
+
+ @Test
+ public void testSetContainerWithInexactButCompatibleTypes() {
+ TestableTable customTable = new TestableTable("Test table",
+ createContainer(new String[] { "col1", "col2", "col3" },
+ new Class[] { String.class, BaseClass.class,
+ DerivedClass.class }));
+ customTable.setConverter("col1", new Converter<String, String>() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public String convertToModel(String value,
+ Class<? extends String> targetType, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ return "model";
+ }
+
+ @Override
+ public String convertToPresentation(String value,
+ Class<? extends String> targetType, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ return "presentation";
+ }
+
+ @Override
+ public Class<String> getModelType() {
+ return String.class;
+ }
+
+ @Override
+ public Class<String> getPresentationType() {
+ return String.class;
+ }
+
+ });
+ customTable.setConverter("col2", new Converter<String, BaseClass>() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public BaseClass convertToModel(String value,
+ Class<? extends BaseClass> targetType, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ return new BaseClass("model");
+ }
+
+ @Override
+ public Class<BaseClass> getModelType() {
+ return BaseClass.class;
+ }
+
+ @Override
+ public Class<String> getPresentationType() {
+ return String.class;
+ }
+
+ @Override
+ public String convertToPresentation(BaseClass value,
+ Class<? extends String> targetType, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ return null;
+ }
+ });
+ customTable.setConverter("col3", new Converter<String, DerivedClass>() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public DerivedClass convertToModel(String value,
+ Class<? extends DerivedClass> targetType, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ return new DerivedClass("derived" + 1001);
+ }
+
+ @Override
+ public Class<DerivedClass> getModelType() {
+ return DerivedClass.class;
+ }
+
+ @Override
+ public Class<String> getPresentationType() {
+ return String.class;
+ }
+
+ @Override
+ public String convertToPresentation(DerivedClass value,
+ Class<? extends String> targetType, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ return null;
+ }
+ });
+ customTable.setContainerDataSource(createContainer(new String[] {
+ "col1", "col2", "col3" }, new Class[] { DerivedClass.class,
+ DerivedClass.class, BaseClass.class }));
+ Set<Object> converters = customTable.getCurrentConverters();
+ // TODO Test temporarily disabled as this feature
+ // is not yet implemented in Table
+ /*
+ * assertTrue("Incompatible types were not removed.", converters.size()
+ * <= 1); assertTrue("Even compatible types were removed",
+ * converters.size() == 1); assertTrue("Compatible type was missing.",
+ * converters.contains("col2"));
+ */
+ }
+
+ @Test
+ public void testPrimitiveTypeConverters() {
+ TestableTable customTable = new TestableTable("Test table",
+ createContainer(new String[] { "col1", "col2", "col3" },
+ new Class[] { int.class, BaseClass.class,
+ DerivedClass.class }));
+ customTable.setConverter("col1", new Converter<String, Integer>() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public Integer convertToModel(String value,
+ Class<? extends Integer> targetType, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ return 11;
+ }
+
+ @Override
+ public String convertToPresentation(Integer value,
+ Class<? extends String> targetType, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ return "presentation";
+ }
+
+ @Override
+ public Class<Integer> getModelType() {
+ return Integer.class;
+ }
+
+ @Override
+ public Class<String> getPresentationType() {
+ return String.class;
+ }
+ });
+ Set<Object> converters = customTable.getCurrentConverters();
+ assertTrue("Converter was not set.", converters.size() > 0);
+ }
+
+ @Test
+ public void testInheritance() {
+ assertTrue("BaseClass isn't assignable from DerivedClass",
+ BaseClass.class.isAssignableFrom(DerivedClass.class));
+ assertFalse("DerivedClass is assignable from BaseClass",
+ DerivedClass.class.isAssignableFrom(BaseClass.class));
+ }
+
+ @Override
+ public void setUp() {
+ table = new TestableTable("Test table", createContainer(new String[] {
+ "col1", "col2", "col3" }));
+ table.setConverter("col1", new Converter<String, String>() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public String convertToModel(String value,
+ Class<? extends String> targetType, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ return "model";
+ }
+
+ @Override
+ public String convertToPresentation(String value,
+ Class<? extends String> targetType, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ return "presentation";
+ }
+
+ @Override
+ public Class<String> getModelType() {
+ return String.class;
+ }
+
+ @Override
+ public Class<String> getPresentationType() {
+ return String.class;
+ }
+
+ });
+
+ table.setConverter("col2", new Converter<String, String>() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public String convertToModel(String value,
+ Class<? extends String> targetType, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ return "model2";
+ }
+
+ @Override
+ public String convertToPresentation(String value,
+ Class<? extends String> targetType, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ return "presentation2";
+ }
+
+ @Override
+ public Class<String> getModelType() {
+ return String.class;
+ }
+
+ @Override
+ public Class<String> getPresentationType() {
+ return String.class;
+ }
+
+ });
+
+ initialProperties = table.getContainerPropertyIds();
+ }
+
+ private static Container createContainer(Object[] ids) {
+ Class[] types = new Class[ids.length];
+ for (int i = 0; i < types.length; ++i) {
+ types[i] = String.class;
+ }
+ return createContainer(ids, types);
+ }
+
+ private static Container createContainer(Object[] ids, Class[] types) {
+ IndexedContainer container = new IndexedContainer();
+ if (ids.length > types.length) {
+ throw new IllegalArgumentException("Too few defined types");
+ }
+ for (int i = 0; i < ids.length; ++i) {
+ container.addContainerProperty(ids[i], types[i], "");
+ }
+
+ for (int i = 0; i < 100; i++) {
+ Item item = container.addItem("item " + i);
+ for (int j = 0; j < ids.length; ++j) {
+ Property itemProperty = item.getItemProperty(ids[j]);
+ if (types[j] == String.class) {
+ itemProperty.setValue(ids[j].toString() + i);
+ } else if (types[j] == BaseClass.class) {
+ itemProperty.setValue(new BaseClass("base" + i));
+ } else if (types[j] == DerivedClass.class) {
+ itemProperty.setValue(new DerivedClass("derived" + i));
+ } else if (types[j] == int.class) {
+ // FIXME can't set values because the int is autoboxed into
+ // an Integer and not unboxed prior to set
+
+ // itemProperty.setValue(i);
+ } else {
+ throw new IllegalArgumentException(
+ "Unhandled type in createContainer: " + types[j]);
+ }
+ }
+ }
+
+ return container;
+ }
+
+ private class TestableTable extends Table {
+ /**
+ * @param string
+ * @param createContainer
+ */
+ public TestableTable(String string, Container container) {
+ super(string, container);
+ }
+
+ Set<Object> getCurrentConverters() {
+ try {
+ Field f = Table.class
+ .getDeclaredField("propertyValueConverters");
+ f.setAccessible(true);
+ HashMap<Object, Converter<String, Object>> pvc = (HashMap<Object, Converter<String, Object>>) f
+ .get(this);
+ Set<Object> currentConverters = new HashSet<Object>();
+ for (Entry<Object, Converter<String, Object>> entry : pvc
+ .entrySet()) {
+ currentConverters.add(entry.getKey());
+ }
+ return currentConverters;
+
+ } catch (Exception e) {
+ fail("Unable to retrieve propertyValueConverters");
+ return null;
+ }
+ }
+ }
+
+ private static class BaseClass {
+ private String title;
+
+ public BaseClass(String title) {
+ this.title = title;
+ }
+ }
+
+ private static class DerivedClass extends BaseClass {
+ public DerivedClass(String title) {
+ super(title);
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/table/TableSelectable.java b/server/src/test/java/com/vaadin/tests/server/component/table/TableSelectable.java
new file mode 100644
index 0000000000..1af99a08eb
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/table/TableSelectable.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.server.component.table;
+
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.ui.Table;
+
+/**
+ * Tests for 'selectable' property of {@link Table} class.
+ *
+ * @author Vaadin Ltd
+ */
+public class TableSelectable {
+
+ @Test
+ public void setSelectable_explicitSelectable_tableIsSelectable() {
+ Table table = new Table();
+ table.setSelectable(true);
+
+ Assert.assertTrue(table.isSelectable());
+ }
+
+ @Test
+ public void addValueChangeListener_explicitSelectable_tableIsSelectable() {
+ TestTable table = new TestTable();
+ table.addValueChangeListener(EasyMock
+ .createMock(ValueChangeListener.class));
+
+ Assert.assertTrue(table.isSelectable());
+ Assert.assertTrue(table.markAsDirtyCalled);
+ }
+
+ @Test
+ public void tableIsNotSelectableByDefult() {
+ Table table = new Table();
+
+ Assert.assertFalse(table.isSelectable());
+ }
+
+ @Test
+ public void setSelectable_explicitNotSelectable_tableIsNotSelectable() {
+ Table table = new Table();
+ table.setSelectable(false);
+ table.addValueChangeListener(EasyMock
+ .createMock(ValueChangeListener.class));
+
+ Assert.assertFalse(table.isSelectable());
+ }
+
+ private static final class TestTable extends Table {
+ @Override
+ public void markAsDirty() {
+ markAsDirtyCalled = true;
+ }
+
+ private boolean markAsDirtyCalled;
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/table/TableSerializationTest.java b/server/src/test/java/com/vaadin/tests/server/component/table/TableSerializationTest.java
new file mode 100644
index 0000000000..3f3c52d6c0
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/table/TableSerializationTest.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 TableSerializationTest 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/src/test/java/com/vaadin/tests/server/component/table/TableStateTest.java b/server/src/test/java/com/vaadin/tests/server/component/table/TableStateTest.java
new file mode 100644
index 0000000000..7f951e0835
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/table/TableStateTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.server.component.table;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.shared.ui.table.TableState;
+import com.vaadin.ui.Table;
+
+/**
+ * Tests for Table State.
+ *
+ */
+public class TableStateTest {
+
+ @Test
+ public void getState_tableHasCustomState() {
+ TestTable table = new TestTable();
+ TableState state = table.getState();
+ Assert.assertEquals("Unexpected state class", TableState.class,
+ state.getClass());
+ }
+
+ @Test
+ public void getPrimaryStyleName_tableHasCustomPrimaryStyleName() {
+ Table table = new Table();
+ TableState state = new TableState();
+ Assert.assertEquals("Unexpected primary style name",
+ state.primaryStyleName, table.getPrimaryStyleName());
+ }
+
+ @Test
+ public void tableStateHasCustomPrimaryStyleName() {
+ TableState state = new TableState();
+ Assert.assertEquals("Unexpected primary style name", "v-table",
+ state.primaryStyleName);
+ }
+
+ private static class TestTable extends Table {
+
+ @Override
+ public TableState getState() {
+ return super.getState();
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/table/TableVisibleColumnsTest.java b/server/src/test/java/com/vaadin/tests/server/component/table/TableVisibleColumnsTest.java
new file mode 100644
index 0000000000..e4f229590f
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/table/TableVisibleColumnsTest.java
@@ -0,0 +1,70 @@
+package com.vaadin.tests.server.component.table;
+
+import static org.junit.Assert.assertArrayEquals;
+
+import org.junit.Test;
+
+import com.vaadin.ui.Table;
+
+public class TableVisibleColumnsTest {
+
+ String[] defaultColumns3 = new String[] { "Property 0", "Property 1",
+ "Property 2" };
+
+ @Test
+ public void defaultVisibleColumns() {
+ for (int properties = 0; properties < 10; properties++) {
+ Table t = TableGeneratorTest.createTableWithDefaultContainer(
+ properties, 10);
+ Object[] expected = new Object[properties];
+ for (int i = 0; i < properties; i++) {
+ expected[i] = "Property " + i;
+ }
+ org.junit.Assert.assertArrayEquals("getVisibleColumns", expected,
+ t.getVisibleColumns());
+ }
+ }
+
+ @Test
+ public void explicitVisibleColumns() {
+ Table t = TableGeneratorTest.createTableWithDefaultContainer(5, 10);
+ Object[] newVisibleColumns = new Object[] { "Property 1", "Property 2" };
+ t.setVisibleColumns(newVisibleColumns);
+ assertArrayEquals("Explicit visible columns, 5 properties",
+ newVisibleColumns, t.getVisibleColumns());
+
+ }
+
+ @Test
+ public void invalidVisibleColumnIds() {
+ Table t = TableGeneratorTest.createTableWithDefaultContainer(3, 10);
+
+ try {
+ t.setVisibleColumns(new Object[] { "a", "Property 2", "Property 3" });
+ junit.framework.Assert.fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ // OK, expected
+ }
+ assertArrayEquals(defaultColumns3, t.getVisibleColumns());
+ }
+
+ @Test
+ public void duplicateVisibleColumnIds() {
+ Table t = TableGeneratorTest.createTableWithDefaultContainer(3, 10);
+ try {
+ t.setVisibleColumns(new Object[] { "Property 0", "Property 1",
+ "Property 2", "Property 1" });
+ } catch (IllegalArgumentException e) {
+ // OK, expected
+ }
+ assertArrayEquals(defaultColumns3, t.getVisibleColumns());
+ }
+
+ @Test
+ public void noVisibleColumns() {
+ Table t = TableGeneratorTest.createTableWithDefaultContainer(3, 10);
+ t.setVisibleColumns(new Object[] {});
+ assertArrayEquals(new Object[] {}, t.getVisibleColumns());
+
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/tabsheet/TabSheetDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/tabsheet/TabSheetDeclarativeTest.java
new file mode 100644
index 0000000000..22472850f6
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/tabsheet/TabSheetDeclarativeTest.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2000-2014 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.tabsheet;
+
+import org.junit.Test;
+
+import com.vaadin.server.ExternalResource;
+import com.vaadin.shared.ui.label.ContentMode;
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.TabSheet;
+import com.vaadin.ui.TabSheet.Tab;
+import com.vaadin.ui.TextField;
+
+/**
+ * Tests declarative support for TabSheet.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class TabSheetDeclarativeTest extends DeclarativeTestBase<TabSheet> {
+
+ @Test
+ public void testFeatures() {
+ String design = "<vaadin-tab-sheet tabindex=5><tab caption=test-caption "
+ + "visible=false closable enabled=false icon=http://www.vaadin.com/test.png"
+ + " icon-alt=OK description=test-desc style-name=test-style "
+ + "id=test-id><vaadin-text-field/></tab></vaadin-tab-sheet>";
+ TabSheet ts = new TabSheet();
+ ts.setTabIndex(5);
+ TextField tf = new TextField();
+ Tab tab = ts.addTab(tf);
+ tab.setCaption("test-caption");
+ tab.setVisible(false);
+ tab.setClosable(true);
+ tab.setEnabled(false);
+ tab.setIcon(new ExternalResource("http://www.vaadin.com/test.png"));
+ tab.setIconAlternateText("OK");
+ tab.setDescription("test-desc");
+ tab.setStyleName("test-style");
+ tab.setId("test-id");
+ ts.setSelectedTab(tf);
+ testRead(design, ts);
+ testWrite(design, ts);
+ }
+
+ @Test
+ public void testSelected() {
+ String design = "<vaadin-tab-sheet><tab selected><vaadin-text-field/></tab></vaadin-tab-sheet>";
+ TabSheet ts = new TabSheet();
+ TextField tf = new TextField();
+ ts.addTab(tf);
+ ts.setSelectedTab(tf);
+ testRead(design, ts);
+ testWrite(design, ts);
+ }
+
+ @Test
+ public void tabsNotShown() {
+ String design = "<vaadin-tab-sheet tabs-visible=\"false\">\n"
+ + " <tab caption=\"My Tab\" selected>\n"
+ + " <vaadin-label>My Content</vaadin-label>\n"
+ + " </tab>\n" + "</vaadin-tab-sheet>\n";
+ TabSheet ts = new TabSheet();
+ ts.setTabsVisible(false);
+ Label l = new Label("My Content", ContentMode.HTML);
+ Tab tab = ts.addTab(l);
+ tab.setCaption("My Tab");
+ ts.setSelectedTab(tab);
+ testRead(design, ts);
+ testWrite(design, ts);
+
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/tabsheet/TabSheetListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/tabsheet/TabSheetListenersTest.java
new file mode 100644
index 0000000000..b1acf05d63
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/tabsheet/TabSheetListenersTest.java
@@ -0,0 +1,13 @@
+package com.vaadin.tests.server.component.tabsheet;
+
+import com.vaadin.tests.server.component.AbstractListenerMethodsTestBase;
+import com.vaadin.ui.TabSheet;
+import com.vaadin.ui.TabSheet.SelectedTabChangeEvent;
+import com.vaadin.ui.TabSheet.SelectedTabChangeListener;
+
+public class TabSheetListenersTest extends AbstractListenerMethodsTestBase {
+ public void testSelectedTabChangeListenerAddGetRemove() throws Exception {
+ testListenerAddGetRemove(TabSheet.class, SelectedTabChangeEvent.class,
+ SelectedTabChangeListener.class);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/tabsheet/TabSheetTest.java b/server/src/test/java/com/vaadin/tests/server/component/tabsheet/TabSheetTest.java
new file mode 100644
index 0000000000..a45b2c5587
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/tabsheet/TabSheetTest.java
@@ -0,0 +1,286 @@
+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.SelectedTabChangeEvent;
+import com.vaadin.ui.TabSheet.SelectedTabChangeListener;
+import com.vaadin.ui.TabSheet.Tab;
+
+public class TabSheetTest {
+
+ @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)));
+ }
+
+ @Test
+ public void testSelectedTabChangeEvent_whenComponentReplaced() {
+
+ // given
+ final class SelectedTabExpectedComponentListener
+ implements SelectedTabChangeListener {
+
+ private Component actualComponent;
+
+ @Override
+ public void selectedTabChange(SelectedTabChangeEvent event) {
+ actualComponent = event.getTabSheet().getSelectedTab();
+
+ }
+
+ public void assertActualComponentIs(Component expectedComponent) {
+ assertEquals(expectedComponent, actualComponent);
+ actualComponent = null;
+ }
+ }
+ TabSheet tabSheet = new TabSheet();
+ final Label lbl1 = new Label("aaa");
+ final Label lbl2 = new Label("bbb");
+ final Label lbl3 = new Label("ccc");
+ final Label lbl4 = new Label("ddd");
+ tabSheet.addComponent(lbl1);
+ tabSheet.addComponent(lbl2);
+ tabSheet.addComponent(lbl3);
+ tabSheet.setSelectedTab(lbl2);
+ SelectedTabExpectedComponentListener listener = new SelectedTabExpectedComponentListener();
+ tabSheet.addSelectedTabChangeListener(listener);
+
+ // when selected tab is replaced with new Component
+ tabSheet.replaceComponent(lbl2, lbl4);
+
+ // then
+ listener.assertActualComponentIs(lbl4);
+ assertEquals(lbl4, tabSheet.getSelectedTab());
+
+ // when not selected tab is replaced with new Component
+ tabSheet.replaceComponent(lbl1, lbl2);
+
+ // then
+ assertEquals(lbl4, tabSheet.getSelectedTab());
+
+ // when not selected tab is replaced with existing Component
+ tabSheet.replaceComponent(lbl2, lbl3);
+
+ // then
+ assertEquals(lbl4, tabSheet.getSelectedTab());
+
+ // when selected tab is replaced with existing Component (locations are
+ // just swapped)
+ tabSheet.replaceComponent(lbl4, lbl3);
+
+ // then
+ listener.assertActualComponentIs(lbl3);
+ assertEquals(lbl3, tabSheet.getSelectedTab());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/textarea/TextAreaDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/textarea/TextAreaDeclarativeTest.java
new file mode 100644
index 0000000000..fdf2599370
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/textarea/TextAreaDeclarativeTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2000-2014 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.textarea;
+
+import java.io.IOException;
+
+import org.jsoup.nodes.Element;
+import org.jsoup.parser.Tag;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.TextArea;
+import com.vaadin.ui.declarative.DesignContext;
+
+/**
+ * Tests declarative support for implementations of {@link TextArea}.
+ *
+ * @since 7.4
+ * @author Vaadin Ltd
+ */
+public class TextAreaDeclarativeTest extends DeclarativeTestBase<TextArea> {
+
+ @Test
+ public void testTextArea() {
+ String design = "<vaadin-text-area rows=6 wordwrap=false>Hello World!</vaadin-text-area>";
+ TextArea ta = new TextArea();
+ ta.setRows(6);
+ ta.setWordwrap(false);
+ ta.setValue("Hello World!");
+ testRead(design, ta);
+ testWrite(design, ta);
+ }
+
+ @Test
+ public void testHtmlEntities() throws IOException {
+ String design = "<vaadin-text-area>&amp; Test</vaadin-text-area>";
+ TextArea read = read(design);
+ Assert.assertEquals("& Test", read.getValue());
+
+ read.setValue("&amp; Test");
+
+ DesignContext dc = new DesignContext();
+ Element root = new Element(Tag.valueOf("vaadin-text-area"), "");
+ read.writeDesign(root, dc);
+
+ Assert.assertEquals("&amp;amp; Test", root.html());
+ }
+
+ @Test
+ public void testReadOnlyValue() {
+ String design = "<vaadin-text-area readonly rows=6 wordwrap=false>Hello World!</vaadin-text-area>";
+ TextArea ta = new TextArea();
+ ta.setRows(6);
+ ta.setWordwrap(false);
+ ta.setValue("Hello World!");
+ ta.setReadOnly(true);
+ testRead(design, ta);
+ testWrite(design, ta);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/textfield/TextFieldDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/textfield/TextFieldDeclarativeTest.java
new file mode 100644
index 0000000000..63ea493344
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/textfield/TextFieldDeclarativeTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2014 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.textfield;
+
+import org.junit.Test;
+
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.TextField;
+
+/**
+ * Tests declarative support for implementations of {@link TextField}.
+ *
+ * @since 7.4
+ * @author Vaadin Ltd
+ */
+public class TextFieldDeclarativeTest extends DeclarativeTestBase<TextField> {
+
+ @Test
+ public void testEmpty() {
+ String design = "<vaadin-text-field/>";
+ TextField tf = new TextField();
+ testRead(design, tf);
+ testWrite(design, tf);
+ }
+
+ @Test
+ public void testValue() {
+ String design = "<vaadin-text-field value=\"test value\"/>";
+ TextField tf = new TextField();
+ tf.setValue("test value");
+ testRead(design, tf);
+ testWrite(design, tf);
+ }
+
+ @Test
+ public void testReadOnlyValue() {
+ String design = "<vaadin-text-field readonly value=\"test value\"/>";
+ TextField tf = new TextField();
+ tf.setValue("test value");
+ tf.setReadOnly(true);
+ testRead(design, tf);
+ testWrite(design, tf);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/textfield/TextFieldWithConverterAndValidatorTest.java b/server/src/test/java/com/vaadin/tests/server/component/textfield/TextFieldWithConverterAndValidatorTest.java
new file mode 100644
index 0000000000..83c45f94db
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/textfield/TextFieldWithConverterAndValidatorTest.java
@@ -0,0 +1,49 @@
+package com.vaadin.tests.server.component.textfield;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.data.validator.RangeValidator;
+import com.vaadin.tests.data.converter.ConverterFactoryTest.ConvertTo42;
+import com.vaadin.ui.TextField;
+
+public class TextFieldWithConverterAndValidatorTest extends TestCase {
+
+ private TextField field;
+ private ObjectProperty<Integer> property;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ field = new TextField();
+ field.setInvalidAllowed(false);
+ }
+
+ public void testConvert42AndValidator() {
+ property = new ObjectProperty<Integer>(123);
+ field.setConverter(new ConvertTo42());
+ field.setPropertyDataSource(property);
+
+ field.addValidator(new RangeValidator<Integer>("Incorrect value",
+ Integer.class, 42, 42));
+
+ // succeeds
+ field.setValue("a");
+ // succeeds
+ field.setValue("42");
+ // succeeds - no validation
+ property.setValue(42);
+
+ // nulls
+
+ // succeeds - validate() converts field value back to property type
+ // before validation
+ property.setValue(null);
+ field.validate();
+ // succeeds
+ field.setValue(null);
+ }
+
+ // TODO test converter changing value to null with validator
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/textfield/TextFieldWithPropertyFormatterTest.java b/server/src/test/java/com/vaadin/tests/server/component/textfield/TextFieldWithPropertyFormatterTest.java
new file mode 100644
index 0000000000..8f2bec455b
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/textfield/TextFieldWithPropertyFormatterTest.java
@@ -0,0 +1,106 @@
+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 TextFieldWithPropertyFormatterTest 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);
+ assertTrue(repainted >= 1);
+ 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/src/test/java/com/vaadin/tests/server/component/textfield/TextFieldWithValidatorTest.java b/server/src/test/java/com/vaadin/tests/server/component/textfield/TextFieldWithValidatorTest.java
new file mode 100644
index 0000000000..b2a51aad8b
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/textfield/TextFieldWithValidatorTest.java
@@ -0,0 +1,172 @@
+package com.vaadin.tests.server.component.textfield;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.Validator;
+import com.vaadin.data.Validator.InvalidValueException;
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.data.validator.EmailValidator;
+import com.vaadin.data.validator.RegexpValidator;
+import com.vaadin.data.validator.StringLengthValidator;
+import com.vaadin.ui.TextField;
+
+public class TextFieldWithValidatorTest extends TestCase {
+
+ private TextField field;
+ private ObjectProperty<String> property;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ field = new TextField();
+ field.setInvalidAllowed(false);
+ property = new ObjectProperty<String>("original");
+ field.setPropertyDataSource(property);
+ }
+
+ public void testMultipleValidators() {
+ field.addValidator(new StringLengthValidator(
+ "Length not between 1 and 3", 1, 3, false));
+ field.addValidator(new StringLengthValidator(
+ "Length not between 2 and 4", 2, 4, false));
+
+ // fails
+ try {
+ field.setValue("a");
+ fail();
+ } catch (InvalidValueException e) {
+ // should fail
+ }
+ // succeeds
+ field.setValue("ab");
+ // fails
+ try {
+ field.setValue("abcd");
+ fail();
+ } catch (InvalidValueException e) {
+ // should fail
+ }
+ }
+
+ public void testRemoveValidator() {
+ Validator validator1 = new StringLengthValidator(
+ "Length not between 1 and 3", 1, 3, false);
+ Validator validator2 = new StringLengthValidator(
+ "Length not between 2 and 4", 2, 4, false);
+
+ field.addValidator(validator1);
+ field.addValidator(validator2);
+ field.removeValidator(validator1);
+
+ // fails
+ try {
+ field.setValue("a");
+ fail();
+ } catch (InvalidValueException e) {
+ // should fail
+ }
+ // succeeds
+ field.setValue("ab");
+ // succeeds
+ field.setValue("abcd");
+ }
+
+ public void testRemoveAllValidators() {
+ Validator validator1 = new StringLengthValidator(
+ "Length not between 1 and 3", 1, 3, false);
+ Validator validator2 = new StringLengthValidator(
+ "Length not between 2 and 4", 2, 4, false);
+
+ field.addValidator(validator1);
+ field.addValidator(validator2);
+ field.removeAllValidators();
+
+ // all should succeed now
+ field.setValue("a");
+ field.setValue("ab");
+ field.setValue("abcd");
+ }
+
+ public void testEmailValidator() {
+ field.addValidator(new EmailValidator("Invalid e-mail address"));
+
+ // not required
+
+ field.setRequired(false);
+ // succeeds
+ field.setValue("");
+ // needed as required flag not checked by setValue()
+ field.validate();
+ // succeeds
+ field.setValue(null);
+ // needed as required flag not checked by setValue()
+ field.validate();
+ // succeeds
+ field.setValue("test@example.com");
+ // fails
+ try {
+ field.setValue("invalid e-mail");
+ fail();
+ } catch (InvalidValueException e) {
+ // should fail
+ }
+
+ // required
+
+ field.setRequired(true);
+ // fails
+ try {
+ field.setValue("");
+ // needed as required flag not checked by setValue()
+ field.validate();
+ fail();
+ } catch (InvalidValueException e) {
+ // should fail
+ }
+ // fails
+ try {
+ field.setValue(null);
+ // needed as required flag not checked by setValue()
+ field.validate();
+ fail();
+ } catch (InvalidValueException e) {
+ // should fail
+ }
+ // succeeds
+ field.setValue("test@example.com");
+ // fails
+ try {
+ field.setValue("invalid e-mail");
+ fail();
+ } catch (InvalidValueException e) {
+ // should fail
+ }
+ }
+
+ public void testRegexpValidator() {
+ field.addValidator(new RegexpValidator("pattern", true,
+ "Validation failed"));
+ field.setRequired(false);
+
+ // succeeds
+ field.setValue("");
+ // needed as required flag not checked by setValue()
+ field.validate();
+ // succeeds
+ field.setValue(null);
+ // needed as required flag not checked by setValue()
+ field.validate();
+ // succeeds
+ field.setValue("pattern");
+
+ // fails
+ try {
+ field.setValue("mismatch");
+ fail();
+ } catch (InvalidValueException e) {
+ // should fail
+ }
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/tree/ListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/tree/ListenersTest.java
new file mode 100644
index 0000000000..c327fe8c5f
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/tree/ListenersTest.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 ListenersTest 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/src/test/java/com/vaadin/tests/server/component/tree/TreeDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/tree/TreeDeclarativeTest.java
new file mode 100644
index 0000000000..8577ed1af8
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/tree/TreeDeclarativeTest.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2000-2014 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.tree;
+
+import org.junit.Test;
+
+import com.vaadin.server.ExternalResource;
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.Tree;
+import com.vaadin.ui.Tree.TreeDragMode;
+
+/**
+ * Tests the declarative support for implementations of {@link Tree}.
+ *
+ * @since 7.4
+ * @author Vaadin Ltd
+ */
+public class TreeDeclarativeTest extends DeclarativeTestBase<Tree> {
+
+ @Test
+ public void testDragMode() {
+ String design = "<vaadin-tree drag-mode='node' />";
+
+ Tree tree = new Tree();
+ tree.setDragMode(TreeDragMode.NODE);
+
+ testRead(design, tree);
+ testWrite(design, tree);
+ }
+
+ @Test
+ public void testEmpty() {
+ testRead("<vaadin-tree />", new Tree());
+ testWrite("<vaadin-tree />", new Tree());
+ }
+
+ @Test
+ public void testNodes() {
+ String design = "<vaadin-tree>" //
+ + " <node text='Node'/>" //
+ + " <node text='Parent'>" //
+ + " <node text='Child'>" //
+ + " <node text='Grandchild'/>" //
+ + " </node>" //
+ + " </node>" //
+ + " <node text='With icon' icon='http://example.com/icon.png'/>" //
+ + "</vaadin-tree>";
+
+ Tree tree = new Tree();
+
+ tree.addItem("Node");
+
+ tree.addItem("Parent");
+
+ tree.addItem("Child");
+ tree.setParent("Child", "Parent");
+
+ tree.addItem("Grandchild");
+ tree.setParent("Grandchild", "Child");
+
+ tree.addItem("With icon");
+ tree.setItemIcon("With icon", new ExternalResource(
+ "http://example.com/icon.png"));
+
+ testRead(design, tree);
+ testWrite(design, tree, true);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/tree/TreeListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/tree/TreeListenersTest.java
new file mode 100644
index 0000000000..449f418596
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/tree/TreeListenersTest.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.AbstractListenerMethodsTestBase;
+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 TreeListenersTest extends AbstractListenerMethodsTestBase {
+ 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);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/tree/TreeTest.java b/server/src/test/java/com/vaadin/tests/server/component/tree/TreeTest.java
new file mode 100644
index 0000000000..3e5425a875
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/tree/TreeTest.java
@@ -0,0 +1,178 @@
+package com.vaadin.tests.server.component.tree;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Field;
+import java.util.HashSet;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.Container;
+import com.vaadin.data.util.HierarchicalContainer;
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.shared.ui.tree.TreeState;
+import com.vaadin.ui.Tree;
+
+public class TreeTest {
+
+ private Tree tree;
+ private Tree tree2;
+ private Tree tree3;
+ private Tree tree4;
+
+ @Before
+ public void setUp() {
+ tree = new Tree();
+ tree.addItem("parent");
+ tree.addItem("child");
+ tree.setChildrenAllowed("parent", true);
+ tree.setParent("child", "parent");
+
+ tree2 = new Tree("Caption");
+ tree2.addItem("parent");
+ tree2.addItem("child");
+ tree2.setChildrenAllowed("parent", true);
+ tree2.setParent("child", "parent");
+
+ tree3 = new Tree("Caption", null);
+ tree3.addItem("parent");
+ tree3.addItem("child");
+ tree3.setChildrenAllowed("parent", true);
+ tree3.setParent("child", "parent");
+
+ tree4 = new Tree("Caption", new IndexedContainer());
+ tree4.addItem("parent");
+ tree4.addItem("child");
+ tree4.setChildrenAllowed("parent", true);
+ tree4.setParent("child", "parent");
+ }
+
+ @Test
+ public void testRemoveChildren() {
+ assertTrue(tree.hasChildren("parent"));
+ tree.removeItem("child");
+ assertFalse(tree.hasChildren("parent"));
+
+ assertTrue(tree2.hasChildren("parent"));
+ tree2.removeItem("child");
+ assertFalse(tree2.hasChildren("parent"));
+
+ assertTrue(tree3.hasChildren("parent"));
+ tree3.removeItem("child");
+ assertFalse(tree3.hasChildren("parent"));
+
+ assertTrue(tree4.hasChildren("parent"));
+ tree4.removeItem("child");
+ assertFalse(tree4.hasChildren("parent"));
+ }
+
+ @Test
+ public void testContainerTypeIsHierarchical() {
+ assertTrue(HierarchicalContainer.class.isAssignableFrom(tree
+ .getContainerDataSource().getClass()));
+ assertTrue(HierarchicalContainer.class.isAssignableFrom(tree2
+ .getContainerDataSource().getClass()));
+ assertTrue(HierarchicalContainer.class.isAssignableFrom(tree3
+ .getContainerDataSource().getClass()));
+ assertFalse(HierarchicalContainer.class.isAssignableFrom(tree4
+ .getContainerDataSource().getClass()));
+ assertTrue(Container.Hierarchical.class.isAssignableFrom(tree4
+ .getContainerDataSource().getClass()));
+ }
+
+ @Test
+ public void testRemoveExpandedItems() throws Exception {
+ tree.expandItem("parent");
+ tree.expandItem("child");
+
+ Field expandedField = tree.getClass().getDeclaredField("expanded");
+ Field expandedItemIdField = tree.getClass().getDeclaredField(
+ "expandedItemId");
+
+ expandedField.setAccessible(true);
+ expandedItemIdField.setAccessible(true);
+
+ HashSet<Object> expanded = (HashSet<Object>) expandedField.get(tree);
+ Object expandedItemId = expandedItemIdField.get(tree);
+
+ assertEquals(2, expanded.size());
+ assertTrue("Contains parent", expanded.contains("parent"));
+ assertTrue("Contains child", expanded.contains("child"));
+ assertEquals("child", expandedItemId);
+
+ tree.removeItem("parent");
+
+ expanded = (HashSet<Object>) expandedField.get(tree);
+ expandedItemId = expandedItemIdField.get(tree);
+
+ assertEquals(1, expanded.size());
+ assertTrue("Contains child", expanded.contains("child"));
+ assertEquals("child", expandedItemId);
+
+ tree.removeItem("child");
+
+ expanded = (HashSet<Object>) expandedField.get(tree);
+ expandedItemId = expandedItemIdField.get(tree);
+
+ assertEquals(0, expanded.size());
+ assertNull(expandedItemId);
+ }
+
+ @Test
+ public void testRemoveExpandedItemsOnContainerChange() throws Exception {
+ tree.expandItem("parent");
+ tree.expandItem("child");
+
+ tree.setContainerDataSource(new HierarchicalContainer());
+
+ Field expandedField = tree.getClass().getDeclaredField("expanded");
+ Field expandedItemIdField = tree.getClass().getDeclaredField(
+ "expandedItemId");
+
+ expandedField.setAccessible(true);
+ expandedItemIdField.setAccessible(true);
+
+ HashSet<Object> expanded = (HashSet<Object>) expandedField.get(tree);
+ assertEquals(0, expanded.size());
+
+ Object expandedItemId = expandedItemIdField.get(tree);
+ assertNull(expandedItemId);
+ }
+
+ @Test
+ public void getState_treeHasCustomState() {
+ TestTree table = new TestTree();
+ TreeState state = table.getState();
+ Assert.assertEquals("Unexpected state class", TreeState.class,
+ state.getClass());
+ }
+
+ @Test
+ public void getPrimaryStyleName_treeHasCustomPrimaryStyleName() {
+ Tree table = new Tree();
+ TreeState state = new TreeState();
+ Assert.assertEquals("Unexpected primary style name",
+ state.primaryStyleName, table.getPrimaryStyleName());
+ }
+
+ @Test
+ public void treeStateHasCustomPrimaryStyleName() {
+ TreeState state = new TreeState();
+ Assert.assertEquals("Unexpected primary style name", "v-tree",
+ state.primaryStyleName);
+ }
+
+ private static class TestTree extends Tree {
+
+ @Override
+ public TreeState getState() {
+ return super.getState();
+ }
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/treetable/EmptyTreeTableTest.java b/server/src/test/java/com/vaadin/tests/server/component/treetable/EmptyTreeTableTest.java
new file mode 100644
index 0000000000..a886b74f57
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/treetable/EmptyTreeTableTest.java
@@ -0,0 +1,13 @@
+package com.vaadin.tests.server.component.treetable;
+
+import junit.framework.TestCase;
+
+import com.vaadin.ui.TreeTable;
+
+public class EmptyTreeTableTest extends TestCase {
+ public void testLastId() {
+ TreeTable treeTable = new TreeTable();
+
+ assertFalse(treeTable.isLastId(treeTable.getValue()));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableDeclarativeTest.java
new file mode 100644
index 0000000000..9d614eccc9
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableDeclarativeTest.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.server.component.treetable;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.tests.server.component.table.TableDeclarativeTest;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.TreeTable;
+import com.vaadin.ui.declarative.DesignException;
+
+/**
+ * Test declarative support for {@link TreeTable}.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class TreeTableDeclarativeTest extends TableDeclarativeTest {
+
+ @Test
+ public void testAttributes() {
+ String design = "<vaadin-tree-table animations-enabled>";
+ TreeTable table = getTable();
+ table.setAnimationsEnabled(true);
+
+ testRead(design, table);
+ testWrite(design, table);
+ }
+
+ @Test
+ public void testHierarchy() {
+ String design = "<vaadin-tree-table>" //
+ + "<table>" //
+ + "<colgroup><col property-id=''></colgroup>" //
+ + "<tbody>" //
+ + " <tr item-id='1'><td></tr>" //
+ + " <tr depth=1 item-id='1.1'><td></tr>" //
+ + " <tr depth=1 item-id='1.2'><td></tr>" //
+ + " <tr depth=2 item-id='1.2.1'><td></tr>" //
+ + " <tr depth=3 item-id='1.2.1.1'><td></tr>" //
+ + " <tr depth=2 item-id='1.2.2'><td></tr>" //
+ + " <tr item-id='2'><td></tr>" //
+ + " <tr depth=1 item-id='2.1'><td></tr>" //
+ + "</tbody>" //
+ + "</table>" //
+ + "</vaadin-tree-table>";
+
+ TreeTable table = getTable();
+ table.addContainerProperty("", String.class, "");
+
+ table.addItem("1");
+ table.addItem("1.1");
+ table.setParent("1.1", "1");
+ table.addItem("1.2");
+ table.setParent("1.2", "1");
+ table.addItem("1.2.1");
+ table.setParent("1.2.1", "1.2");
+ table.addItem("1.2.1.1");
+ table.setParent("1.2.1.1", "1.2.1");
+ table.addItem("1.2.2");
+ table.setParent("1.2.2", "1.2");
+ table.addItem("2");
+ table.addItem("2.1");
+ table.setParent("2.1", "2");
+
+ testRead(design, table);
+ testWrite(design, table, true);
+ }
+
+ @Test
+ public void testCollapsed() {
+ String design = "<vaadin-tree-table>" //
+ + " <table>" //
+ + " <colgroup><col property-id=''></colgroup>" //
+ + " <tbody>" //
+ + " <tr item-id='1' collapsed=false><td></tr>" //
+ + " <tr depth=1 item-id='1.1'><td></tr>" //
+ + " <tr depth=2 item-id='1.1.1'><td></tr>" //
+ + " </tbody>" //
+ + " </table>" //
+ + "</vaadin-tree-table>";
+
+ TreeTable table = getTable();
+ table.addContainerProperty("", String.class, "");
+
+ table.addItem("1");
+ table.setCollapsed("1", false);
+ table.addItem("1.1");
+ table.setParent("1.1", "1");
+ table.addItem("1.1.1");
+ table.setParent("1.1.1", "1.1");
+
+ testRead(design, table);
+ testWrite(design, table, true);
+ }
+
+ @Test
+ public void testMalformedHierarchy() {
+ assertMalformed("<tr depth=-4><td>");
+ assertMalformed("<tr depth=1><td>");
+ assertMalformed("<tr><td><tr depth=3><td>");
+ }
+
+ protected void assertMalformed(String hierarchy) {
+ String design = "<vaadin-tree-table>" //
+ + " <table>" //
+ + " <colgroup><col property-id=''></colgroup>" //
+ + " <tbody>" + hierarchy + "</tbody>" //
+ + " </table>" //
+ + "</vaadin-tree-table>";
+
+ try {
+ read(design);
+ Assert.fail("Malformed hierarchy should fail: " + hierarchy);
+ } catch (DesignException expected) {
+ }
+ }
+
+ @Override
+ protected void compareBody(Table read, Table expected) {
+ super.compareBody(read, expected);
+
+ for (Object itemId : read.getItemIds()) {
+ Assert.assertEquals("parent of item " + itemId,
+ ((TreeTable) expected).getParent(itemId),
+ ((TreeTable) read).getParent(itemId));
+ Assert.assertEquals("collapsed status of item " + itemId,
+ ((TreeTable) expected).isCollapsed(itemId),
+ ((TreeTable) read).isCollapsed(itemId));
+ }
+ }
+
+ @Override
+ protected TreeTable getTable() {
+ return new TreeTable();
+ }
+
+ @Override
+ protected String getTag() {
+ return "vaadin-tree-table";
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableSetContainerNullTest.java b/server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableSetContainerNullTest.java
new file mode 100644
index 0000000000..4a34094da1
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableSetContainerNullTest.java
@@ -0,0 +1,15 @@
+package com.vaadin.tests.server.component.treetable;
+
+import junit.framework.TestCase;
+
+import com.vaadin.ui.TreeTable;
+
+public class TreeTableSetContainerNullTest extends TestCase {
+
+ public void testNullContainer() {
+ TreeTable treeTable = new TreeTable();
+
+ // should not cause an exception
+ treeTable.setContainerDataSource(null);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableTest.java b/server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableTest.java
new file mode 100644
index 0000000000..33f41d84ea
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.server.component.treetable;
+
+import java.util.EnumSet;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.shared.ui.treetable.TreeTableState;
+import com.vaadin.ui.Table.RowHeaderMode;
+import com.vaadin.ui.TreeTable;
+
+/**
+ * Tests for {@link TreeTable}
+ *
+ * @author Vaadin Ltd
+ */
+public class TreeTableTest {
+
+ @Test
+ public void rowHeadersAreEnabled_iconRowHeaderMode_rowHeadersAreDisabled() {
+ TestTreeTable tree = new TestTreeTable();
+ tree.setRowHeaderMode(RowHeaderMode.ICON_ONLY);
+
+ Assert.assertFalse("Row headers are enabled for Icon header mode",
+ tree.rowHeadersAreEnabled());
+ }
+
+ @Test
+ public void rowHeadersAreEnabled_hiddenRowHeaderMode_rowHeadersAreDisabled() {
+ TestTreeTable tree = new TestTreeTable();
+ tree.setRowHeaderMode(RowHeaderMode.HIDDEN);
+
+ Assert.assertFalse("Row headers are enabled for Hidden header mode",
+ tree.rowHeadersAreEnabled());
+ }
+
+ @Test
+ public void rowHeadersAreEnabled_otherRowHeaderModes_rowHeadersAreEnabled() {
+ TestTreeTable tree = new TestTreeTable();
+ EnumSet<RowHeaderMode> modes = EnumSet.allOf(RowHeaderMode.class);
+ modes.remove(RowHeaderMode.ICON_ONLY);
+ modes.remove(RowHeaderMode.HIDDEN);
+
+ for (RowHeaderMode mode : modes) {
+ tree.setRowHeaderMode(mode);
+ Assert.assertTrue("Row headers are disabled for " + mode
+ + " header mode", tree.rowHeadersAreEnabled());
+ }
+ }
+
+ @Test
+ public void getState_treeTableHasCustomState() {
+ TestTreeTable table = new TestTreeTable();
+ TreeTableState state = table.getState();
+ Assert.assertEquals("Unexpected state class", TreeTableState.class,
+ state.getClass());
+ }
+
+ @Test
+ public void getPrimaryStyleName_treeTableHasCustomPrimaryStyleName() {
+ TreeTable table = new TreeTable();
+ TreeTableState state = new TreeTableState();
+ Assert.assertEquals("Unexpected primary style name",
+ state.primaryStyleName, table.getPrimaryStyleName());
+ }
+
+ @Test
+ public void treeTableStateHasCustomPrimaryStyleName() {
+ TreeTableState state = new TreeTableState();
+ Assert.assertEquals("Unexpected primary style name", "v-table",
+ state.primaryStyleName);
+ }
+
+ private static class TestTreeTable extends TreeTable {
+
+ @Override
+ protected boolean rowHeadersAreEnabled() {
+ return super.rowHeadersAreEnabled();
+ }
+
+ @Override
+ public TreeTableState getState() {
+ return super.getState();
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/twincolselect/TwinColSelectDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/twincolselect/TwinColSelectDeclarativeTest.java
new file mode 100644
index 0000000000..146d1f1ad1
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/twincolselect/TwinColSelectDeclarativeTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2000-2014 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.twincolselect;
+
+import java.util.Arrays;
+
+import org.junit.Test;
+
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.TwinColSelect;
+
+/**
+ * Test cases for reading the properties of selection components.
+ *
+ * @author Vaadin Ltd
+ */
+public class TwinColSelectDeclarativeTest extends
+ DeclarativeTestBase<TwinColSelect> {
+
+ public String getBasicDesign() {
+ return "<vaadin-twin-col-select rows=5 right-column-caption='Selected values' left-column-caption='Unselected values'>\n"
+ + " <option>First item</option>\n"
+ + " <option selected>Second item</option>\n"
+ + " <option selected>Third item</option>\n"
+ + "</vaadin-twin-col-select>";
+
+ }
+
+ public TwinColSelect getBasicExpected() {
+ TwinColSelect s = new TwinColSelect();
+ s.setRightColumnCaption("Selected values");
+ s.setLeftColumnCaption("Unselected values");
+ s.addItem("First item");
+ s.addItem("Second item");
+ s.addItem("Third item");
+ s.setValue(Arrays.asList(new Object[] { "Second item", "Third item" }));
+ s.setRows(5);
+ return s;
+ }
+
+ @Test
+ public void testReadBasic() {
+ testRead(getBasicDesign(), getBasicExpected());
+ }
+
+ @Test
+ public void testWriteBasic() {
+ testWrite(stripOptionTags(getBasicDesign()), getBasicExpected());
+ }
+
+ @Test
+ public void testReadEmpty() {
+ testRead("<vaadin-twin-col-select />", new TwinColSelect());
+ }
+
+ @Test
+ public void testWriteEmpty() {
+ testWrite("<vaadin-twin-col-select />", new TwinColSelect());
+ }
+
+} \ No newline at end of file
diff --git a/server/src/test/java/com/vaadin/tests/server/component/twincolselect/TwinColSelectStateTest.java b/server/src/test/java/com/vaadin/tests/server/component/twincolselect/TwinColSelectStateTest.java
new file mode 100644
index 0000000000..b2e2c0a65b
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/twincolselect/TwinColSelectStateTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2014 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.twincolselect;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.shared.ui.twincolselect.TwinColSelectState;
+import com.vaadin.ui.TwinColSelect;
+
+/**
+ * Tests for TwinColSelectState.
+ *
+ */
+public class TwinColSelectStateTest {
+
+ @Test
+ public void getState_selectHasCustomState() {
+ TestTwinColSelect select = new TestTwinColSelect();
+ TwinColSelectState state = select.getState();
+ Assert.assertEquals("Unexpected state class", TwinColSelectState.class,
+ state.getClass());
+ }
+
+ @Test
+ public void getPrimaryStyleName_selectHasCustomPrimaryStyleName() {
+ TwinColSelect table = new TwinColSelect();
+ TwinColSelectState state = new TwinColSelectState();
+ Assert.assertEquals("Unexpected primary style name",
+ state.primaryStyleName, table.getPrimaryStyleName());
+ }
+
+ @Test
+ public void selectStateHasCustomPrimaryStyleName() {
+ TwinColSelectState state = new TwinColSelectState();
+ Assert.assertEquals("Unexpected primary style name",
+ "v-select-twincol", state.primaryStyleName);
+ }
+
+ private static class TestTwinColSelect extends TwinColSelect {
+
+ @Override
+ public TwinColSelectState getState() {
+ return super.getState();
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/ui/CustomUIClassLoaderTest.java b/server/src/test/java/com/vaadin/tests/server/component/ui/CustomUIClassLoaderTest.java
new file mode 100644
index 0000000000..470f04c15c
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/ui/CustomUIClassLoaderTest.java
@@ -0,0 +1,124 @@
+package com.vaadin.tests.server.component.ui;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import junit.framework.TestCase;
+
+import org.easymock.EasyMock;
+
+import com.vaadin.server.DefaultDeploymentConfiguration;
+import com.vaadin.server.DefaultUIProvider;
+import com.vaadin.server.DeploymentConfiguration;
+import com.vaadin.server.UIClassSelectionEvent;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.VaadinService;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.tests.util.AlwaysLockedVaadinSession;
+import com.vaadin.ui.UI;
+
+public class CustomUIClassLoaderTest extends TestCase {
+
+ /**
+ * Stub root
+ */
+ public static class MyUI extends UI {
+ @Override
+ protected void init(VaadinRequest 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 testWithDefaultClassLoader() throws Exception {
+ VaadinSession application = createStubApplication();
+ application.setConfiguration(createConfigurationMock());
+
+ DefaultUIProvider uiProvider = new DefaultUIProvider();
+ Class<? extends UI> uiClass = uiProvider
+ .getUIClass(new UIClassSelectionEvent(
+ createRequestMock(getClass().getClassLoader())));
+
+ assertEquals(MyUI.class, uiClass);
+ }
+
+ private static DeploymentConfiguration createConfigurationMock() {
+ Properties properties = new Properties();
+ properties.put(VaadinSession.UI_PARAMETER, MyUI.class.getName());
+ return new DefaultDeploymentConfiguration(
+ CustomUIClassLoaderTest.class, properties);
+ }
+
+ private static VaadinRequest createRequestMock(ClassLoader classloader) {
+ // Mock a VaadinService to give the passed classloader
+ VaadinService configurationMock = EasyMock
+ .createMock(VaadinService.class);
+ EasyMock.expect(configurationMock.getDeploymentConfiguration())
+ .andReturn(createConfigurationMock());
+ EasyMock.expect(configurationMock.getClassLoader()).andReturn(
+ classloader);
+
+ // Mock a VaadinRequest to give the mocked vaadin service
+ VaadinRequest requestMock = EasyMock.createMock(VaadinRequest.class);
+ EasyMock.expect(requestMock.getService()).andReturn(configurationMock);
+ EasyMock.expect(requestMock.getService()).andReturn(configurationMock);
+ EasyMock.expect(requestMock.getService()).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();
+
+ DefaultUIProvider uiProvider = new DefaultUIProvider();
+ Class<? extends UI> uiClass = uiProvider
+ .getUIClass(new UIClassSelectionEvent(
+ createRequestMock(loggingClassLoader)));
+
+ assertEquals(MyUI.class, uiClass);
+ assertEquals(1, loggingClassLoader.requestedClasses.size());
+ assertEquals(MyUI.class.getName(),
+ loggingClassLoader.requestedClasses.get(0));
+
+ }
+
+ private VaadinSession createStubApplication() {
+ return new AlwaysLockedVaadinSession(null) {
+ @Override
+ public DeploymentConfiguration getConfiguration() {
+ return createConfigurationMock();
+ }
+ };
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/ui/LegacyUIAddRemoveComponentsTest.java b/server/src/test/java/com/vaadin/tests/server/component/ui/LegacyUIAddRemoveComponentsTest.java
new file mode 100644
index 0000000000..2a88bb3208
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/ui/LegacyUIAddRemoveComponentsTest.java
@@ -0,0 +1,65 @@
+package com.vaadin.tests.server.component.ui;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+
+import org.junit.Test;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.LegacyWindow;
+
+public class LegacyUIAddRemoveComponentsTest {
+
+ private static class TestUI extends LegacyWindow {
+ @Override
+ protected void init(VaadinRequest request) {
+ }
+ }
+
+ @Test
+ public void addComponent() {
+ TestUI ui = new TestUI();
+ Component c = new Label("abc");
+
+ ui.addComponent(c);
+
+ assertSame(c.getParent(), ui.iterator().next());
+ assertSame(c, ui.getContent().iterator().next());
+ assertEquals(1, ui.getComponentCount());
+ assertEquals(1, ui.getContent().getComponentCount());
+ }
+
+ @Test
+ public void removeComponent() {
+ TestUI ui = new TestUI();
+ Component c = new Label("abc");
+
+ ui.addComponent(c);
+
+ ui.removeComponent(c);
+
+ assertEquals(ui.getContent(), ui.iterator().next());
+ assertFalse(ui.getContent().iterator().hasNext());
+ assertEquals(1, ui.getComponentCount());
+ assertEquals(0, ui.getContent().getComponentCount());
+ }
+
+ @Test
+ public void replaceComponent() {
+ TestUI ui = new TestUI();
+ Component c = new Label("abc");
+ Component d = new Label("def");
+
+ ui.addComponent(c);
+
+ ui.replaceComponent(c, d);
+
+ assertSame(d.getParent(), ui.iterator().next());
+ assertSame(d, ui.getContent().iterator().next());
+ assertEquals(1, ui.getComponentCount());
+ assertEquals(1, ui.getContent().getComponentCount());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/upload/UploadDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/upload/UploadDeclarativeTest.java
new file mode 100644
index 0000000000..12f319c6ad
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/upload/UploadDeclarativeTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2000-2014 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.upload;
+
+import org.junit.Test;
+
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.Upload;
+
+/**
+ * Tests the declarative support for implementations of {@link Upload}.
+ *
+ * @since 7.4
+ * @author Vaadin Ltd
+ */
+public class UploadDeclarativeTest extends DeclarativeTestBase<Upload> {
+
+ @Test
+ public void testReadBasic() {
+ testRead(getBasicDesign(), getBasicExpected());
+ }
+
+ @Test
+ public void testWriteBasic() {
+ testWrite(getBasicDesign(), getBasicExpected());
+ }
+
+ private String getBasicDesign() {
+ return "<vaadin-upload button-caption='Send the file' tabindex=5 />";
+ }
+
+ private Upload getBasicExpected() {
+ Upload u = new Upload();
+ u.setButtonCaption("Send the file");
+ u.setTabIndex(5);
+ return u;
+ }
+
+ @Test
+ public void testReadEmpty() {
+ testRead("<vaadin-upload />", new Upload());
+ }
+
+ @Test
+ public void testWriteEmpty() {
+ testWrite("<vaadin-upload />", new Upload());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/upload/UploadListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/upload/UploadListenersTest.java
new file mode 100644
index 0000000000..13d4c6bfe6
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/upload/UploadListenersTest.java
@@ -0,0 +1,41 @@
+package com.vaadin.tests.server.component.upload;
+
+import com.vaadin.server.StreamVariable.StreamingProgressEvent;
+import com.vaadin.tests.server.component.AbstractListenerMethodsTestBase;
+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 UploadListenersTest extends AbstractListenerMethodsTestBase {
+ 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/src/test/java/com/vaadin/tests/server/component/upload/UploadTest.java b/server/src/test/java/com/vaadin/tests/server/component/upload/UploadTest.java
new file mode 100644
index 0000000000..358e4db9cd
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/upload/UploadTest.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2000-2014 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.upload;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.server.StreamVariable;
+import com.vaadin.server.StreamVariable.StreamingErrorEvent;
+import com.vaadin.shared.ui.upload.UploadState;
+import com.vaadin.ui.Upload;
+
+/**
+ *
+ * @author Vaadin Ltd
+ */
+public class UploadTest {
+
+ @Test
+ public void getStreamVariable_streamingFailed_endUploadIsCalled() {
+ TestUpload upload = new TestUpload();
+ upload.startUpload();
+ StreamVariable variable = upload.getStreamVariable();
+ try {
+ variable.streamingFailed(new TestStreamingErrorEvent());
+ } catch (Exception e) {
+ }
+ Assert.assertFalse(upload.isUploading());
+ }
+
+ @Test
+ public void getState_uploadHasCustomState() {
+ TestUpload upload = new TestUpload();
+ UploadState state = upload.getState();
+ Assert.assertEquals("Unexpected state class", UploadState.class,
+ state.getClass());
+ }
+
+ @Test
+ public void getPrimaryStyleName_uploadHasCustomPrimaryStyleName() {
+ Upload upload = new Upload();
+ UploadState state = new UploadState();
+ Assert.assertEquals("Unexpected primary style name",
+ state.primaryStyleName, upload.getPrimaryStyleName());
+ }
+
+ @Test
+ public void uploadStateHasCustomPrimaryStyleName() {
+ UploadState state = new UploadState();
+ Assert.assertEquals("Unexpected primary style name", "v-upload",
+ state.primaryStyleName);
+ }
+
+ private static class TestStreamingErrorEvent implements StreamingErrorEvent {
+
+ @Override
+ public String getFileName() {
+ return null;
+ }
+
+ @Override
+ public String getMimeType() {
+ return null;
+ }
+
+ @Override
+ public long getContentLength() {
+ return 0;
+ }
+
+ @Override
+ public long getBytesReceived() {
+ return 0;
+ }
+
+ @Override
+ public Exception getException() {
+ return new Exception();
+ }
+
+ }
+
+ private static class TestUpload extends Upload {
+
+ @Override
+ public StreamVariable getStreamVariable() {
+ return super.getStreamVariable();
+ }
+
+ @Override
+ public UploadState getState() {
+ return super.getState();
+ }
+
+ @Override
+ protected void fireNoInputStream(String filename, String MIMEType,
+ long length) {
+ fireEvent();
+ }
+
+ @Override
+ protected void fireNoOutputStream(String filename, String MIMEType,
+ long length) {
+ fireEvent();
+ }
+
+ @Override
+ protected void fireUploadInterrupted(String filename, String MIMEType,
+ long length, Exception e) {
+ fireEvent();
+ }
+
+ private void fireEvent() {
+ throw new NullPointerException();
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/window/AddRemoveSubWindowTest.java b/server/src/test/java/com/vaadin/tests/server/component/window/AddRemoveSubWindowTest.java
new file mode 100644
index 0000000000..7fa8665c01
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/window/AddRemoveSubWindowTest.java
@@ -0,0 +1,82 @@
+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.server.LegacyApplication;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.tests.util.AlwaysLockedVaadinSession;
+import com.vaadin.ui.LegacyWindow;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.Window;
+
+public class AddRemoveSubWindowTest {
+
+ public class TestApp extends LegacyApplication {
+
+ @Override
+ public void init() {
+ LegacyWindow w = new LegacyWindow("Main window");
+ setMainWindow(w);
+ }
+ }
+
+ @Test
+ public void addSubWindow() {
+ VaadinSession.setCurrent(new AlwaysLockedVaadinSession(null));
+ 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/src/test/java/com/vaadin/tests/server/component/window/AttachDetachWindowTest.java b/server/src/test/java/com/vaadin/tests/server/component/window/AttachDetachWindowTest.java
new file mode 100644
index 0000000000..9f7a54df9c
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/window/AttachDetachWindowTest.java
@@ -0,0 +1,314 @@
+package com.vaadin.tests.server.component.window;
+
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.server.ClientConnector;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.tests.util.AlwaysLockedVaadinSession;
+import com.vaadin.ui.HasComponents.ComponentAttachEvent;
+import com.vaadin.ui.HasComponents.ComponentAttachListener;
+import com.vaadin.ui.HasComponents.ComponentDetachEvent;
+import com.vaadin.ui.HasComponents.ComponentDetachListener;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+
+public class AttachDetachWindowTest {
+
+ private VaadinSession testApp = new AlwaysLockedVaadinSession(null);
+
+ private interface TestContainer {
+ public boolean attachCalled();
+
+ public boolean detachCalled();
+
+ public TestContent getTestContent();
+
+ public VaadinSession getSession();
+ }
+
+ 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;
+ }
+
+ @Override
+ public VaadinSession getSession() {
+ return super.getSession();
+ }
+ }
+
+ 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(VaadinRequest 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.setSession(testApp);
+ assertAttached(main);
+ assertAttached(sub);
+ }
+
+ @Test
+ public void addSubWindowAfterAttachingMainWindow() {
+ assertUnattached(main);
+ assertUnattached(sub);
+
+ main.setSession(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.setSession(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.setSession(null);
+ assertDetached(main);
+ assertDetached(sub);
+ }
+
+ @Test
+ public void removeSubWindowAfterDetachingMainWindow() {
+ main.setSession(testApp);
+ main.addWindow(sub);
+
+ // main detach should recurse to sub
+ main.setSession(null);
+ assertDetached(main);
+ assertDetached(sub);
+
+ main.removeWindow(sub);
+ assertDetached(main);
+ assertDetached(sub);
+ }
+
+ @Test
+ public void addWindow_attachEventIsFired() {
+ TestUI ui = new TestUI();
+ final Window window = new Window();
+
+ final boolean[] eventFired = new boolean[1];
+ ui.addComponentAttachListener(new ComponentAttachListener() {
+
+ @Override
+ public void componentAttachedToContainer(ComponentAttachEvent event) {
+ eventFired[0] = event.getAttachedComponent().equals(window);
+ }
+ });
+ ui.addWindow(window);
+ Assert.assertTrue("Attach event is not fired for added window",
+ eventFired[0]);
+ }
+
+ @Test
+ public void removeWindow_detachEventIsFired() {
+ TestUI ui = new TestUI();
+ final Window window = new Window();
+
+ final boolean[] eventFired = new boolean[1];
+ ui.addComponentDetachListener(new ComponentDetachListener() {
+
+ @Override
+ public void componentDetachedFromContainer(
+ ComponentDetachEvent event) {
+ eventFired[0] = event.getDetachedComponent().equals(window);
+ }
+ });
+ ui.addWindow(window);
+ ui.removeWindow(window);
+
+ Assert.assertTrue("Detach event is not fired for removed window",
+ eventFired[0]);
+ }
+
+ /**
+ * 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.getSession(), testApp);
+ assertSame("window content not attached", testContent.getUI()
+ .getSession(), testApp);
+ assertSame("window children not attached", testContent.child.getUI()
+ .getSession(), testApp);
+ }
+
+ /**
+ * Asserts that win and its children are not attached.
+ */
+ private void assertUnattached(TestContainer win) {
+ assertSame("window not detached", win.getSession(), null);
+ assertSame("window content not detached",
+ getSession(win.getTestContent()), null);
+ assertSame("window children not detached",
+ getSession(win.getTestContent().child), null);
+ }
+
+ private VaadinSession getSession(ClientConnector testContainer) {
+ UI ui = testContainer.getUI();
+ if (ui != null) {
+ return ui.getSession();
+ } else {
+ return 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/src/test/java/com/vaadin/tests/server/component/window/WindowAttachTest.java b/server/src/test/java/com/vaadin/tests/server/component/window/WindowAttachTest.java
new file mode 100644
index 0000000000..867342ab03
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/window/WindowAttachTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2000-2014 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.window;
+
+import org.junit.Test;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+
+public class WindowAttachTest {
+
+ private static class MyUI extends UI {
+ @Override
+ protected void init(VaadinRequest request) {
+ }
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testAttachUsingSetContent() {
+ UI ui = new MyUI();
+ ui.setContent(new Window("foo"));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testAddToLayout() {
+ VerticalLayout vl = new VerticalLayout();
+ vl.addComponent(new Window("foo"));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/window/WindowDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/window/WindowDeclarativeTest.java
new file mode 100644
index 0000000000..e1c14e9757
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/window/WindowDeclarativeTest.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2000-2014 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.window;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.event.ShortcutAction.KeyCode;
+import com.vaadin.event.ShortcutAction.ModifierKey;
+import com.vaadin.shared.ui.window.WindowMode;
+import com.vaadin.shared.ui.window.WindowRole;
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Window;
+import com.vaadin.ui.declarative.DesignException;
+
+/**
+ * Tests declarative support for implementations of {@link Window}.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class WindowDeclarativeTest extends DeclarativeTestBase<Window> {
+
+ @Test
+ public void testDefault() {
+ String design = "<vaadin-window>";
+
+ Window expected = new Window();
+
+ testRead(design, expected);
+ testWrite(design, expected);
+ }
+
+ @Test
+ public void testFeatures() {
+
+ String design = "<vaadin-window position='100,100' window-mode='maximized' "
+ + "center modal resizable=false resize-lazy closable=false draggable=false "
+ + "close-shortcut='ctrl-alt-escape' "
+ + "assistive-prefix='Hello' assistive-postfix='World' assistive-role='alertdialog' "
+ + "tab-stop-enabled "
+ + "tab-stop-top-assistive-text='Do not move above the window' "
+ + "tab-stop-bottom-assistive-text='End of window'>"
+ + "</vaadin-window>";
+
+ Window expected = new Window();
+
+ expected.setPositionX(100);
+ expected.setPositionY(100);
+ expected.setWindowMode(WindowMode.MAXIMIZED);
+
+ expected.center();
+ expected.setModal(!expected.isModal());
+ expected.setResizable(!expected.isResizable());
+ expected.setResizeLazy(!expected.isResizeLazy());
+ expected.setClosable(!expected.isClosable());
+ expected.setDraggable(!expected.isDraggable());
+
+ expected.removeAllCloseShortcuts();
+ expected.addCloseShortcut(KeyCode.ESCAPE, ModifierKey.ALT,
+ ModifierKey.CTRL);
+
+ expected.setAssistivePrefix("Hello");
+ expected.setAssistivePostfix("World");
+ expected.setAssistiveRole(WindowRole.ALERTDIALOG);
+ expected.setTabStopEnabled(!expected.isTabStopEnabled());
+ expected.setTabStopTopAssistiveText("Do not move above the window");
+ expected.setTabStopBottomAssistiveText("End of window");
+
+ testRead(design, expected);
+ testWrite(design, expected);
+ }
+
+ @Test
+ public void testMultiCloseShortcuts() {
+
+ Window expected = new Window();
+
+ // Add two shortcuts - should now contain three (default escape + two
+ // added)
+ expected.addCloseShortcut(KeyCode.SPACEBAR);
+ expected.addCloseShortcut(KeyCode.ARROW_LEFT, ModifierKey.ALT,
+ ModifierKey.CTRL);
+
+ // Try to add the same shortcut again, should be no-op
+ expected.addCloseShortcut(KeyCode.ARROW_LEFT, ModifierKey.CTRL,
+ ModifierKey.ALT);
+
+ // Add a third shortcut, should total four (default escape + three
+ // added)
+ expected.addCloseShortcut(KeyCode.ARROW_RIGHT, ModifierKey.CTRL);
+
+ // Test validity
+ String design = "<vaadin-window close-shortcut='escape spacebar ctrl-alt-left ctrl-right' />";
+ testRead(design, expected);
+ testWrite(design, expected);
+
+ // Try removing the spacebar shortcut
+ expected.removeCloseShortcut(KeyCode.SPACEBAR);
+
+ // Test again
+ design = "<vaadin-window close-shortcut='escape ctrl-alt-left ctrl-right' />";
+ testRead(design, expected);
+ testWrite(design, expected);
+
+ }
+
+ @Test
+ public void testInvalidPosition() {
+ assertInvalidPosition("");
+ assertInvalidPosition("1");
+ assertInvalidPosition("100,100.1");
+ assertInvalidPosition("x");
+ assertInvalidPosition("2,foo");
+ // Should be invalid, not checked currently
+ // assertInvalidPosition("1,2,3");
+ }
+
+ protected void assertInvalidPosition(String position) {
+ try {
+ read("<vaadin-window position='" + position + "'>");
+ Assert.fail("Invalid position '" + position + "' should throw");
+ } catch (Exception e) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testChildContent() {
+
+ String design = "<vaadin-window>" + createElement(new Button("OK"))
+ + "</vaadin-window>";
+
+ Window expected = new Window();
+ expected.setContent(new Button("OK"));
+
+ testRead(design, expected);
+ testWrite(design, expected);
+ }
+
+ @Test(expected = DesignException.class)
+ public void testMultipleContentChildren() {
+
+ String design = "<vaadin-window>" + createElement(new Label("Hello"))
+ + createElement(new Button("OK")) + "</vaadin-window>";
+
+ read(design);
+ }
+
+ @Test
+ public void testAssistiveDescription() {
+
+ Label assistive1 = new Label("Assistive text");
+ Label assistive2 = new Label("More assistive text");
+
+ String design = "<vaadin-window>"
+ + createElement(assistive1)
+ .attr(":assistive-description", true)
+ + createElement(new Button("OK"))
+ + createElement(assistive2)
+ .attr(":assistive-description", true);
+
+ Window expected = new Window();
+ expected.setContent(new Button("OK"));
+ expected.setAssistiveDescription(assistive1, assistive2);
+
+ testRead(design, expected);
+
+ String written = "<vaadin-window>"
+ + createElement(new Button("OK"))
+ + createElement(assistive1)
+ .attr(":assistive-description", true)
+ + createElement(assistive2)
+ .attr(":assistive-description", true);
+
+ testWrite(written, expected);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/window/WindowListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/window/WindowListenersTest.java
new file mode 100644
index 0000000000..87a1af301c
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/window/WindowListenersTest.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.AbstractListenerMethodsTestBase;
+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 WindowListenersTest extends AbstractListenerMethodsTestBase {
+ 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/src/test/java/com/vaadin/tests/server/component/window/WindowTest.java b/server/src/test/java/com/vaadin/tests/server/component/window/WindowTest.java
new file mode 100644
index 0000000000..e9e73c1e0f
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/window/WindowTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2014 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.window;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Window;
+
+public class WindowTest {
+
+ public Window window;
+
+ @Before
+ public void setup() {
+ window = new Window();
+ }
+
+ @Test
+ public void testAssistiveDescription() {
+ Label l1 = new Label("label 1");
+ Button b2 = new Button("button 2");
+ window.setAssistiveDescription(l1, b2);
+
+ Assert.assertEquals(2, window.getAssistiveDescription().length);
+ Assert.assertEquals(l1, window.getAssistiveDescription()[0]);
+ Assert.assertEquals(b2, window.getAssistiveDescription()[1]);
+
+ // Modifying return value must not change actual value
+ window.getAssistiveDescription()[0] = null;
+
+ Assert.assertEquals(2, window.getAssistiveDescription().length);
+ Assert.assertEquals(l1, window.getAssistiveDescription()[0]);
+ Assert.assertEquals(b2, window.getAssistiveDescription()[1]);
+
+ }
+
+ @Test
+ public void testSetPosition() {
+ window.setPosition(100, 200);
+ Assert.assertEquals(100, window.getPositionX());
+ Assert.assertEquals(200, window.getPositionY());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/componentcontainer/AbstractIndexedLayoutTestBase.java b/server/src/test/java/com/vaadin/tests/server/componentcontainer/AbstractIndexedLayoutTestBase.java
new file mode 100644
index 0000000000..f19821f92e
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/componentcontainer/AbstractIndexedLayoutTestBase.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 AbstractIndexedLayoutTestBase 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/src/test/java/com/vaadin/tests/server/componentcontainer/AddRemoveComponentTest.java b/server/src/test/java/com/vaadin/tests/server/componentcontainer/AddRemoveComponentTest.java
new file mode 100644
index 0000000000..91a302a274
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/componentcontainer/AddRemoveComponentTest.java
@@ -0,0 +1,42 @@
+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;
+import com.vaadin.ui.components.colorpicker.ColorPickerPreview;
+
+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);
+ containerClasses.remove(ColorPickerPreview.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/src/test/java/com/vaadin/tests/server/componentcontainer/CssLayoutTest.java b/server/src/test/java/com/vaadin/tests/server/componentcontainer/CssLayoutTest.java
new file mode 100644
index 0000000000..8dd36beda3
--- /dev/null
+++ b/server/src/test/java/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 AbstractIndexedLayoutTestBase {
+
+ @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/src/test/java/com/vaadin/tests/server/componentcontainer/FormLayoutTest.java b/server/src/test/java/com/vaadin/tests/server/componentcontainer/FormLayoutTest.java
new file mode 100644
index 0000000000..f55798007f
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/componentcontainer/FormLayoutTest.java
@@ -0,0 +1,105 @@
+package com.vaadin.tests.server.componentcontainer;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.shared.ui.orderedlayout.FormLayoutState;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.FormLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Layout;
+
+public class FormLayoutTest extends AbstractIndexedLayoutTestBase {
+
+ @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();
+ }
+
+ Component[] children = new Component[] { new Label("A"), new Label("B"),
+ new Label("C"), new Label("D") };
+
+ @Test
+ public void testConstructorWithComponents() {
+ FormLayout l = new FormLayout(children);
+ assertOrder(l, new int[] { 0, 1, 2, 3 });
+ }
+
+ @Test
+ public void testAddComponents() {
+ FormLayout l = new FormLayout();
+ l.addComponents(children);
+ assertOrder(l, new int[] { 0, 1, 2, 3 });
+ }
+
+ @Test
+ public void getState_formLayoutHasCustomState() {
+ TestFormLayout layout = new TestFormLayout();
+ FormLayoutState state = layout.getState();
+ Assert.assertEquals("Unexpected state class", FormLayoutState.class,
+ state.getClass());
+ }
+
+ @Test
+ public void getPrimaryStyleName_formLayoutHasCustomPrimaryStyleName() {
+ FormLayout layout = new FormLayout();
+ FormLayoutState state = new FormLayoutState();
+ Assert.assertEquals("Unexpected primary style name",
+ state.primaryStyleName, layout.getPrimaryStyleName());
+ }
+
+ @Test
+ public void formLayoutStateHasCustomPrimaryStyleName() {
+ FormLayoutState state = new FormLayoutState();
+ Assert.assertEquals("Unexpected primary style name", "v-formlayout",
+ state.primaryStyleName);
+ }
+
+ private void assertOrder(Layout layout, int[] indices) {
+ Iterator<?> i = layout.iterator();
+ try {
+ for (int index : indices) {
+ if (index != -1) {
+ assertSame(children[index], i.next());
+ } else {
+ i.next();
+ }
+ }
+ assertFalse("Too many components in layout", i.hasNext());
+ } catch (NoSuchElementException e) {
+ fail("Too few components in layout");
+ }
+ }
+
+ private static class TestFormLayout extends FormLayout {
+
+ @Override
+ public FormLayoutState getState() {
+ return super.getState();
+ }
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/componentcontainer/VerticalLayoutTest.java b/server/src/test/java/com/vaadin/tests/server/componentcontainer/VerticalLayoutTest.java
new file mode 100644
index 0000000000..565cc8e8ab
--- /dev/null
+++ b/server/src/test/java/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 AbstractIndexedLayoutTestBase {
+
+ @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/src/test/java/com/vaadin/tests/server/components/AbstractFieldValueChangeTestBase.java b/server/src/test/java/com/vaadin/tests/server/components/AbstractFieldValueChangeTestBase.java
new file mode 100644
index 0000000000..637947fc9b
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/components/AbstractFieldValueChangeTestBase.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 AbstractFieldValueChangeTestBase<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((T) "newValue");
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/components/ComboBoxValueChangeTest.java b/server/src/test/java/com/vaadin/tests/server/components/ComboBoxValueChangeTest.java
new file mode 100644
index 0000000000..f3cc337657
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/components/ComboBoxValueChangeTest.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 ComboBoxValueChangeTest extends
+ AbstractFieldValueChangeTestBase<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/src/test/java/com/vaadin/tests/server/components/ComponentAttachDetachListenerTest.java b/server/src/test/java/com/vaadin/tests/server/components/ComponentAttachDetachListenerTest.java
new file mode 100644
index 0000000000..d8b366ffbc
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/components/ComponentAttachDetachListenerTest.java
@@ -0,0 +1,395 @@
+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.CssLayout;
+import com.vaadin.ui.CustomLayout;
+import com.vaadin.ui.GridLayout;
+import com.vaadin.ui.GridLayout.Area;
+import com.vaadin.ui.HasComponents;
+import com.vaadin.ui.HasComponents.ComponentAttachEvent;
+import com.vaadin.ui.HasComponents.ComponentAttachListener;
+import com.vaadin.ui.HasComponents.ComponentDetachEvent;
+import com.vaadin.ui.HasComponents.ComponentDetachListener;
+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;
+ private CustomLayout customlayout;
+
+ // General variables
+ private int attachCounter = 0;
+ private Component attachedComponent = null;
+ private HasComponents attachTarget = null;
+ private boolean foundInContainer = false;
+
+ private int detachCounter = 0;
+ private Component detachedComponent = null;
+ private HasComponents 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.iterator();
+ 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.iterator();
+ 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.addComponentAttachListener(new MyAttachListener());
+ olayout.addComponentDetachListener(new MyDetachListener());
+
+ gridlayout = new GridLayout();
+ gridlayout.addComponentAttachListener(new MyAttachListener());
+ gridlayout.addComponentDetachListener(new MyDetachListener());
+
+ absolutelayout = new AbsoluteLayout();
+ absolutelayout.addComponentAttachListener(new MyAttachListener());
+ absolutelayout.addComponentDetachListener(new MyDetachListener());
+
+ csslayout = new CssLayout();
+ csslayout.addComponentAttachListener(new MyAttachListener());
+ csslayout.addComponentDetachListener(new MyDetachListener());
+
+ customlayout = new CustomLayout("<div location='loc'/>");
+ customlayout.addComponentAttachListener(new MyAttachListener());
+ customlayout.addComponentDetachListener(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);
+ }
+
+ public void testCustomLayoutAttachListener() {
+ // Reset state variables
+ resetVariables();
+
+ // Add component -> Should trigger attach listener
+ Component comp = new Label();
+ customlayout.addComponent(comp, "loc");
+
+ assertEquals("Attach counter should get incremented", 1, attachCounter);
+
+ assertSame("The attached component should be the label", comp,
+ attachedComponent);
+
+ assertSame("The attached target should be the layout", customlayout,
+ attachTarget);
+
+ assertTrue("The attached component should be found in the container",
+ foundInContainer);
+ }
+
+ public void testCustomLayoutDetachListener() {
+ // Add a component to detach
+ Component comp = new Label();
+ customlayout.addComponent(comp);
+
+ // Reset state variables (since they are set by the attach listener)
+ resetVariables();
+
+ // Detach the component -> triggers the detach listener
+ customlayout.removeComponent(comp);
+
+ assertEquals("Detach counter should get incremented", 1, detachCounter);
+
+ assertSame("The detached component should be the label", comp,
+ detachedComponent);
+
+ assertSame("The detached target should be the layout", customlayout,
+ detachedTarget);
+
+ assertFalse(
+ "The detached component should not be found in the container",
+ foundInContainer);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/components/GridLayoutLastRowRemovalTest.java b/server/src/test/java/com/vaadin/tests/server/components/GridLayoutLastRowRemovalTest.java
new file mode 100644
index 0000000000..3467d1d80c
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/components/GridLayoutLastRowRemovalTest.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 GridLayoutLastRowRemovalTest 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/src/test/java/com/vaadin/tests/server/components/TextFieldValueChangeTest.java b/server/src/test/java/com/vaadin/tests/server/components/TextFieldValueChangeTest.java
new file mode 100644
index 0000000000..cfceb6f7d7
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/components/TextFieldValueChangeTest.java
@@ -0,0 +1,125 @@
+package com.vaadin.tests.server.components;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.easymock.EasyMock;
+import org.junit.Assert;
+
+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 TextFieldValueChangeTest extends
+ AbstractFieldValueChangeTestBase<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/src/test/java/com/vaadin/tests/server/components/WindowTest.java b/server/src/test/java/com/vaadin/tests/server/components/WindowTest.java
new file mode 100644
index 0000000000..26fe238342
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/components/WindowTest.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.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 WindowTest 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/src/test/java/com/vaadin/tests/server/navigator/ClassBasedViewProviderTest.java b/server/src/test/java/com/vaadin/tests/server/navigator/ClassBasedViewProviderTest.java
new file mode 100644
index 0000000000..bc067ddb88
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/navigator/ClassBasedViewProviderTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2000-2014 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.navigator.ViewChangeListener.ViewChangeEvent;
+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 enter(ViewChangeEvent event) {
+ parameters = event.getParameters();
+ }
+
+ }
+
+ 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/src/test/java/com/vaadin/tests/server/navigator/NavigatorTest.java b/server/src/test/java/com/vaadin/tests/server/navigator/NavigatorTest.java
new file mode 100644
index 0000000000..0de804fa0b
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/navigator/NavigatorTest.java
@@ -0,0 +1,824 @@
+/*
+ * Copyright 2000-2014 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.IArgumentMatcher;
+import org.easymock.IMocksControl;
+import org.junit.Assert;
+
+import com.vaadin.navigator.NavigationStateManager;
+import com.vaadin.navigator.Navigator;
+import com.vaadin.navigator.Navigator.UriFragmentManager;
+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.server.Page;
+import com.vaadin.server.Page.UriFragmentChangedEvent;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.server.navigator.ClassBasedViewProviderTest.TestView;
+import com.vaadin.tests.server.navigator.ClassBasedViewProviderTest.TestView2;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+
+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 NavigationStateManager {
+ @Override
+ public String getState() {
+ return null;
+ }
+
+ @Override
+ public void setState(String fragment) {
+ // do nothing
+ }
+
+ @Override
+ public void setNavigator(Navigator navigator) {
+ // 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(createMockUI(), new NullFragmentManager(), new TestDisplay());
+ }
+
+ public TestNavigator(UI ui) {
+ super(ui, EasyMock.createMock(ViewDisplay.class));
+ }
+
+ public View getView(String viewAndParameters) {
+ try {
+ navigateTo(viewAndParameters);
+ } catch (IllegalArgumentException e) {
+ // ignore
+ }
+ return ((TestDisplay) getDisplay()).getCurrentView();
+ }
+
+ @Override
+ protected NavigationStateManager getStateManager() {
+ return super.getStateManager();
+ }
+ }
+
+ 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.getParameters(), event.getParameters())) {
+ 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 beforeViewChange(ViewChangeEvent event) {
+ if (referenceEvents.isEmpty()) {
+ fail("Unexpected call to beforeViewChange()");
+ }
+ ViewChangeEvent reference = referenceEvents.remove();
+ Boolean isCheck = referenceIsCheck.remove();
+ if (!isCheck) {
+ fail("Expected afterViewChange(), received beforeViewChange()");
+ }
+ // 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 afterViewChange(ViewChangeEvent event) {
+ if (referenceEvents.isEmpty()) {
+ fail("Unexpected call to afterViewChange()");
+ }
+ ViewChangeEvent reference = referenceEvents.remove();
+ Boolean isCheck = referenceIsCheck.remove();
+ if (isCheck) {
+ fail("Expected beforeViewChange(), received afterViewChange()");
+ }
+ if (!equalsReferenceEvent(event, reference)) {
+ fail("View change event does not match reference event");
+ }
+ }
+ }
+
+ private static class TestUI extends UI {
+
+ TestUI(Page page) {
+ this.page = page;
+ }
+
+ @Override
+ protected void init(VaadinRequest request) {
+ }
+
+ @Override
+ public Page getPage() {
+ return page;
+ }
+
+ private Page page;
+ }
+
+ private static class TestPage extends Page {
+
+ public TestPage() {
+ super(null, null);
+ }
+
+ @Override
+ public void addUriFragmentChangedListener(
+ UriFragmentChangedListener listener) {
+ addUriFragmentCalled = true;
+ }
+
+ @Override
+ public void removeUriFragmentChangedListener(
+ UriFragmentChangedListener listener) {
+ removeUriFragmentCalled = true;
+ }
+
+ boolean addUriFragmentCalled() {
+ return addUriFragmentCalled;
+ }
+
+ boolean removeUriFragmentCalled() {
+ return removeUriFragmentCalled;
+ }
+
+ private boolean addUriFragmentCalled;
+
+ private boolean removeUriFragmentCalled;
+ }
+
+ public static ViewChangeEvent eventParametersEqual(final String expected) {
+ EasyMock.reportMatcher(new IArgumentMatcher() {
+ @Override
+ public void appendTo(StringBuffer buffer) {
+ buffer.append("paramsIs(\"" + expected + "\")");
+ }
+
+ @Override
+ public boolean matches(Object actual) {
+ return actual instanceof ViewChangeEvent
+ && expected.equals(((ViewChangeEvent) actual)
+ .getParameters());
+ }
+ });
+ return null;
+ }
+
+ private static UI createMockUI() {
+ UI ui = EasyMock.createMock(UI.class);
+ ui.setNavigator(EasyMock.anyObject(Navigator.class));
+ EasyMock.replay(ui);
+ return ui;
+ }
+
+ private static Navigator createNavigator(NavigationStateManager manager,
+ ViewDisplay display) {
+ return new Navigator(createMockUI(), manager, display);
+ }
+
+ public void testDestroy_unsetNavigatorInUIAndUriFragmentManager() {
+ TestPage page = new TestPage();
+ UI ui = new TestUI(page);
+
+ TestNavigator navigator = new TestNavigator(ui);
+ Assert.assertTrue("Add URI fragment Page method has not been called",
+ page.addUriFragmentCalled());
+ Assert.assertFalse("Unexpected remove URI fragment Page method call",
+ page.removeUriFragmentCalled());
+ Assert.assertNotNull("Navigator is null in UI", ui.getNavigator());
+
+ navigator.destroy();
+ Assert.assertTrue(
+ "Remove URI fragment Page method has not been called after destroy",
+ page.removeUriFragmentCalled());
+ Assert.assertNull("Navigator is not null in UI after destroy",
+ ui.getNavigator());
+ UriFragmentManager manager = (UriFragmentManager) navigator
+ .getStateManager();
+ try {
+ manager.uriFragmentChanged(EasyMock
+ .createMock(UriFragmentChangedEvent.class));
+ Assert.assertTrue(
+ "Expected null pointer exception after call uriFragmentChanged "
+ + "for destroyed navigator", false);
+ } catch (NullPointerException e) {
+ }
+ }
+
+ public void testBasicNavigation() {
+ IMocksControl control = EasyMock.createControl();
+ NavigationStateManager manager = control
+ .createMock(NavigationStateManager.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
+ manager.setNavigator(EasyMock.anyObject(Navigator.class));
+
+ EasyMock.expect(provider.getViewName("test1")).andReturn("test1");
+ EasyMock.expect(provider.getView("test1")).andReturn(view1);
+ EasyMock.expect(manager.getState()).andReturn("");
+ view1.enter(eventParametersEqual(""));
+ display.showView(view1);
+ manager.setState("test1");
+ EasyMock.expect(manager.getState()).andReturn("test1");
+
+ EasyMock.expect(provider.getViewName("test2/")).andReturn("test2");
+ EasyMock.expect(provider.getView("test2")).andReturn(view2);
+ EasyMock.expect(manager.getState()).andReturn("test1");
+ view2.enter(eventParametersEqual(""));
+ display.showView(view2);
+ manager.setState("test2");
+ EasyMock.expect(manager.getState()).andReturn("test2");
+
+ EasyMock.expect(provider.getViewName("test1/params"))
+ .andReturn("test1");
+ EasyMock.expect(provider.getView("test1")).andReturn(view1);
+ EasyMock.expect(manager.getState()).andReturn("test2");
+ view1.enter(eventParametersEqual("params"));
+ display.showView(view1);
+ manager.setState("test1/params");
+ EasyMock.expect(manager.getState()).andReturn("test1/params");
+
+ control.replay();
+
+ // create and test navigator
+ Navigator navigator = createNavigator(manager, display);
+ navigator.addProvider(provider);
+
+ navigator.navigateTo("test1");
+ assertEquals("test1", navigator.getState());
+
+ navigator.navigateTo("test2/");
+ assertEquals("test2", navigator.getState());
+
+ navigator.navigateTo("test1/params");
+ assertEquals("test1/params", navigator.getState());
+ }
+
+ public void testMainView() {
+ IMocksControl control = EasyMock.createControl();
+ NavigationStateManager manager = control
+ .createMock(NavigationStateManager.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
+ manager.setNavigator(EasyMock.anyObject(Navigator.class));
+
+ EasyMock.expect(provider.getViewName("test2")).andReturn("test2");
+ EasyMock.expect(provider.getView("test2")).andReturn(view2);
+ EasyMock.expect(manager.getState()).andReturn("view1");
+ view2.enter(eventParametersEqual(""));
+ display.showView(view2);
+ manager.setState("test2");
+
+ EasyMock.expect(provider.getViewName("")).andReturn("test1");
+ EasyMock.expect(provider.getView("test1")).andReturn(view1);
+ EasyMock.expect(manager.getState()).andReturn("");
+ view1.enter(eventParametersEqual(""));
+ display.showView(view1);
+ manager.setState("test1");
+
+ EasyMock.expect(provider.getViewName("test1/params"))
+ .andReturn("test1");
+ EasyMock.expect(provider.getView("test1")).andReturn(view1);
+ EasyMock.expect(manager.getState()).andReturn("test2");
+ view1.enter(eventParametersEqual("params"));
+ display.showView(view1);
+ manager.setState("test1/params");
+
+ control.replay();
+
+ // create and test navigator
+ Navigator navigator = createNavigator(manager, display);
+ navigator.addProvider(provider);
+
+ navigator.navigateTo("test2");
+ navigator.navigateTo("");
+ navigator.navigateTo("test1/params");
+ }
+
+ public void testListeners() {
+ IMocksControl control = EasyMock.createControl();
+ NavigationStateManager manager = control
+ .createMock(NavigationStateManager.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 = createNavigator(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.getState()).andReturn("");
+ view1.enter(eventParametersEqual(""));
+ display.showView(view1);
+ manager.setState("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.getState()).andReturn("test1");
+ view2.enter(eventParametersEqual(""));
+ display.showView(view2);
+ manager.setState("test2");
+ listener.addExpectedNavigatorViewChange(event2);
+
+ control.replay();
+
+ // test navigator
+ navigator.addProvider(provider);
+ navigator.addViewChangeListener(listener);
+
+ navigator.navigateTo("test1");
+ navigator.navigateTo("test2");
+
+ if (!listener.isReady()) {
+ fail("Missing listener calls");
+ }
+ }
+
+ public void testComponentContainerViewDisplay() {
+ abstract class TestView implements Component, View {
+ }
+
+ TestView tv1 = EasyMock.createNiceMock(TestView.class);
+ TestView tv2 = EasyMock.createNiceMock(TestView.class);
+ EasyMock.replay(tv1, tv2);
+
+ VerticalLayout container = new VerticalLayout();
+ ViewDisplay display = new Navigator.ComponentContainerViewDisplay(
+ container);
+ Navigator navigator = createNavigator(new NullFragmentManager(),
+ display);
+
+ navigator.addView("tv1", tv1);
+ navigator.addView("tv2", tv2);
+
+ navigator.navigateTo("tv1");
+
+ assertSame(tv1, container.getComponent(0));
+ assertEquals(1, container.getComponentCount());
+
+ navigator.navigateTo("tv2");
+
+ assertSame(tv2, container.getComponent(0));
+ assertEquals(1, container.getComponentCount());
+ }
+
+ public void testBlockNavigation() {
+ IMocksControl control = EasyMock.createControl();
+ NavigationStateManager manager = control
+ .createMock(NavigationStateManager.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 = createNavigator(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.getState()).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.getState()).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.getState()).andReturn("");
+ ViewChangeEvent event3 = new ViewChangeEvent(navigator, null, view1,
+ "test1", "bar");
+ listener1.addExpectedIsViewChangeAllowed(event3, true);
+ listener2.addExpectedIsViewChangeAllowed(event3, true);
+ view1.enter(EasyMock.isA(ViewChangeEvent.class));
+ display.showView(view1);
+ manager.setState("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.getState()).andReturn("view1");
+ ViewChangeEvent event4 = new ViewChangeEvent(navigator, view1, view2,
+ "test2", "");
+ listener1.addExpectedIsViewChangeAllowed(event4, true);
+ listener2.addExpectedIsViewChangeAllowed(event4, true);
+ view2.enter(EasyMock.isA(ViewChangeEvent.class));
+ display.showView(view2);
+ manager.setState("test2");
+ listener1.addExpectedNavigatorViewChange(event4);
+ listener2.addExpectedNavigatorViewChange(event4);
+
+ control.replay();
+
+ // test navigator
+ navigator.addProvider(provider);
+ navigator.addViewChangeListener(listener1);
+ navigator.addViewChangeListener(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 TestNavigator();
+
+ 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 TestNavigator();
+
+ try {
+ navigator.addView("test", (View) null);
+ fail("addView() accepted null view instance");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ public void testAddViewWithNullClass() throws Exception {
+ Navigator navigator = new TestNavigator();
+
+ 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());
+ }
+
+ public void testNavigateToUnknownView() {
+ TestNavigator navigator = new TestNavigator();
+
+ View errorView = EasyMock.createMock(View.class);
+ errorView.enter(EasyMock.anyObject(ViewChangeEvent.class));
+ EasyMock.replay(errorView);
+
+ try {
+ navigator.navigateTo("doesnotexist");
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException iae) {
+ }
+
+ navigator.setErrorView(errorView);
+ navigator.navigateTo("doesnotexist");
+
+ View testView = EasyMock.createMock(View.class);
+ testView.enter(EasyMock.anyObject(ViewChangeEvent.class));
+ EasyMock.replay(testView);
+
+ navigator.addView("doesnotexist", testView);
+ navigator.navigateTo("doesnotexist");
+
+ View errorView2 = EasyMock.createMock(View.class);
+ errorView2.enter(EasyMock.anyObject(ViewChangeEvent.class));
+ EasyMock.replay(errorView2);
+
+ ViewProvider errorProvider = EasyMock.createMock(ViewProvider.class);
+ EasyMock.expect(errorProvider.getView("doesnotexist2")).andReturn(
+ errorView2);
+ EasyMock.expect(errorProvider.getViewName("doesnotexist2")).andReturn(
+ "doesnotexist2");
+ EasyMock.replay(errorProvider);
+
+ navigator.setErrorProvider(errorProvider);
+ navigator.navigateTo("doesnotexist2");
+ }
+
+ public void testShowViewEnterOrder() {
+ IMocksControl control = EasyMock.createStrictControl();
+
+ View view = control.createMock(View.class);
+ ViewDisplay display = control.createMock(ViewDisplay.class);
+
+ display.showView(view);
+ view.enter(EasyMock.anyObject(ViewChangeEvent.class));
+
+ control.replay();
+
+ NavigationStateManager manager = EasyMock
+ .createNiceMock(NavigationStateManager.class);
+ EasyMock.replay(manager);
+
+ Navigator navigator = new Navigator(createMockUI(), manager, display);
+ navigator.addView("view", view);
+ navigator.navigateTo("view");
+ }
+
+ public void testNullViewProvider() {
+ IMocksControl control = EasyMock.createControl();
+ NavigationStateManager manager = control
+ .createMock(NavigationStateManager.class);
+ ViewDisplay display = control.createMock(ViewDisplay.class);
+
+ // create navigator to test
+ Navigator navigator = createNavigator(manager, display);
+
+ try {
+ navigator.addProvider(null);
+ fail("Should not be allowed to add a null view provider");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/navigator/UriFragmentManagerTest.java b/server/src/test/java/com/vaadin/tests/server/navigator/UriFragmentManagerTest.java
new file mode 100644
index 0000000000..327baae21f
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/navigator/UriFragmentManagerTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2000-2014 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 org.easymock.EasyMock;
+import org.easymock.IMocksControl;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.navigator.Navigator;
+import com.vaadin.navigator.Navigator.UriFragmentManager;
+import com.vaadin.server.Page;
+import com.vaadin.server.Page.UriFragmentChangedEvent;
+
+public class UriFragmentManagerTest {
+
+ @Test
+ public void testGetSetUriFragment() {
+ Page page = EasyMock.createMock(Page.class);
+ UriFragmentManager manager = new UriFragmentManager(page);
+
+ // prepare mock
+ EasyMock.expect(page.getUriFragment()).andReturn("");
+ page.setUriFragment("!test", false);
+ EasyMock.expect(page.getUriFragment()).andReturn("!test");
+ EasyMock.replay(page);
+
+ // test manager using the mock
+ Assert.assertEquals("Incorrect fragment value", "", manager.getState());
+ manager.setState("test");
+ Assert.assertEquals("Incorrect fragment value", "test",
+ manager.getState());
+ }
+
+ @Test
+ 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);
+ manager.setNavigator(navigator);
+
+ EasyMock.expect(page.getUriFragment()).andReturn("!test");
+ navigator.navigateTo("test");
+ control.replay();
+
+ UriFragmentChangedEvent event = new UriFragmentChangedEvent(page,
+ "oldtest");
+ manager.uriFragmentChanged(event);
+ }
+
+ @Test
+ public void setNavigator_someNavigatorInstance_uriFragmentChangedListenerIsRemoved() {
+ TestPage page = new TestPage();
+
+ UriFragmentManager manager = new UriFragmentManager(page);
+ manager.setNavigator(EasyMock.createMock(Navigator.class));
+
+ Assert.assertTrue(
+ "addUriFragmentChangedListener() method is not called for the Page",
+ page.addUriFragmentCalled());
+ Assert.assertFalse(
+ "removeUriFragmentChangedListener() method is called for the Page",
+ page.removeUriFragmentCalled());
+ }
+
+ @Test
+ public void setNavigator_nullNavigatorInstance_uriFragmentChangedListenerIsRemoved() {
+ TestPage page = new TestPage();
+
+ UriFragmentManager manager = new UriFragmentManager(page);
+ manager.setNavigator(EasyMock.createMock(Navigator.class));
+
+ manager.setNavigator(null);
+ Assert.assertTrue(
+ "removeUriFragmentChangedListener() method is not called for the Page",
+ page.removeUriFragmentCalled());
+ }
+
+ private static class TestPage extends Page {
+
+ public TestPage() {
+ super(null, null);
+ }
+
+ @Override
+ public void addUriFragmentChangedListener(
+ UriFragmentChangedListener listener) {
+ addUriFragmentCalled = true;
+ }
+
+ @Override
+ public void removeUriFragmentChangedListener(
+ UriFragmentChangedListener listener) {
+ removeUriFragmentCalled = true;
+ }
+
+ boolean addUriFragmentCalled() {
+ return addUriFragmentCalled;
+ }
+
+ boolean removeUriFragmentCalled() {
+ return removeUriFragmentCalled;
+ }
+
+ private boolean addUriFragmentCalled;
+
+ private boolean removeUriFragmentCalled;
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/renderer/ImageRendererTest.java b/server/src/test/java/com/vaadin/tests/server/renderer/ImageRendererTest.java
new file mode 100644
index 0000000000..782434bcd5
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/renderer/ImageRendererTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2000-2014 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.renderer;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+
+import org.easymock.EasyMock;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.server.ClassResource;
+import com.vaadin.server.ExternalResource;
+import com.vaadin.server.FileResource;
+import com.vaadin.server.FontAwesome;
+import com.vaadin.server.ThemeResource;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.renderers.ImageRenderer;
+
+import elemental.json.JsonObject;
+import elemental.json.JsonValue;
+
+public class ImageRendererTest {
+
+ private ImageRenderer renderer;
+
+ @Before
+ public void setUp() {
+ UI mockUI = EasyMock.createNiceMock(UI.class);
+ EasyMock.replay(mockUI);
+
+ Grid grid = new Grid();
+ grid.setParent(mockUI);
+
+ renderer = new ImageRenderer();
+ renderer.setParent(grid);
+ }
+
+ @Test
+ public void testThemeResource() {
+ JsonValue v = renderer.encode(new ThemeResource("foo.png"));
+ assertEquals("theme://foo.png", getUrl(v));
+ }
+
+ @Test
+ public void testExternalResource() {
+ JsonValue v = renderer.encode(new ExternalResource(
+ "http://example.com/foo.png"));
+ assertEquals("http://example.com/foo.png", getUrl(v));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testFileResource() {
+ renderer.encode(new FileResource(new File("/tmp/foo.png")));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testClassResource() {
+ renderer.encode(new ClassResource("img/foo.png"));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testFontIcon() {
+ renderer.encode(FontAwesome.AMBULANCE);
+ }
+
+ private String getUrl(JsonValue v) {
+ return ((JsonObject) v).get("uRL").asString();
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/renderer/RendererTest.java b/server/src/test/java/com/vaadin/tests/server/renderer/RendererTest.java
new file mode 100644
index 0000000000..cea8df0ba6
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/renderer/RendererTest.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright 2000-2014 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.renderer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+
+import java.util.Date;
+import java.util.Locale;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.Item;
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.data.util.converter.Converter;
+import com.vaadin.data.util.converter.StringToIntegerConverter;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.tests.server.component.grid.TestGrid;
+import com.vaadin.tests.util.AlwaysLockedVaadinSession;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.AbstractRenderer;
+import com.vaadin.ui.Grid.Column;
+import com.vaadin.ui.renderers.ButtonRenderer;
+import com.vaadin.ui.renderers.DateRenderer;
+import com.vaadin.ui.renderers.HtmlRenderer;
+import com.vaadin.ui.renderers.NumberRenderer;
+import com.vaadin.ui.renderers.TextRenderer;
+
+import elemental.json.JsonValue;
+
+public class RendererTest {
+
+ private static class TestBean {
+ int i = 42;
+
+ @Override
+ public String toString() {
+ return "TestBean [" + i + "]";
+ }
+ }
+
+ private static class ExtendedBean extends TestBean {
+ float f = 3.14f;
+ }
+
+ private static class TestRenderer extends TextRenderer {
+ @Override
+ public JsonValue encode(String value) {
+ return super.encode("renderer(" + value + ")");
+ }
+ }
+
+ private static class TestConverter implements Converter<String, TestBean> {
+
+ @Override
+ public TestBean convertToModel(String value,
+ Class<? extends TestBean> targetType, Locale locale)
+ throws ConversionException {
+ return null;
+ }
+
+ @Override
+ public String convertToPresentation(TestBean value,
+ Class<? extends String> targetType, Locale locale)
+ throws ConversionException {
+ if (value instanceof ExtendedBean) {
+ return "ExtendedBean(" + value.i + ", "
+ + ((ExtendedBean) value).f + ")";
+ } else {
+ return "TestBean(" + value.i + ")";
+ }
+ }
+
+ @Override
+ public Class<TestBean> getModelType() {
+ return TestBean.class;
+ }
+
+ @Override
+ public Class<String> getPresentationType() {
+ return String.class;
+ }
+ }
+
+ private Grid grid;
+
+ private Column intColumn;
+ private Column textColumn;
+ private Column beanColumn;
+ private Column htmlColumn;
+ private Column numberColumn;
+ private Column dateColumn;
+ private Column extendedBeanColumn;
+ private Column buttonColumn;
+
+ @Before
+ @SuppressWarnings("unchecked")
+ public void setUp() {
+ VaadinSession.setCurrent(new AlwaysLockedVaadinSession(null));
+
+ IndexedContainer c = new IndexedContainer();
+
+ c.addContainerProperty("int", Integer.class, 0);
+ c.addContainerProperty("text", String.class, "");
+ c.addContainerProperty("html", String.class, "");
+ c.addContainerProperty("number", Number.class, null);
+ c.addContainerProperty("date", Date.class, null);
+ c.addContainerProperty("bean", TestBean.class, null);
+ c.addContainerProperty("button", String.class, null);
+ c.addContainerProperty("extendedBean", ExtendedBean.class, null);
+
+ Object id = c.addItem();
+ Item item = c.getItem(id);
+ item.getItemProperty("int").setValue(123);
+ item.getItemProperty("text").setValue("321");
+ item.getItemProperty("html").setValue("<b>html</b>");
+ item.getItemProperty("number").setValue(3.14);
+ item.getItemProperty("date").setValue(new Date(123456789));
+ item.getItemProperty("bean").setValue(new TestBean());
+ item.getItemProperty("extendedBean").setValue(new ExtendedBean());
+
+ grid = new TestGrid(c);
+
+ intColumn = grid.getColumn("int");
+ textColumn = grid.getColumn("text");
+ htmlColumn = grid.getColumn("html");
+ numberColumn = grid.getColumn("number");
+ dateColumn = grid.getColumn("date");
+ beanColumn = grid.getColumn("bean");
+ extendedBeanColumn = grid.getColumn("extendedBean");
+ buttonColumn = grid.getColumn("button");
+
+ }
+
+ @Test
+ public void testDefaultRendererAndConverter() throws Exception {
+ assertSame(TextRenderer.class, intColumn.getRenderer().getClass());
+ assertSame(StringToIntegerConverter.class, intColumn.getConverter()
+ .getClass());
+
+ assertSame(TextRenderer.class, textColumn.getRenderer().getClass());
+ // String->String; converter not needed
+ assertNull(textColumn.getConverter());
+
+ assertSame(TextRenderer.class, beanColumn.getRenderer().getClass());
+ // MyBean->String; converter not found
+ assertNull(beanColumn.getConverter());
+ }
+
+ @Test
+ public void testFindCompatibleConverter() throws Exception {
+ intColumn.setRenderer(renderer());
+ assertSame(StringToIntegerConverter.class, intColumn.getConverter()
+ .getClass());
+
+ textColumn.setRenderer(renderer());
+ assertNull(textColumn.getConverter());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testCannotFindConverter() {
+ beanColumn.setRenderer(renderer());
+ }
+
+ @Test
+ public void testExplicitConverter() throws Exception {
+ beanColumn.setRenderer(renderer(), converter());
+ extendedBeanColumn.setRenderer(renderer(), converter());
+ }
+
+ @Test
+ public void testEncoding() throws Exception {
+ assertEquals("42", render(intColumn, 42).asString());
+ intColumn.setRenderer(renderer());
+ assertEquals("renderer(42)", render(intColumn, 42).asString());
+
+ assertEquals("2.72", render(textColumn, "2.72").asString());
+ textColumn.setRenderer(new TestRenderer());
+ assertEquals("renderer(2.72)", render(textColumn, "2.72").asString());
+ }
+
+ @Test
+ public void testEncodingWithoutConverter() throws Exception {
+ assertEquals("TestBean [42]", render(beanColumn, new TestBean())
+ .asString());
+ }
+
+ @Test
+ public void testBeanEncoding() throws Exception {
+ beanColumn.setRenderer(renderer(), converter());
+ extendedBeanColumn.setRenderer(renderer(), converter());
+
+ assertEquals("renderer(TestBean(42))",
+ render(beanColumn, new TestBean()).asString());
+ assertEquals("renderer(ExtendedBean(42, 3.14))",
+ render(beanColumn, new ExtendedBean()).asString());
+
+ assertEquals("renderer(ExtendedBean(42, 3.14))",
+ render(extendedBeanColumn, new ExtendedBean()).asString());
+ }
+
+ @Test
+ public void testNullEncoding() {
+
+ textColumn.setRenderer(new TextRenderer());
+ htmlColumn.setRenderer(new HtmlRenderer());
+ numberColumn.setRenderer(new NumberRenderer());
+ dateColumn.setRenderer(new DateRenderer());
+ buttonColumn.setRenderer(new ButtonRenderer());
+
+ assertEquals("", textColumn.getRenderer().encode(null).asString());
+ assertEquals("", htmlColumn.getRenderer().encode(null).asString());
+ assertEquals("", numberColumn.getRenderer().encode(null).asString());
+ assertEquals("", dateColumn.getRenderer().encode(null).asString());
+ assertEquals("", buttonColumn.getRenderer().encode(null).asString());
+ }
+
+ @Test
+ public void testNullEncodingWithDefault() {
+
+ textColumn.setRenderer(new TextRenderer("default value"));
+ htmlColumn.setRenderer(new HtmlRenderer("default value"));
+ numberColumn.setRenderer(new NumberRenderer("%s", Locale.getDefault(),
+ "default value"));
+ dateColumn.setRenderer(new DateRenderer("%s", "default value"));
+ buttonColumn.setRenderer(new ButtonRenderer("default value"));
+
+ assertEquals("default value", textColumn.getRenderer().encode(null)
+ .asString());
+ assertEquals("default value", htmlColumn.getRenderer().encode(null)
+ .asString());
+ assertEquals("default value", numberColumn.getRenderer().encode(null)
+ .asString());
+ assertEquals("default value", dateColumn.getRenderer().encode(null)
+ .asString());
+ assertEquals("default value", buttonColumn.getRenderer().encode(null)
+ .asString());
+ }
+
+ private TestConverter converter() {
+ return new TestConverter();
+ }
+
+ private TestRenderer renderer() {
+ return new TestRenderer();
+ }
+
+ private JsonValue render(Column column, Object value) {
+ return AbstractRenderer.encodeValue(value, column.getRenderer(),
+ column.getConverter(), grid.getLocale());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/validation/BeanValidationTest.java b/server/src/test/java/com/vaadin/tests/server/validation/BeanValidationTest.java
new file mode 100644
index 0000000000..6b7582525e
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/validation/BeanValidationTest.java
@@ -0,0 +1,125 @@
+package com.vaadin.tests.server.validation;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.Validator.InvalidValueException;
+import com.vaadin.data.fieldgroup.BeanFieldGroup;
+import com.vaadin.data.validator.BeanValidator;
+import com.vaadin.tests.data.bean.BeanToValidate;
+import com.vaadin.ui.Field;
+
+public class BeanValidationTest {
+ @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");
+ }
+
+ @Test
+ public void testBeanValidationException_OneValidationError() {
+ InvalidValueException[] causes = null;
+ BeanValidator validator = new BeanValidator(BeanToValidate.class,
+ "lastname");
+ try {
+ validator.validate(null);
+ } catch (InvalidValueException e) {
+ causes = e.getCauses();
+ }
+
+ Assert.assertEquals(1, causes.length);
+ }
+
+ @Test
+ public void testBeanValidationsException_TwoValidationErrors() {
+ InvalidValueException[] causes = null;
+ BeanValidator validator = new BeanValidator(BeanToValidate.class,
+ "nickname");
+ try {
+ validator.validate("A");
+ } catch (InvalidValueException e) {
+ causes = e.getCauses();
+ }
+
+ Assert.assertEquals(2, causes.length);
+ }
+
+ public void testBeanValidationNotAddedTwice() {
+ // See ticket #11045
+ BeanFieldGroup<BeanToValidate> fieldGroup = new BeanFieldGroup<BeanToValidate>(
+ BeanToValidate.class);
+
+ BeanToValidate beanToValidate = new BeanToValidate();
+ beanToValidate.setFirstname("a");
+ fieldGroup.setItemDataSource(beanToValidate);
+
+ Field<?> nameField = fieldGroup.buildAndBind("firstname");
+ Assert.assertEquals(1, nameField.getValidators().size());
+
+ try {
+ nameField.validate();
+ } catch (InvalidValueException e) {
+ // NOTE: causes are empty if only one validation fails
+ Assert.assertEquals(0, e.getCauses().length);
+ }
+
+ // Create new, identical bean to cause duplicate validator unless #11045
+ // is fixed
+ beanToValidate = new BeanToValidate();
+ beanToValidate.setFirstname("a");
+ fieldGroup.setItemDataSource(beanToValidate);
+
+ Assert.assertEquals(1, nameField.getValidators().size());
+
+ try {
+ nameField.validate();
+ } catch (InvalidValueException e) {
+ // NOTE: if more than one validation fails, we get the number of
+ // failed validations
+ Assert.assertEquals(0, e.getCauses().length);
+ }
+
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/server/validation/RangeValidatorTest.java b/server/src/test/java/com/vaadin/tests/server/validation/RangeValidatorTest.java
new file mode 100644
index 0000000000..e3320b8699
--- /dev/null
+++ b/server/src/test/java/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/src/test/java/com/vaadin/tests/server/validation/ReadOnlyValidationTest.java b/server/src/test/java/com/vaadin/tests/server/validation/ReadOnlyValidationTest.java
new file mode 100644
index 0000000000..661236e597
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/validation/ReadOnlyValidationTest.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 ReadOnlyValidationTest {
+
+ @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/src/test/java/com/vaadin/tests/util/AlwaysLockedVaadinSession.java b/server/src/test/java/com/vaadin/tests/util/AlwaysLockedVaadinSession.java
new file mode 100644
index 0000000000..89d3449b12
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/util/AlwaysLockedVaadinSession.java
@@ -0,0 +1,13 @@
+package com.vaadin.tests.util;
+
+import com.vaadin.server.MockVaadinSession;
+import com.vaadin.server.VaadinService;
+
+public class AlwaysLockedVaadinSession extends MockVaadinSession {
+
+ public AlwaysLockedVaadinSession(VaadinService service) {
+ super(service);
+ lock();
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/util/GraphVizClassHierarchyCreator.java b/server/src/test/java/com/vaadin/tests/util/GraphVizClassHierarchyCreator.java
new file mode 100644
index 0000000000..9e791500b0
--- /dev/null
+++ b/server/src/test/java/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/src/test/java/com/vaadin/tests/util/MockDeploymentConfiguration.java b/server/src/test/java/com/vaadin/tests/util/MockDeploymentConfiguration.java
new file mode 100644
index 0000000000..ddee23a9ec
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/util/MockDeploymentConfiguration.java
@@ -0,0 +1,128 @@
+package com.vaadin.tests.util;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import com.vaadin.server.AbstractDeploymentConfiguration;
+import com.vaadin.shared.communication.PushMode;
+
+public class MockDeploymentConfiguration extends
+ AbstractDeploymentConfiguration {
+
+ private boolean productionMode = false;
+ private boolean xsrfProtectionEnabled = true;
+
+ private int resourceCacheTime = 12;
+ private int heartbeatInterval = 300;
+ private boolean closeIdleSessions = false;
+ private PushMode pushMode = PushMode.DISABLED;
+ private Properties initParameters = new Properties();
+ private Map<String, String> applicationOrSystemProperty = new HashMap<String, String>();
+ private LegacyProperyToStringMode legacyPropertyToStringMode = LegacyProperyToStringMode.DISABLED;
+ private boolean syncIdCheckEnabled = true;
+ private boolean sendUrlsAsParameters = true;
+
+ @Override
+ public boolean isProductionMode() {
+ return productionMode;
+ }
+
+ public void setProductionMode(boolean productionMode) {
+ this.productionMode = productionMode;
+ }
+
+ @Override
+ public boolean isXsrfProtectionEnabled() {
+ return xsrfProtectionEnabled;
+ }
+
+ @Override
+ public boolean isSyncIdCheckEnabled() {
+ return syncIdCheckEnabled;
+ }
+
+ public void setSyncIdCheckEnabled(boolean syncIdCheckEnabled) {
+ this.syncIdCheckEnabled = syncIdCheckEnabled;
+ }
+
+ public void setXsrfProtectionEnabled(boolean xsrfProtectionEnabled) {
+ this.xsrfProtectionEnabled = xsrfProtectionEnabled;
+ }
+
+ @Override
+ public int getResourceCacheTime() {
+ return resourceCacheTime;
+ }
+
+ public void setResourceCacheTime(int resourceCacheTime) {
+ this.resourceCacheTime = resourceCacheTime;
+ }
+
+ @Override
+ public int getHeartbeatInterval() {
+ return heartbeatInterval;
+ }
+
+ public void setHeartbeatInterval(int heartbeatInterval) {
+ this.heartbeatInterval = heartbeatInterval;
+ }
+
+ @Override
+ public boolean isCloseIdleSessions() {
+ return closeIdleSessions;
+ }
+
+ public void setCloseIdleSessions(boolean closeIdleSessions) {
+ this.closeIdleSessions = closeIdleSessions;
+ }
+
+ @Override
+ public PushMode getPushMode() {
+ return pushMode;
+ }
+
+ public void setPushMode(PushMode pushMode) {
+ this.pushMode = pushMode;
+ }
+
+ @Override
+ public Properties getInitParameters() {
+ return initParameters;
+ }
+
+ public void setInitParameter(String key, String value) {
+ initParameters.setProperty(key, value);
+ }
+
+ public void setApplicationOrSystemProperty(String key, String value) {
+ applicationOrSystemProperty.put(key, value);
+ }
+
+ @Override
+ public String getApplicationOrSystemProperty(String propertyName,
+ String defaultValue) {
+ if (applicationOrSystemProperty.containsKey(propertyName)) {
+ return applicationOrSystemProperty.get(propertyName);
+ } else {
+ return defaultValue;
+ }
+ }
+
+ @Override
+ @Deprecated
+ public LegacyProperyToStringMode getLegacyPropertyToStringMode() {
+ return legacyPropertyToStringMode;
+ }
+
+ public void setLegacyPropertyToStringMode(
+ LegacyProperyToStringMode legacyPropertyToStringMode) {
+ this.legacyPropertyToStringMode = legacyPropertyToStringMode;
+ }
+
+ @Override
+ public boolean isSendUrlsAsParameters() {
+ return sendUrlsAsParameters;
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tests/util/MockUI.java b/server/src/test/java/com/vaadin/tests/util/MockUI.java
new file mode 100644
index 0000000000..17dc24e9e8
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/util/MockUI.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2000-2014 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 com.vaadin.server.VaadinRequest;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.ui.UI;
+
+public class MockUI extends UI {
+
+ public MockUI() {
+ this(findOrcreateSession());
+ }
+
+ public MockUI(VaadinSession session) {
+ setSession(session);
+ setCurrent(this);
+ }
+
+ @Override
+ protected void init(VaadinRequest request) {
+ // Do nothing
+ }
+
+ private static VaadinSession findOrcreateSession() {
+ VaadinSession session = VaadinSession.getCurrent();
+ if (session == null) {
+ session = new AlwaysLockedVaadinSession(null);
+ VaadinSession.setCurrent(session);
+ }
+ return session;
+ }
+}
diff --git a/server/src/test/java/com/vaadin/tests/util/TestUtil.java b/server/src/test/java/com/vaadin/tests/util/TestUtil.java
new file mode 100644
index 0000000000..88ed017f91
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/util/TestUtil.java
@@ -0,0 +1,43 @@
+package com.vaadin.tests.util;
+
+import java.util.Iterator;
+
+import org.junit.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/src/test/java/com/vaadin/tests/util/UniqueSerializableTest.java b/server/src/test/java/com/vaadin/tests/util/UniqueSerializableTest.java
new file mode 100644
index 0000000000..abdc6c1a5c
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/util/UniqueSerializableTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2000-2014 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));
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/ui/AbsFieldDataSourceLocaleChangeTest.java b/server/src/test/java/com/vaadin/ui/AbsFieldDataSourceLocaleChangeTest.java
new file mode 100644
index 0000000000..bb5babf360
--- /dev/null
+++ b/server/src/test/java/com/vaadin/ui/AbsFieldDataSourceLocaleChangeTest.java
@@ -0,0 +1,62 @@
+package com.vaadin.ui;
+
+import java.text.NumberFormat;
+import java.util.Locale;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.util.converter.StringToIntegerConverter;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.tests.util.AlwaysLockedVaadinSession;
+
+public class AbsFieldDataSourceLocaleChangeTest {
+
+ private VaadinSession vaadinSession;
+ private UI ui;
+
+ @Before
+ public void setup() {
+ vaadinSession = new AlwaysLockedVaadinSession(null);
+ VaadinSession.setCurrent(vaadinSession);
+ ui = new UI() {
+
+ @Override
+ protected void init(VaadinRequest request) {
+
+ }
+ };
+ ui.setSession(vaadinSession);
+ UI.setCurrent(ui);
+ }
+
+ @Test
+ public void localeChangesOnAttach() {
+ TextField tf = new TextField();
+
+ tf.setConverter(new StringToIntegerConverter() {
+ @Override
+ protected NumberFormat getFormat(Locale locale) {
+ if (locale == null) {
+ NumberFormat format = super.getFormat(locale);
+ format.setGroupingUsed(false);
+ format.setMinimumIntegerDigits(10);
+ return format;
+ }
+ return super.getFormat(locale);
+ }
+ });
+ tf.setImmediate(true);
+ tf.setConvertedValue(10000);
+ Assert.assertEquals("0000010000", tf.getValue());
+
+ VerticalLayout vl = new VerticalLayout();
+ ui.setContent(vl);
+ ui.setLocale(new Locale("en", "US"));
+
+ vl.addComponent(tf);
+ Assert.assertEquals("10,000", tf.getValue());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/ui/AbsSelectTest.java b/server/src/test/java/com/vaadin/ui/AbsSelectTest.java
new file mode 100644
index 0000000000..0b807c5f21
--- /dev/null
+++ b/server/src/test/java/com/vaadin/ui/AbsSelectTest.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2000-2014 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.ui;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.util.ObjectProperty;
+
+public class AbsSelectTest {
+
+ @Test
+ public void addItemsStrings() {
+ NativeSelect ns = new NativeSelect();
+ ns.addItems("Foo", "bar", "baz");
+ Assert.assertEquals(3, ns.size());
+ Assert.assertArrayEquals(new Object[] { "Foo", "bar", "baz" }, ns
+ .getItemIds().toArray());
+ }
+
+ @Test
+ public void addItemsObjects() {
+ Object o1 = new Object();
+ Object o2 = new Object();
+ Object o3 = new Object();
+
+ NativeSelect ns = new NativeSelect();
+ ns.addItems(o1, o2, o3);
+ Assert.assertEquals(3, ns.size());
+ Assert.assertArrayEquals(new Object[] { o1, o2, o3 }, ns.getItemIds()
+ .toArray());
+ }
+
+ @Test
+ public void addItemsStringList() {
+ ArrayList<String> itemIds = new ArrayList<String>();
+ itemIds.add("foo");
+ itemIds.add("bar");
+ itemIds.add("baz");
+ NativeSelect ns = new NativeSelect();
+ ns.addItems(itemIds);
+ Assert.assertEquals(3, ns.size());
+ Assert.assertArrayEquals(new Object[] { "foo", "bar", "baz" }, ns
+ .getItemIds().toArray());
+ }
+
+ @Test
+ public void addItemsObjectList() {
+ Object o1 = new Object();
+ Object o2 = new Object();
+ Object o3 = new Object();
+ ArrayList<Object> itemIds = new ArrayList<Object>();
+ itemIds.add(o1);
+ itemIds.add(o2);
+ itemIds.add(o3);
+ NativeSelect ns = new NativeSelect();
+ ns.addItems(itemIds);
+ Assert.assertEquals(3, ns.size());
+ Assert.assertArrayEquals(new Object[] { o1, o2, o3 }, ns.getItemIds()
+ .toArray());
+
+ }
+
+ @Test
+ public void singleSelectInitiallyEmpty() {
+ AbstractSelect s = new ListSelect();
+ Assert.assertTrue(s.isEmpty());
+ }
+
+ @Test
+ public void singleSelectEmptyAfterClearUsingPDS() {
+ AbstractSelect s = new ListSelect();
+ s.addItem("foo");
+ s.addItem("bar");
+ s.setPropertyDataSource(new ObjectProperty<String>("foo"));
+
+ Assert.assertFalse(s.isEmpty());
+ s.clear();
+ Assert.assertTrue(s.isEmpty());
+ }
+
+ @Test
+ public void singleSelectEmptyAfterClear() {
+ AbstractSelect s = new ListSelect();
+ s.addItem("foo");
+ s.addItem("bar");
+ s.setValue("bar");
+
+ Assert.assertFalse(s.isEmpty());
+ s.clear();
+ Assert.assertTrue(s.isEmpty());
+ }
+
+ @Test
+ public void multiSelectInitiallyEmpty() {
+ AbstractSelect s = new ListSelect();
+ s.setMultiSelect(true);
+ Assert.assertTrue(s.isEmpty());
+ }
+
+ @Test
+ public void multiSelectEmptyAfterClearUsingPDS() {
+ AbstractSelect s = new ListSelect();
+ s.setMultiSelect(true);
+ s.addItem("foo");
+ s.addItem("bar");
+ HashSet<String> sel = new HashSet<String>();
+ sel.add("foo");
+ sel.add("bar");
+ s.setPropertyDataSource(new ObjectProperty<HashSet>(sel));
+
+ Assert.assertFalse(s.isEmpty());
+ s.clear();
+ Assert.assertTrue(s.isEmpty());
+ }
+
+ @Test
+ public void multiSelectEmptyAfterClear() {
+ AbstractSelect s = new ListSelect();
+ s.setMultiSelect(true);
+ s.addItem("foo");
+ s.addItem("bar");
+ s.select("foo");
+ s.select("bar");
+
+ Assert.assertFalse(s.isEmpty());
+ s.clear();
+ Assert.assertTrue(s.isEmpty());
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/ui/CheckBoxTest.java b/server/src/test/java/com/vaadin/ui/CheckBoxTest.java
new file mode 100644
index 0000000000..7d699998de
--- /dev/null
+++ b/server/src/test/java/com/vaadin/ui/CheckBoxTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2000-2014 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.ui;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.util.ObjectProperty;
+
+public class CheckBoxTest {
+ @Test
+ public void initiallyEmpty() {
+ CheckBox tf = new CheckBox();
+ Assert.assertTrue(tf.isEmpty());
+ }
+
+ @Test
+ public void emptyAfterClearUsingPDS() {
+ CheckBox tf = new CheckBox();
+ tf.setPropertyDataSource(new ObjectProperty<Boolean>(Boolean.TRUE));
+ Assert.assertFalse(tf.isEmpty());
+ tf.clear();
+ Assert.assertTrue(tf.isEmpty());
+ }
+
+ @Test
+ public void emptyAfterClear() {
+ CheckBox tf = new CheckBox();
+ tf.setValue(true);
+ Assert.assertFalse(tf.isEmpty());
+ tf.clear();
+ Assert.assertTrue(tf.isEmpty());
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/ui/DateFieldTests.java b/server/src/test/java/com/vaadin/ui/DateFieldTests.java
new file mode 100644
index 0000000000..6a75b4630c
--- /dev/null
+++ b/server/src/test/java/com/vaadin/ui/DateFieldTests.java
@@ -0,0 +1,56 @@
+package com.vaadin.ui;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Date;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsNull.nullValue;
+
+public class DateFieldTests {
+
+ private DateField dateField;
+ private Date date;
+
+ @Before
+ public void setup() {
+ dateField = new DateField();
+ date = new Date();
+ }
+
+ @Test
+ public void rangeStartIsSetToNull() {
+ dateField.setRangeStart(null);
+
+ assertThat(dateField.getRangeStart(), is(nullValue()));
+ }
+
+ @Test
+ public void rangeStartIsImmutable() {
+ long expectedTime = date.getTime();
+
+ dateField.setRangeStart(date);
+ date.setTime(expectedTime + 1);
+
+ assertThat(dateField.getRangeStart().getTime(), is(expectedTime));
+ }
+
+ @Test
+ public void rangeEndIsSetToNull() {
+ dateField.setRangeEnd(null);
+
+ assertThat(dateField.getRangeEnd(), is(nullValue()));
+ }
+
+ @Test
+ public void rangeEndIsImmutable() {
+ long expectedTime = date.getTime();
+
+ dateField.setRangeEnd(date);
+ date.setTime(expectedTime + 1);
+
+ assertThat(dateField.getRangeEnd().getTime(), is(expectedTime));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/ui/GridLayoutExpandRatioTest.java b/server/src/test/java/com/vaadin/ui/GridLayoutExpandRatioTest.java
new file mode 100644
index 0000000000..617c7f54ed
--- /dev/null
+++ b/server/src/test/java/com/vaadin/ui/GridLayoutExpandRatioTest.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2000-2014 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.ui;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import com.vaadin.server.Sizeable.Unit;
+
+public class GridLayoutExpandRatioTest {
+
+ private GridLayout gridLayout;
+
+ @Test
+ public void testColExpandRatioIsForgotten() {
+ gridLayout = new GridLayout(4, 1);
+ gridLayout.setWidth(100, Unit.PERCENTAGE);
+ gridLayout.setSizeFull();
+ gridLayout.setSpacing(true);
+
+ addComponents(true);
+
+ gridLayout.setColumnExpandRatio(1, 1);
+ gridLayout.setColumnExpandRatio(3, 1);
+
+ assertTrue(gridLayout.getColumnExpandRatio(0) == 0);
+ assertTrue(gridLayout.getColumnExpandRatio(1) == 1);
+ assertTrue(gridLayout.getColumnExpandRatio(2) == 0);
+ assertTrue(gridLayout.getColumnExpandRatio(3) == 1);
+ assertFalse(gridLayout.getState().explicitColRatios.contains(0));
+ assertTrue(gridLayout.getState().explicitColRatios.contains(1));
+ assertFalse(gridLayout.getState().explicitColRatios.contains(2));
+ assertTrue(gridLayout.getState().explicitColRatios.contains(3));
+
+ gridLayout.removeAllComponents();
+ gridLayout.setColumns(3);
+ addComponents(false);
+
+ assertTrue(gridLayout.getColumnExpandRatio(0) == 0);
+ assertTrue(gridLayout.getColumnExpandRatio(1) == 1);
+ assertTrue(gridLayout.getColumnExpandRatio(2) == 0);
+ assertTrue(gridLayout.getColumnExpandRatio(3) == 0);
+ assertFalse(gridLayout.getState().explicitColRatios.contains(0));
+ assertTrue(gridLayout.getState().explicitColRatios.contains(1));
+ assertFalse(gridLayout.getState().explicitColRatios.contains(2));
+ assertFalse(gridLayout.getState().explicitColRatios.contains(3));
+ }
+
+ @Test
+ public void testRowExpandRatioIsForgotten() {
+ gridLayout = new GridLayout(1, 4);
+ gridLayout.setWidth(100, Unit.PERCENTAGE);
+ gridLayout.setSizeFull();
+ gridLayout.setSpacing(true);
+
+ addComponents(true);
+
+ gridLayout.setRowExpandRatio(1, 1);
+ gridLayout.setRowExpandRatio(3, 1);
+
+ assertTrue(gridLayout.getRowExpandRatio(0) == 0);
+ assertTrue(gridLayout.getRowExpandRatio(1) == 1);
+ assertTrue(gridLayout.getRowExpandRatio(2) == 0);
+ assertTrue(gridLayout.getRowExpandRatio(3) == 1);
+ assertFalse(gridLayout.getState().explicitRowRatios.contains(0));
+ assertTrue(gridLayout.getState().explicitRowRatios.contains(1));
+ assertFalse(gridLayout.getState().explicitRowRatios.contains(2));
+ assertTrue(gridLayout.getState().explicitRowRatios.contains(3));
+
+ gridLayout.removeAllComponents();
+ gridLayout.setRows(3);
+ addComponents(false);
+
+ assertTrue(gridLayout.getRowExpandRatio(0) == 0);
+ assertTrue(gridLayout.getRowExpandRatio(1) == 1);
+ assertTrue(gridLayout.getRowExpandRatio(2) == 0);
+ assertTrue(gridLayout.getRowExpandRatio(3) == 0);
+ assertFalse(gridLayout.getState().explicitRowRatios.contains(0));
+ assertTrue(gridLayout.getState().explicitRowRatios.contains(1));
+ assertFalse(gridLayout.getState().explicitRowRatios.contains(2));
+ assertFalse(gridLayout.getState().explicitRowRatios.contains(3));
+ }
+
+ private void addComponents(boolean includeLastOne) {
+ gridLayout.addComponent(label("{1}"));
+ gridLayout.addComponent(label("{2}"));
+ gridLayout.addComponent(label("{3}"));
+ if (includeLastOne) {
+ gridLayout.addComponent(label("{4}"));
+ }
+ }
+
+ private Label label(String content) {
+ Label label = new Label(content);
+ label.setSizeUndefined();
+ return label;
+ }
+}
diff --git a/server/src/test/java/com/vaadin/ui/HorizontalSplitPanelTest.java b/server/src/test/java/com/vaadin/ui/HorizontalSplitPanelTest.java
new file mode 100644
index 0000000000..9797e48924
--- /dev/null
+++ b/server/src/test/java/com/vaadin/ui/HorizontalSplitPanelTest.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2000-2014 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.ui;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.shared.ui.splitpanel.HorizontalSplitPanelState;
+
+public class HorizontalSplitPanelTest {
+
+ @Test
+ public void primaryStyleName() {
+ Assert.assertEquals(new HorizontalSplitPanelState().primaryStyleName,
+ new HorizontalSplitPanel().getPrimaryStyleName());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/ui/LabelDataSourceTest.java b/server/src/test/java/com/vaadin/ui/LabelDataSourceTest.java
new file mode 100644
index 0000000000..030504cf2b
--- /dev/null
+++ b/server/src/test/java/com/vaadin/ui/LabelDataSourceTest.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2000-2014 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.ui;
+
+import java.util.Locale;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.tests.util.AlwaysLockedVaadinSession;
+import com.vaadin.tests.util.MockUI;
+
+public class LabelDataSourceTest {
+
+ Label label;
+ private static final String STRING_DS_VALUE = "String DatA source";
+ private static final int INTEGER_DS_VALUE = 1587;
+ private static final String INTEGER_STRING_VALUE_FI = "1 587";
+ private static final String INTEGER_STRING_VALUE_EN_US = "1,587";
+ private static final Object INTEGER_STRING_VALUE_DE = "1.587";
+ ObjectProperty<String> stringDataSource;
+ private ObjectProperty<Integer> integerDataSource;
+ VaadinSession vaadinSession;
+
+ @Before
+ public void setup() {
+ vaadinSession = new AlwaysLockedVaadinSession(null);
+ VaadinSession.setCurrent(vaadinSession);
+
+ label = new Label();
+ stringDataSource = new ObjectProperty<String>(STRING_DS_VALUE);
+ integerDataSource = new ObjectProperty<Integer>(INTEGER_DS_VALUE);
+ }
+
+ @Test
+ public void stringDataSource() {
+ label.setPropertyDataSource(stringDataSource);
+ Assert.assertEquals(STRING_DS_VALUE, label.getState().text);
+ Assert.assertEquals(STRING_DS_VALUE, label.getValue());
+ Assert.assertEquals(stringDataSource, label.getPropertyDataSource());
+ label.setPropertyDataSource(null);
+ Assert.assertEquals(STRING_DS_VALUE, label.getState().text);
+ Assert.assertEquals(STRING_DS_VALUE, label.getValue());
+ Assert.assertEquals(null, label.getPropertyDataSource());
+ label.setValue("foo");
+ Assert.assertEquals("foo", label.getState().text);
+ Assert.assertEquals("foo", label.getValue());
+ Assert.assertNull(label.getPropertyDataSource());
+
+ }
+
+ @Test
+ public void integerDataSourceFi() {
+ label.setLocale(new Locale("fi", "FI"));
+ label.setPropertyDataSource(integerDataSource);
+ Assert.assertEquals(INTEGER_STRING_VALUE_FI, label.getState().text);
+ Assert.assertEquals(INTEGER_STRING_VALUE_FI, label.getValue());
+ Assert.assertEquals(integerDataSource, label.getPropertyDataSource());
+ }
+
+ @Test
+ public void integerDataSourceEn() {
+ label.setLocale(new Locale("en", "US"));
+ label.setPropertyDataSource(integerDataSource);
+ Assert.assertEquals(INTEGER_STRING_VALUE_EN_US, label.getState().text);
+ Assert.assertEquals(INTEGER_STRING_VALUE_EN_US, label.getValue());
+ Assert.assertEquals(integerDataSource, label.getPropertyDataSource());
+ }
+
+ @Test
+ public void changeLocaleAfterDataSource() {
+ label.setLocale(new Locale("en", "US"));
+ label.setPropertyDataSource(integerDataSource);
+ label.setLocale(new Locale("fi", "FI"));
+ Assert.assertEquals(INTEGER_STRING_VALUE_FI, label.getState().text);
+ Assert.assertEquals(INTEGER_STRING_VALUE_FI, label.getValue());
+ Assert.assertEquals(integerDataSource, label.getPropertyDataSource());
+ }
+
+ @Test
+ public void setRemoveDataSource() {
+ label.setValue("before");
+ label.setPropertyDataSource(stringDataSource);
+ Assert.assertEquals(STRING_DS_VALUE, label.getValue());
+ label.setPropertyDataSource(null);
+ Assert.assertEquals(STRING_DS_VALUE, label.getValue());
+ label.setValue("after");
+ Assert.assertEquals("after", label.getValue());
+ }
+
+ @Test
+ public void attachToSessionWithDifferentLocale() {
+ label.setValue("before");
+ // label.setLocale(Locale.GERMANY);
+ label.setPropertyDataSource(integerDataSource);
+ UI ui = new MockUI();
+ ui.setLocale(Locale.GERMANY);
+ ui.setContent(label);
+ Assert.assertEquals(INTEGER_STRING_VALUE_DE, label.getState().text);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/ui/NativeSelectTest.java b/server/src/test/java/com/vaadin/ui/NativeSelectTest.java
new file mode 100644
index 0000000000..78e4715f9b
--- /dev/null
+++ b/server/src/test/java/com/vaadin/ui/NativeSelectTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2000-2014 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.ui;
+
+import java.util.Collections;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.shared.ui.select.AbstractSelectState;
+
+public class NativeSelectTest {
+
+ @Test
+ public void rpcRegisteredConstructorNoArg() {
+ assertFocusRpcRegistered(new NativeSelect());
+ }
+
+ @Test
+ public void rpcRegisteredConstructorString() {
+ assertFocusRpcRegistered(new NativeSelect("foo"));
+ }
+
+ @Test
+ public void rpcRegisteredConstructorStringCollection() {
+ assertFocusRpcRegistered(new NativeSelect("foo",
+ Collections.singleton("Hello")));
+ }
+
+ @Test
+ public void rpcRegisteredConstructorStringContainer() {
+ assertFocusRpcRegistered(new NativeSelect("foo", new IndexedContainer()));
+ }
+
+ @Test
+ public void getState_listSelectHasCustomState() {
+ TestNativeSelect select = new TestNativeSelect();
+ AbstractSelectState state = select.getState();
+ Assert.assertEquals("Unexpected state class",
+ AbstractSelectState.class, state.getClass());
+ }
+
+ private static class TestNativeSelect extends NativeSelect {
+ @Override
+ public AbstractSelectState getState() {
+ return super.getState();
+ }
+ }
+
+ private void assertFocusRpcRegistered(NativeSelect s) {
+ Assert.assertNotNull(
+ "RPC is not correctly registered",
+ s.getRpcManager("com.vaadin.shared.communication.FieldRpc$FocusAndBlurServerRpc"));
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/ui/PushConfigurationTransportTest.java b/server/src/test/java/com/vaadin/ui/PushConfigurationTransportTest.java
new file mode 100644
index 0000000000..80e7dd9261
--- /dev/null
+++ b/server/src/test/java/com/vaadin/ui/PushConfigurationTransportTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2000-2014 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.ui;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.shared.ui.ui.Transport;
+
+/**
+ * @author Vaadin Ltd
+ */
+public class PushConfigurationTransportTest {
+ @Test
+ public void testTransportModes() throws Exception {
+ UI ui = new UI() {
+
+ @Override
+ protected void init(VaadinRequest request) {
+ // TODO Auto-generated method stub
+
+ }
+
+ };
+ for (Transport transport : Transport.values()) {
+ ui.getPushConfiguration().setTransport(transport);
+ Assert.assertEquals(ui.getPushConfiguration().getTransport(),
+ transport);
+
+ if (transport == Transport.WEBSOCKET_XHR) {
+ Assert.assertTrue(ui.getState().pushConfiguration.alwaysUseXhrForServerRequests);
+ } else {
+ Assert.assertFalse(ui.getState().pushConfiguration.alwaysUseXhrForServerRequests);
+ }
+ }
+
+ }
+}
diff --git a/server/src/test/java/com/vaadin/ui/RichTextAreaTest.java b/server/src/test/java/com/vaadin/ui/RichTextAreaTest.java
new file mode 100644
index 0000000000..ce0dfdc696
--- /dev/null
+++ b/server/src/test/java/com/vaadin/ui/RichTextAreaTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2000-2014 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.ui;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.util.ObjectProperty;
+
+public class RichTextAreaTest {
+ @Test
+ public void initiallyEmpty() {
+ RichTextArea tf = new RichTextArea();
+ Assert.assertTrue(tf.isEmpty());
+ }
+
+ @Test
+ public void emptyAfterClearUsingPDS() {
+ RichTextArea tf = new RichTextArea(new ObjectProperty<String>("foo"));
+ Assert.assertFalse(tf.isEmpty());
+ tf.clear();
+ Assert.assertTrue(tf.isEmpty());
+ }
+
+ @Test
+ public void emptyAfterClear() {
+ RichTextArea tf = new RichTextArea();
+ tf.setValue("foobar");
+ Assert.assertFalse(tf.isEmpty());
+ tf.clear();
+ Assert.assertTrue(tf.isEmpty());
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/ui/SplitPositionChangeListenerTest.java b/server/src/test/java/com/vaadin/ui/SplitPositionChangeListenerTest.java
new file mode 100644
index 0000000000..02dc412cd9
--- /dev/null
+++ b/server/src/test/java/com/vaadin/ui/SplitPositionChangeListenerTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2000-2014 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.ui;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import org.junit.Test;
+
+import com.vaadin.server.Sizeable.Unit;
+import com.vaadin.ui.AbstractSplitPanel.SplitPositionChangeEvent;
+import com.vaadin.ui.AbstractSplitPanel.SplitPositionChangeListener;
+
+/**
+ * Test for {@link SplitPositionChangeListener}
+ *
+ * @author Vaadin Ltd
+ */
+public class SplitPositionChangeListenerTest {
+
+ @Test
+ public void testSplitPositionListenerIsTriggered() throws Exception {
+ final HorizontalSplitPanel splitPanel = new HorizontalSplitPanel();
+ SplitPositionChangeListener splitPositionChangeListener = mock(SplitPositionChangeListener.class);
+ splitPanel.addSplitPositionChangeListener(splitPositionChangeListener);
+ splitPanel.setSplitPosition(50, Unit.PERCENTAGE);
+ verify(splitPositionChangeListener).onSplitPositionChanged(
+ any(SplitPositionChangeEvent.class));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/ui/TableTest.java b/server/src/test/java/com/vaadin/ui/TableTest.java
new file mode 100644
index 0000000000..86237abbe0
--- /dev/null
+++ b/server/src/test/java/com/vaadin/ui/TableTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2000-2014 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.ui;
+
+import java.util.Collection;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.util.BeanItemContainerGenerator;
+
+public class TableTest {
+
+ Table table;
+
+ @Before
+ public void init() {
+ table = new Table();
+ }
+
+ @Test
+ public void initiallyEmpty() {
+ Assert.assertTrue(table.isEmpty());
+ }
+
+ @Test
+ public void emptyAfterClearSingleSelect() {
+ table.setContainerDataSource(BeanItemContainerGenerator
+ .createContainer(100));
+ Assert.assertTrue(table.isEmpty());
+ Object first = table.getContainerDataSource().getItemIds().iterator()
+ .next();
+ table.setValue(first);
+ Assert.assertEquals(first, table.getValue());
+ Assert.assertFalse(table.isEmpty());
+ table.clear();
+ Assert.assertEquals(null, table.getValue());
+ Assert.assertTrue(table.isEmpty());
+ }
+
+ @Test
+ public void emptyAfterClearMultiSelect() {
+ table.setMultiSelect(true);
+ table.setContainerDataSource(BeanItemContainerGenerator
+ .createContainer(100));
+
+ Assert.assertTrue(table.isEmpty());
+ Assert.assertArrayEquals(new Object[] {},
+ ((Collection) table.getValue()).toArray());
+
+ Object first = table.getContainerDataSource().getItemIds().iterator()
+ .next();
+ table.select(first);
+ Assert.assertArrayEquals(new Object[] { first },
+ ((Collection) table.getValue()).toArray());
+ Assert.assertFalse(table.isEmpty());
+
+ table.clear();
+ Assert.assertArrayEquals(new Object[] {},
+ ((Collection) table.getValue()).toArray());
+ Assert.assertTrue(table.isEmpty());
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/ui/TextAreaTest.java b/server/src/test/java/com/vaadin/ui/TextAreaTest.java
new file mode 100644
index 0000000000..e7e99c19e9
--- /dev/null
+++ b/server/src/test/java/com/vaadin/ui/TextAreaTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2000-2014 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.ui;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.util.ObjectProperty;
+
+public class TextAreaTest {
+ @Test
+ public void initiallyEmpty() {
+ TextArea tf = new TextArea();
+ Assert.assertTrue(tf.isEmpty());
+ }
+
+ @Test
+ public void emptyAfterClearUsingPDS() {
+ TextArea tf = new TextArea(new ObjectProperty<String>("foo"));
+ Assert.assertFalse(tf.isEmpty());
+ tf.clear();
+ Assert.assertTrue(tf.isEmpty());
+ }
+
+ @Test
+ public void emptyAfterClear() {
+ TextArea tf = new TextArea();
+ tf.setValue("foobar");
+ Assert.assertFalse(tf.isEmpty());
+ tf.clear();
+ Assert.assertTrue(tf.isEmpty());
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/ui/TextFieldTest.java b/server/src/test/java/com/vaadin/ui/TextFieldTest.java
new file mode 100644
index 0000000000..bfd452bd3b
--- /dev/null
+++ b/server/src/test/java/com/vaadin/ui/TextFieldTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2000-2014 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.ui;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.util.ObjectProperty;
+
+public class TextFieldTest {
+
+ @Test
+ public void initiallyEmpty() {
+ TextField tf = new TextField();
+ Assert.assertTrue(tf.isEmpty());
+ }
+
+ @Test
+ public void emptyAfterClearUsingPDS() {
+ TextField tf = new TextField(new ObjectProperty<String>("foo"));
+ Assert.assertFalse(tf.isEmpty());
+ tf.clear();
+ Assert.assertTrue(tf.isEmpty());
+ }
+
+ @Test
+ public void emptyAfterClear() {
+ TextField tf = new TextField();
+ tf.setValue("foobar");
+ Assert.assertFalse(tf.isEmpty());
+ tf.clear();
+ Assert.assertTrue(tf.isEmpty());
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/ui/UIInitRefreshTest.java b/server/src/test/java/com/vaadin/ui/UIInitRefreshTest.java
new file mode 100644
index 0000000000..9e1fabc58f
--- /dev/null
+++ b/server/src/test/java/com/vaadin/ui/UIInitRefreshTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2000-2014 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.ui;
+
+import org.easymock.EasyMock;
+import org.easymock.IMocksControl;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.server.Page.BrowserWindowResizeEvent;
+import com.vaadin.server.Page.BrowserWindowResizeListener;
+import com.vaadin.server.Page.UriFragmentChangedEvent;
+import com.vaadin.server.Page.UriFragmentChangedListener;
+import com.vaadin.server.VaadinRequest;
+
+public class UIInitRefreshTest {
+
+ private boolean initCalled;
+ private boolean refreshCalled;
+ private boolean fragmentChangeCalled;
+ private boolean browserWindowResizeCalled;
+
+ private class TestUI extends UI implements UriFragmentChangedListener,
+ BrowserWindowResizeListener {
+ @Override
+ protected void init(VaadinRequest request) {
+ getPage().addBrowserWindowResizeListener(this);
+ getPage().addUriFragmentChangedListener(this);
+
+ initCalled = true;
+
+ Assert.assertEquals("foo", getPage().getUriFragment());
+ Assert.assertEquals(100, getPage().getBrowserWindowWidth());
+ Assert.assertEquals(100, getPage().getBrowserWindowHeight());
+
+ Assert.assertFalse(fragmentChangeCalled);
+ Assert.assertFalse(browserWindowResizeCalled);
+ }
+
+ @Override
+ protected void refresh(VaadinRequest request) {
+ refreshCalled = true;
+
+ Assert.assertEquals("bar", getPage().getUriFragment());
+ Assert.assertEquals(200, getPage().getBrowserWindowWidth());
+ Assert.assertEquals(200, getPage().getBrowserWindowHeight());
+
+ Assert.assertFalse(fragmentChangeCalled);
+ Assert.assertFalse(browserWindowResizeCalled);
+ }
+
+ @Override
+ public void browserWindowResized(BrowserWindowResizeEvent event) {
+ Assert.assertEquals(200, event.getWidth());
+ Assert.assertEquals(200, event.getHeight());
+ browserWindowResizeCalled = true;
+ }
+
+ @Override
+ public void uriFragmentChanged(UriFragmentChangedEvent event) {
+ Assert.assertEquals("bar", event.getUriFragment());
+ fragmentChangeCalled = true;
+ }
+ }
+
+ @Before
+ public void setUp() {
+ initCalled = refreshCalled = fragmentChangeCalled = browserWindowResizeCalled = false;
+ }
+
+ @Test
+ public void testListenersCalled() {
+ IMocksControl control = EasyMock.createNiceControl();
+
+ VaadinRequest initRequest = control.createMock(VaadinRequest.class);
+ EasyMock.expect(initRequest.getParameter("v-loc")).andReturn(
+ "http://example.com/#foo");
+ EasyMock.expect(initRequest.getParameter("v-cw")).andReturn("100");
+ EasyMock.expect(initRequest.getParameter("v-ch")).andReturn("100");
+
+ VaadinRequest reinitRequest = control.createMock(VaadinRequest.class);
+ EasyMock.expect(reinitRequest.getParameter("v-loc")).andReturn(
+ "http://example.com/#bar");
+ EasyMock.expect(reinitRequest.getParameter("v-cw")).andReturn("200");
+ EasyMock.expect(reinitRequest.getParameter("v-ch")).andReturn("200");
+
+ control.replay();
+
+ UI ui = new TestUI();
+ ui.doInit(initRequest, 0, "");
+
+ Assert.assertTrue(initCalled);
+ Assert.assertFalse(fragmentChangeCalled);
+ Assert.assertFalse(browserWindowResizeCalled);
+
+ ui.doRefresh(reinitRequest);
+
+ Assert.assertTrue(refreshCalled);
+ Assert.assertTrue(fragmentChangeCalled);
+ Assert.assertTrue(browserWindowResizeCalled);
+ }
+}
diff --git a/server/src/test/java/com/vaadin/ui/UIThemeEscapingTest.java b/server/src/test/java/com/vaadin/ui/UIThemeEscapingTest.java
new file mode 100644
index 0000000000..7a0a5551e3
--- /dev/null
+++ b/server/src/test/java/com/vaadin/ui/UIThemeEscapingTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2000-2014 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.ui;
+
+import com.vaadin.server.VaadinRequest;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class UIThemeEscapingTest {
+
+ private UI ui;
+
+ private void initUiWithTheme(String theme) {
+ VaadinRequest request = getRequestWithTheme(theme);
+
+ ui.doInit(request, 1234, "foobar");
+ }
+
+ private VaadinRequest getRequestWithTheme(String theme) {
+ VaadinRequest request = mock(VaadinRequest.class);
+
+ when(request.getParameter("theme")).thenReturn(theme);
+
+ return request;
+ }
+
+ @Before
+ public void setup() {
+ ui = new UI() {
+ @Override
+ protected void init(VaadinRequest request) {
+ // Nothing to do
+ }
+ };
+ }
+
+ @Test
+ public void dangerousCharactersAreRemoved() {
+ ui.setTheme("a<å(_\"$");
+
+ assertThat(ui.getTheme(), is("aå_$"));
+ }
+
+ @Test
+ public void nullThemeIsSet() {
+ ui.setTheme("foobar");
+
+ ui.setTheme(null);
+
+ assertThat(ui.getTheme(), is(nullValue()));
+ }
+
+ @Test
+ public void themeIsSetOnInit() {
+ ui.setTheme("foobar");
+
+ initUiWithTheme("bar");
+
+ assertThat(ui.getTheme(), is("bar"));
+ }
+
+ @Test
+ public void nullThemeIsSetOnInit() {
+ ui.setTheme("foobar");
+
+ initUiWithTheme(null);
+
+ assertThat(ui.getTheme(), is(nullValue()));
+ }
+}
diff --git a/server/src/test/java/com/vaadin/ui/VerticalSplitPanelTest.java b/server/src/test/java/com/vaadin/ui/VerticalSplitPanelTest.java
new file mode 100644
index 0000000000..c48caf8144
--- /dev/null
+++ b/server/src/test/java/com/vaadin/ui/VerticalSplitPanelTest.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2000-2014 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.ui;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.shared.ui.splitpanel.VerticalSplitPanelState;
+
+public class VerticalSplitPanelTest {
+
+ @Test
+ public void primaryStyleName() {
+ Assert.assertEquals(new VerticalSplitPanelState().primaryStyleName,
+ new VerticalSplitPanel().getPrimaryStyleName());
+ }
+}
diff --git a/server/src/test/java/com/vaadin/ui/declarative/DesignTest.java b/server/src/test/java/com/vaadin/ui/declarative/DesignTest.java
new file mode 100644
index 0000000000..f1d6982992
--- /dev/null
+++ b/server/src/test/java/com/vaadin/ui/declarative/DesignTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2000-2014 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.ui.declarative;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.nio.charset.Charset;
+
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.nodes.Node;
+import org.jsoup.nodes.TextNode;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.ui.Component;
+import com.vaadin.ui.Label;
+
+/**
+ * Tests for {@link Design} declarative support class.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class DesignTest {
+
+ private static Charset CP1251_CHARSET = Charset.forName("cp1251");
+ private static Charset UTF8_CHARSET = Charset.forName("UTF-8");
+
+ private static String NON_ASCII_STRING = "\u043C";
+
+ private static Charset DEFAULT_CHARSET = Charset.defaultCharset();
+
+ @AfterClass
+ public static void restoreCharset() throws NoSuchFieldException,
+ SecurityException, IllegalArgumentException, IllegalAccessException {
+ setCharset(DEFAULT_CHARSET);
+ }
+
+ @Test
+ public void write_cp1251SystemDefaultEncoding_resultEqualsToUtf8Encoding()
+ throws IOException, NoSuchFieldException, SecurityException,
+ IllegalArgumentException, IllegalAccessException {
+ setCp1251Charset();
+ String cp1251Html = getHtml();
+ setUtf8Charset();
+ String utf8Html = getHtml();
+ Assert.assertEquals("Html written with UTF-8 as default encoding "
+ + "differs from html written with cp1251 encoding", cp1251Html,
+ utf8Html);
+ }
+
+ @Test
+ public void write_cp1251SystemDefaultEncoding_writtenLabelHasCorrectValue()
+ throws IOException, NoSuchFieldException, SecurityException,
+ IllegalArgumentException, IllegalAccessException {
+ setCp1251Charset();
+ String cp1251Html = getHtml();
+ Assert.assertEquals("Non ascii string parsed from serialized HTML "
+ + "differs from expected", NON_ASCII_STRING,
+ getHtmlLabelValue(cp1251Html));
+ }
+
+ @Test
+ public void write_utf8SystemDefaultEncoding_writtenLabelHasCorrectValue()
+ throws IOException, NoSuchFieldException, SecurityException,
+ IllegalArgumentException, IllegalAccessException {
+ setUtf8Charset();
+ String utf8 = getHtml();
+ Assert.assertEquals("Non ascii string parsed from serialized HTML "
+ + "differs from expected", NON_ASCII_STRING,
+ getHtmlLabelValue(utf8));
+ }
+
+ private String getHtmlLabelValue(String html) {
+ Document document = Jsoup.parse(html);
+ Element label = document.select("vaadin-label").get(0);
+
+ StringBuilder builder = new StringBuilder();
+ for (Node child : label.childNodes()) {
+ if (child instanceof TextNode) {
+ builder.append(((TextNode) child).getWholeText());
+ }
+ }
+ return builder.toString().trim();
+ }
+
+ private String getHtml() throws IOException {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ Component label = new Label(NON_ASCII_STRING);
+ Design.write(label, out);
+ return out.toString(UTF8_CHARSET.name());
+ }
+
+ private void setCp1251Charset() throws NoSuchFieldException,
+ SecurityException, IllegalArgumentException, IllegalAccessException {
+ setCharset(CP1251_CHARSET);
+ }
+
+ private void setUtf8Charset() throws NoSuchFieldException,
+ SecurityException, IllegalArgumentException, IllegalAccessException {
+ setCharset(UTF8_CHARSET);
+ }
+
+ private static void setCharset(Charset charset)
+ throws NoSuchFieldException, SecurityException,
+ IllegalArgumentException, IllegalAccessException {
+ Field field = Charset.class.getDeclaredField("defaultCharset");
+ field.setAccessible(true);
+ field.set(null, charset);
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/util/CurrentInstanceTest.java b/server/src/test/java/com/vaadin/util/CurrentInstanceTest.java
new file mode 100644
index 0000000000..458e8a2f6c
--- /dev/null
+++ b/server/src/test/java/com/vaadin/util/CurrentInstanceTest.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2000-2014 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.util;
+
+import static org.junit.Assert.assertNull;
+
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Field;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.VaadinService;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.ui.UI;
+
+public class CurrentInstanceTest {
+
+ @Before
+ public void clearExistingThreadLocals() {
+ // Ensure no previous test left some thread locals hanging
+ CurrentInstance.clearAll();
+ }
+
+ @Test
+ public void testInitiallyCleared() throws Exception {
+ assertCleared();
+ }
+
+ @Test
+ public void testClearedAfterRemove() throws Exception {
+ CurrentInstance.set(CurrentInstanceTest.class, this);
+ Assert.assertEquals(this,
+ CurrentInstance.get(CurrentInstanceTest.class));
+ CurrentInstance.set(CurrentInstanceTest.class, null);
+
+ assertCleared();
+ }
+
+ @Test
+ public void testClearedAfterRemoveInheritable() throws Exception {
+ CurrentInstance.clearAll();
+
+ CurrentInstance.setInheritable(CurrentInstanceTest.class, this);
+ Assert.assertEquals(this,
+ CurrentInstance.get(CurrentInstanceTest.class));
+ CurrentInstance.setInheritable(CurrentInstanceTest.class, null);
+
+ assertCleared();
+ }
+
+ @Test
+ public void testInheritableThreadLocal() throws Exception {
+ final AtomicBoolean threadFailed = new AtomicBoolean(true);
+
+ CurrentInstance.setInheritable(CurrentInstanceTest.class, this);
+ Assert.assertEquals(this,
+ CurrentInstance.get(CurrentInstanceTest.class));
+ Thread t = new Thread() {
+ @Override
+ public void run() {
+ Assert.assertEquals(CurrentInstanceTest.this,
+ CurrentInstance.get(CurrentInstanceTest.class));
+ threadFailed.set(false);
+ }
+ };
+ t.start();
+ CurrentInstance.set(CurrentInstanceTest.class, null);
+
+ assertCleared();
+ while (t.isAlive()) {
+ Thread.sleep(1000);
+ }
+ Assert.assertFalse("Thread failed", threadFailed.get());
+
+ }
+
+ @Test
+ public void testClearedAfterRemoveInSeparateThread() throws Exception {
+ final AtomicBoolean threadFailed = new AtomicBoolean(true);
+
+ CurrentInstance.setInheritable(CurrentInstanceTest.class, this);
+ Assert.assertEquals(this,
+ CurrentInstance.get(CurrentInstanceTest.class));
+ Thread t = new Thread() {
+ @Override
+ public void run() {
+ try {
+ Assert.assertEquals(CurrentInstanceTest.this,
+ CurrentInstance.get(CurrentInstanceTest.class));
+ CurrentInstance.set(CurrentInstanceTest.class, null);
+ assertCleared();
+
+ threadFailed.set(false);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ };
+ t.start();
+
+ while (t.isAlive()) {
+ Thread.sleep(1000);
+ }
+ Assert.assertFalse("Thread failed", threadFailed.get());
+
+ // Clearing the threadlocal in the thread should not have cleared it
+ // here
+ Assert.assertEquals(this,
+ CurrentInstance.get(CurrentInstanceTest.class));
+
+ // Clearing the only remaining threadlocal should free all memory
+ CurrentInstance.set(CurrentInstanceTest.class, null);
+ assertCleared();
+ }
+
+ @Test
+ public void testClearedWithClearAll() throws Exception {
+ CurrentInstance.set(CurrentInstanceTest.class, this);
+ Assert.assertEquals(this,
+ CurrentInstance.get(CurrentInstanceTest.class));
+ CurrentInstance.clearAll();
+
+ assertCleared();
+ }
+
+ private void assertCleared() throws SecurityException,
+ NoSuchFieldException, IllegalAccessException {
+ Assert.assertNull(getInternalCurrentInstanceVariable().get());
+ }
+
+ private InheritableThreadLocal<Map<Class<?>, CurrentInstance>> getInternalCurrentInstanceVariable()
+ throws SecurityException, NoSuchFieldException,
+ IllegalAccessException {
+ Field f = CurrentInstance.class.getDeclaredField("instances");
+ f.setAccessible(true);
+ return (InheritableThreadLocal<Map<Class<?>, CurrentInstance>>) f
+ .get(null);
+ }
+
+ public void testInheritedClearedAfterRemove() {
+
+ }
+
+ private static class UIStoredInCurrentInstance extends UI {
+ @Override
+ protected void init(VaadinRequest request) {
+ }
+ }
+
+ private static class SessionStoredInCurrentInstance extends VaadinSession {
+ public SessionStoredInCurrentInstance(VaadinService service) {
+ super(service);
+ }
+ }
+
+ @Test
+ public void testRestoringNullUIWorks() throws Exception {
+ // First make sure current instance is empty
+ CurrentInstance.clearAll();
+
+ // Then store a new UI in there
+ Map<Class<?>, CurrentInstance> old = CurrentInstance
+ .setCurrent(new UIStoredInCurrentInstance());
+
+ // Restore the old values and assert that the UI is null again
+ CurrentInstance.restoreInstances(old);
+ assertNull(CurrentInstance.get(UI.class));
+ }
+
+ @Test
+ public void testRestoringNullSessionWorks() throws Exception {
+ // First make sure current instance is empty
+ CurrentInstance.clearAll();
+
+ // Then store a new session in there
+ Map<Class<?>, CurrentInstance> old = CurrentInstance
+ .setCurrent(new SessionStoredInCurrentInstance(EasyMock
+ .createNiceMock(VaadinService.class)));
+
+ // Restore the old values and assert that the session is null again
+ CurrentInstance.restoreInstances(old);
+ assertNull(CurrentInstance.get(VaadinSession.class));
+ assertNull(CurrentInstance.get(VaadinService.class));
+ }
+
+ @Test
+ public void testRestoreWithGarbageCollectedValue()
+ throws InterruptedException {
+ VaadinSession session1 = new VaadinSession(null) {
+ @Override
+ public String toString() {
+ return "First session";
+ }
+ };
+ VaadinSession session2 = new VaadinSession(null) {
+ @Override
+ public String toString() {
+ return "Second session";
+ }
+ };
+
+ VaadinSession.setCurrent(session1);
+ Map<Class<?>, CurrentInstance> previous = CurrentInstance
+ .setCurrent(session2);
+
+ // Use weak ref to verify object is collected
+ WeakReference<VaadinSession> ref = new WeakReference<VaadinSession>(
+ session1);
+
+ session1 = null;
+ waitUntilGarbageCollected(ref);
+
+ CurrentInstance.restoreInstances(previous);
+
+ Assert.assertNull(VaadinSession.getCurrent());
+ }
+
+ private static void waitUntilGarbageCollected(WeakReference<?> ref)
+ throws InterruptedException {
+ for (int i = 0; i < 50; i++) {
+ System.gc();
+ if (ref.get() == null) {
+ return;
+ }
+ Thread.sleep(100);
+ }
+ Assert.fail("Value was not garbage collected.");
+ }
+}
diff --git a/server/src/test/java/com/vaadin/util/ReflectToolsGetFieldValueByTypeTest.java b/server/src/test/java/com/vaadin/util/ReflectToolsGetFieldValueByTypeTest.java
new file mode 100644
index 0000000000..67796314c0
--- /dev/null
+++ b/server/src/test/java/com/vaadin/util/ReflectToolsGetFieldValueByTypeTest.java
@@ -0,0 +1,63 @@
+package com.vaadin.util;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+
+public class ReflectToolsGetFieldValueByTypeTest {
+ @Test
+ public void getFieldValue() {
+ class MyClass {
+ public Integer getField() {
+ return 1;
+ }
+
+ public void setField(Integer i) {
+ }
+
+ }
+ class MySubClass extends MyClass {
+ public String field = "Hello";
+ }
+
+ MySubClass myInstance = new MySubClass();
+
+ java.lang.reflect.Field memberField;
+ Object fieldValue = new Boolean(false);
+ try {
+ memberField = myInstance.getClass().getField("field");
+ // Should get a String value. Without the third parameter (calling
+ // ReflectTools.getJavaFieldValue(Object object, Field field)) would
+ // get an Integer value
+ fieldValue = ReflectTools.getJavaFieldValue(myInstance,
+ memberField, String.class);
+ } catch (Exception e) {
+ }
+ assertTrue(fieldValue instanceof String);
+
+ }
+
+ @Test
+ public void getFieldValueViaGetter() {
+ class MyClass {
+ public Integer field = 1;
+ }
+ class MySubClass extends MyClass {
+ public String field = "Hello";
+ }
+
+ MySubClass myInstance = new MySubClass();
+
+ java.lang.reflect.Field memberField;
+ try {
+ memberField = myInstance.getClass().getField("field");
+ // Should throw an IllegalArgument exception as the mySubClass class
+ // doesn't have an Integer field.
+ ReflectTools.getJavaFieldValue(myInstance, memberField,
+ Integer.class);
+ fail("Previous method call should have thrown an exception");
+ } catch (Exception e) {
+ }
+ }
+}
diff --git a/server/src/test/java/com/vaadin/util/ReflectToolsGetPrimitiveFieldValueTest.java b/server/src/test/java/com/vaadin/util/ReflectToolsGetPrimitiveFieldValueTest.java
new file mode 100644
index 0000000000..40e8f05e1e
--- /dev/null
+++ b/server/src/test/java/com/vaadin/util/ReflectToolsGetPrimitiveFieldValueTest.java
@@ -0,0 +1,26 @@
+package com.vaadin.util;
+
+import static org.junit.Assert.assertFalse;
+
+import org.junit.Test;
+
+public class ReflectToolsGetPrimitiveFieldValueTest {
+ @Test
+ public void getFieldValueViaGetter() {
+ class MyClass {
+ public int field = 1;
+ }
+
+ MyClass myInstance = new MyClass();
+
+ java.lang.reflect.Field memberField;
+ Object fieldValue = new Boolean(false);
+ try {
+ memberField = myInstance.getClass().getField("field");
+ fieldValue = ReflectTools
+ .getJavaFieldValue(myInstance, memberField);
+ } catch (Exception e) {
+ }
+ assertFalse(fieldValue instanceof Boolean);
+ }
+}
diff --git a/server/src/test/resources/com/vaadin/tests/design/DesignReadInConstructor.html b/server/src/test/resources/com/vaadin/tests/design/DesignReadInConstructor.html
new file mode 100644
index 0000000000..72f65d744a
--- /dev/null
+++ b/server/src/test/resources/com/vaadin/tests/design/DesignReadInConstructor.html
@@ -0,0 +1,5 @@
+<vaadin-vertical-layout>
+ <vaadin-text-field caption="First name" />
+ <vaadin-text-field caption="Last name" />
+ <vaadin-button>OK!</vaadin-button>
+</vaadin-vertical-layout> \ No newline at end of file
diff --git a/server/src/test/resources/com/vaadin/tests/design/MyVerticalLayout.html b/server/src/test/resources/com/vaadin/tests/design/MyVerticalLayout.html
new file mode 100644
index 0000000000..f6f4d98259
--- /dev/null
+++ b/server/src/test/resources/com/vaadin/tests/design/MyVerticalLayout.html
@@ -0,0 +1,4 @@
+<v-vertical-layout>
+ <v-label _id="caption" />
+ <v-text-field id="description" />
+</v-vertical-layout> \ No newline at end of file
diff --git a/server/src/test/resources/com/vaadin/tests/design/all-components-legacy.html b/server/src/test/resources/com/vaadin/tests/design/all-components-legacy.html
new file mode 100644
index 0000000000..39aecb6db1
--- /dev/null
+++ b/server/src/test/resources/com/vaadin/tests/design/all-components-legacy.html
@@ -0,0 +1,122 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta name="package-mapping" content="my:com.addon.mypackage"/>
+ </head>
+ <body>
+ <v-vertical-layout>
+ <!-- abstract component -->
+ <v-button primary-style-name="button" id="foo" style-name="red" caption="Some caption" icon="vaadin://themes/runo/icons/16/ok.png" description="My tooltip" error="Something went wrong" locale="en_US"></v-button>
+
+ <!-- absolute layout -->
+ <v-absolute-layout>
+ <v-button :top="100px" :left="0px" :z-index=21>OK</v-button>
+ <v-button :bottom="0px" :right="0px">Cancel</v-button>
+ </v-absolute-layout>
+
+ <!-- vertical layout -->
+ <v-vertical-layout spacing margin>
+ <v-button :top>OK</v-button>
+ <v-table size-full :expand=1 />
+ </v-vertical-layout>
+
+ <!-- horizontal layout -->
+ <v-horizontal-layout spacing margin>
+ <v-button :top>OK</v-button>
+ <v-table size-full :expand=1 />
+ </v-horizontal-layout>
+
+ <!-- form layout -->
+ <v-form-layout spacing margin>
+ <v-button :top>OK</v-button>
+ <v-table size-full :expand=1 />
+ </v-form-layout>
+
+ <!-- css layout -->
+ <v-css-layout>
+ <v-button>OK</v-button>
+ <v-table size-full />
+ </v-css-layout>
+
+ <!-- panel -->
+ <v-panel caption="Hello world" tabindex=2 scroll-left="10" scroll-top="10">
+ <v-table size-full />
+ </v-panel>
+
+ <!-- abstract field -->
+ <v-text-field buffered validation-visible=false invalid-committed invalid-allowed=false required required-error="This is a required field" conversion-error="Input {0} cannot be parsed" tabindex=3 readonly />
+ <!-- abstract text field, text field -->
+ <v-text-field null-representation="" null-setting-allowed maxlength=10 columns=5 input-prompt="Please enter a value" text-change-event-mode="eager" text-change-timeout=2 value="foo" />
+ <!-- password field -->
+ <v-password-field null-representation="" null-setting-allowed maxlength=10 columns=5 input-prompt="Please enter a value" text-change-event-mode="eager" text-change-timeout=2 value="foo" />
+ <!-- text area -->
+ <v-text-area rows=5 wordwrap=false >test value</v-text-area>
+ <!-- button -->
+ <v-button click-shortcut="ctrl-shift-o" disable-on-click tabindex=1 icon="http://vaadin.com/image.png" icon-alt="ok" plain-text>OK</v-button>
+ <!-- native button -->
+ <v-button click-shortcut="ctrl-shift-o" disable-on-click tabindex=1 icon="http://vaadin.com/image.png" icon-alt="ok" plain-text>OK</v-button>
+
+ <!-- tabsheet -->
+ <v-tab-sheet tabindex=5>
+ <tab visible=false closable caption="My first tab">
+ <v-vertical-layout>
+ <v-text-field/>
+ </v-vertical-layout>
+ </tab>
+ <tab enabled=false caption="Disabled second tab">
+ <v-button>In disabled tab - can’t be shown by default</v-button>
+ </tab>
+ <tab icon="theme://../runo/icons/16/ok.png" icon-alt="Ok png from Runo - very helpful" description="Click to show a text field" style-name="red" id="uniqueDomId">
+ <v-text-field input-prompt="Icon only in tab" />
+ </tab>
+ </v-tab-sheet>
+
+ <!-- accordion -->
+ <v-accordion tabindex=5>
+ <tab visible=false closable caption="My first tab">
+ <v-vertical-layout>
+ <v-text-field/>
+ </v-vertical-layout>
+ </tab>
+ <tab enabled=false caption="Disabled second tab">
+ <v-button>In disabled tab - can’t be shown by default</v-button>
+ </tab>
+ <tab icon="theme://../runo/icons/16/ok.png" icon-alt="Ok png from Runo - very helpful" description="Click to show a text field" style-name="red" id="uniqueDomId">
+ <v-text-field input-prompt="Icon only in tab" />
+ </tab>
+ </v-accordion>
+
+ <!-- abstract split panel -->
+ <v-horizontal-split-panel split-position="20px" min-split-position="0px" max-split-position="50px" locked>
+ <v-button>First slot</v-button>
+ </v-horizontal-split-panel>
+ <v-vertical-split-panel split-position="25%" reversed>
+ <v-button :second>Second slot</v-button>
+ </v-vertical-split-panel>
+ <v-horizontal-split-panel split-position="25%" reversed>
+ <v-button>First slot</v-button>
+ <v-button>Second slot</v-button>
+ </v-horizontal-split-panel>
+
+ <!-- label -->
+ <v-label>Hello world!</v-label>
+ <v-label>This is <b><u>Rich</u></b> content!</v-label>
+ <v-label plain-text>This is only <b>text</b> and will contain visible tags</v-label>
+
+ <!-- checkbox -->
+ <v-check-box checked/>
+
+ <!-- abstract select -->
+ <v-list-select new-items-allowed multi-select
+ item-caption-mode="index"
+ null-selection-allowed=false>
+ </v-list-select>
+
+ <v-combo-box>
+ <option icon="http://something/my-icon.png">First value</option>
+ <option>Second value</option>
+ </v-combo-box>
+
+ </v-vertical-layout>
+ </body>
+</html>
diff --git a/server/src/test/resources/com/vaadin/tests/design/all-components.html b/server/src/test/resources/com/vaadin/tests/design/all-components.html
new file mode 100644
index 0000000000..6507188cd7
--- /dev/null
+++ b/server/src/test/resources/com/vaadin/tests/design/all-components.html
@@ -0,0 +1,122 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta name="package-mapping" content="my:com.addon.mypackage"/>
+ </head>
+ <body>
+ <vaadin-vertical-layout>
+ <!-- abstract component -->
+ <vaadin-button primary-style-name="button" id="foo" style-name="red" caption="Some caption" icon="vaadin://themes/runo/icons/16/ok.png" description="My tooltip" error="Something went wrong" locale="en_US"></vaadin-button>
+
+ <!-- absolute layout -->
+ <vaadin-absolute-layout>
+ <vaadin-button :top="100px" :left="0px" :z-index=21>OK</vaadin-button>
+ <vaadin-button :bottom="0px" :right="0px">Cancel</vaadin-button>
+ </vaadin-absolute-layout>
+
+ <!-- vertical layout -->
+ <vaadin-vertical-layout spacing margin>
+ <vaadin-button :top>OK</vaadin-button>
+ <vaadin-table size-full :expand=1 />
+ </vaadin-vertical-layout>
+
+ <!-- horizontal layout -->
+ <vaadin-horizontal-layout spacing margin>
+ <vaadin-button :top>OK</vaadin-button>
+ <vaadin-table size-full :expand=1 />
+ </vaadin-horizontal-layout>
+
+ <!-- form layout -->
+ <vaadin-form-layout spacing margin>
+ <vaadin-button :top>OK</vaadin-button>
+ <vaadin-table size-full :expand=1 />
+ </vaadin-form-layout>
+
+ <!-- css layout -->
+ <vaadin-css-layout>
+ <vaadin-button>OK</vaadin-button>
+ <vaadin-table size-full />
+ </vaadin-css-layout>
+
+ <!-- panel -->
+ <vaadin-panel caption="Hello world" tabindex=2 scroll-left="10" scroll-top="10">
+ <vaadin-table size-full />
+ </vaadin-panel>
+
+ <!-- abstract field -->
+ <vaadin-text-field buffered validation-visible=false invalid-committed invalid-allowed=false required required-error="This is a required field" conversion-error="Input {0} cannot be parsed" tabindex=3 readonly />
+ <!-- abstract text field, text field -->
+ <vaadin-text-field null-representation="" null-setting-allowed maxlength=10 columns=5 input-prompt="Please enter a value" text-change-event-mode="eager" text-change-timeout=2 value="foo" />
+ <!-- password field -->
+ <vaadin-password-field null-representation="" null-setting-allowed maxlength=10 columns=5 input-prompt="Please enter a value" text-change-event-mode="eager" text-change-timeout=2 value="foo" />
+ <!-- text area -->
+ <vaadin-text-area rows=5 wordwrap=false >test value</vaadin-text-area>
+ <!-- button -->
+ <vaadin-button click-shortcut="ctrl-shift-o" disable-on-click tabindex=1 icon="http://vaadin.com/image.png" icon-alt="ok" plain-text>OK</vaadin-button>
+ <!-- native button -->
+ <vaadin-button click-shortcut="ctrl-shift-o" disable-on-click tabindex=1 icon="http://vaadin.com/image.png" icon-alt="ok" plain-text>OK</vaadin-button>
+
+ <!-- tabsheet -->
+ <vaadin-tab-sheet tabindex=5>
+ <tab visible=false closable caption="My first tab">
+ <vaadin-vertical-layout>
+ <vaadin-text-field/>
+ </vaadin-vertical-layout>
+ </tab>
+ <tab enabled=false caption="Disabled second tab">
+ <vaadin-button>In disabled tab - can’t be shown by default</vaadin-button>
+ </tab>
+ <tab icon="theme://../runo/icons/16/ok.png" icon-alt="Ok png from Runo - very helpful" description="Click to show a text field" style-name="red" id="uniqueDomId">
+ <vaadin-text-field input-prompt="Icon only in tab" />
+ </tab>
+ </vaadin-tab-sheet>
+
+ <!-- accordion -->
+ <vaadin-accordion tabindex=5>
+ <tab visible=false closable caption="My first tab">
+ <vaadin-vertical-layout>
+ <vaadin-text-field/>
+ </vaadin-vertical-layout>
+ </tab>
+ <tab enabled=false caption="Disabled second tab">
+ <vaadin-button>In disabled tab - can’t be shown by default</vaadin-button>
+ </tab>
+ <tab icon="theme://../runo/icons/16/ok.png" icon-alt="Ok png from Runo - very helpful" description="Click to show a text field" style-name="red" id="uniqueDomId">
+ <vaadin-text-field input-prompt="Icon only in tab" />
+ </tab>
+ </vaadin-accordion>
+
+ <!-- abstract split panel -->
+ <vaadin-horizontal-split-panel split-position="20px" min-split-position="0px" max-split-position="50px" locked>
+ <vaadin-button>First slot</vaadin-button>
+ </vaadin-horizontal-split-panel>
+ <vaadin-vertical-split-panel split-position="25%" reversed>
+ <vaadin-button :second>Second slot</vaadin-button>
+ </vaadin-vertical-split-panel>
+ <vaadin-horizontal-split-panel split-position="25%" reversed>
+ <vaadin-button>First slot</vaadin-button>
+ <vaadin-button>Second slot</vaadin-button>
+ </vaadin-horizontal-split-panel>
+
+ <!-- label -->
+ <vaadin-label>Hello world!</vaadin-label>
+ <vaadin-label>This is <b><u>Rich</u></b> content!</vaadin-label>
+ <vaadin-label plain-text>This is only <b>text</b> and will contain visible tags</vaadin-label>
+
+ <!-- checkbox -->
+ <vaadin-check-box checked/>
+
+ <!-- abstract select -->
+ <vaadin-list-select new-items-allowed multi-select
+ item-caption-mode="index"
+ null-selection-allowed=false>
+ </vaadin-list-select>
+
+ <vaadin-combo-box>
+ <option icon="http://something/my-icon.png">First value</option>
+ <option>Second value</option>
+ </vaadin-combo-box>
+
+ </vaadin-vertical-layout>
+ </body>
+</html>
diff --git a/server/src/test/resources/com/vaadin/tests/design/designroot/DesignWithEmptyAnnotation.html b/server/src/test/resources/com/vaadin/tests/design/designroot/DesignWithEmptyAnnotation.html
new file mode 100644
index 0000000000..3e7977f568
--- /dev/null
+++ b/server/src/test/resources/com/vaadin/tests/design/designroot/DesignWithEmptyAnnotation.html
@@ -0,0 +1,5 @@
+<vaadin-vertical-layout>
+ <vaadin-button>OK</vaadin-button>
+ <vaadin-button>Cancel</vaadin-button>
+ <vaadin-label caption="preInitializedField">a Label that should not override pre initalized field<vaadin-label/>
+</vaadin-vertical-layout> \ No newline at end of file
diff --git a/server/src/test/resources/com/vaadin/tests/design/duplicate-ids.html b/server/src/test/resources/com/vaadin/tests/design/duplicate-ids.html
new file mode 100644
index 0000000000..984bb1e047
--- /dev/null
+++ b/server/src/test/resources/com/vaadin/tests/design/duplicate-ids.html
@@ -0,0 +1,4 @@
+<vaadin-vertical-layout>
+ <vaadin-label id="foo"/>
+ <vaadin-label id="foo"/>
+</vaadin-vertical-layout> \ No newline at end of file
diff --git a/server/src/test/resources/com/vaadin/tests/design/duplicate-local-ids.html b/server/src/test/resources/com/vaadin/tests/design/duplicate-local-ids.html
new file mode 100644
index 0000000000..e8a698a39f
--- /dev/null
+++ b/server/src/test/resources/com/vaadin/tests/design/duplicate-local-ids.html
@@ -0,0 +1,4 @@
+<vaadin-vertical-layout>
+ <vaadin-label _id="foo"/>
+ <vaadin-label _id="foo"/>
+</vaadin-vertical-layout> \ No newline at end of file
diff --git a/server/src/test/resources/com/vaadin/tests/design/local-ids.html b/server/src/test/resources/com/vaadin/tests/design/local-ids.html
new file mode 100644
index 0000000000..76ff642ee0
--- /dev/null
+++ b/server/src/test/resources/com/vaadin/tests/design/local-ids.html
@@ -0,0 +1,4 @@
+<vaadin-vertical-layout>
+ <vaadin-text-field caption="Enter your name" _id="foo"/>
+ <vaadin-button _id="bar">Say hello</vaadin-button>
+</vaadin-vertical-layout>
diff --git a/server/src/test/resources/com/vaadin/tests/design/nested/mychilddesign.html b/server/src/test/resources/com/vaadin/tests/design/nested/mychilddesign.html
new file mode 100644
index 0000000000..0d2613539b
--- /dev/null
+++ b/server/src/test/resources/com/vaadin/tests/design/nested/mychilddesign.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta name="package-mapping" content="x:com.vaadin.tests.design.nested"/>
+ </head>
+ <body>
+ <vaadin-horizontal-layout caption="Default caption for child design">
+ <vaadin-label _id="childLabel">test content</vaadin-label>
+ <!-- Test some custom component in child template -->
+ <x-my-child-design-custom-component _id="childCustomComponent">custom content</x-my-child-design-custom-component>
+ </vaadin-horizontal-layout>
+</body> \ No newline at end of file
diff --git a/server/src/test/resources/com/vaadin/tests/design/nested/mydesignroot.html b/server/src/test/resources/com/vaadin/tests/design/nested/mydesignroot.html
new file mode 100644
index 0000000000..6bf38db8f6
--- /dev/null
+++ b/server/src/test/resources/com/vaadin/tests/design/nested/mydesignroot.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta name="package-mapping" content="x:com.vaadin.tests.design.nested"/>
+ </head>
+ <body>
+ <vaadin-vertical-layout caption="root caption">
+ <x-my-extended-child-design _id="childDesign" caption="child caption"/>
+ </vaadin-vertical-layout>
+ </body> \ No newline at end of file
diff --git a/server/src/test/resources/com/vaadin/tests/design/testFile-legacy.html b/server/src/test/resources/com/vaadin/tests/design/testFile-legacy.html
new file mode 100644
index 0000000000..79ae1e9eaf
--- /dev/null
+++ b/server/src/test/resources/com/vaadin/tests/design/testFile-legacy.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta name="package-mapping" content="my:com.addon.mypackage"/>
+ </head>
+ <body>
+ <v-vertical-layout width="500px">
+ <v-horizontal-layout>
+ <v-label plain-text caption="FooBar"></v-label>
+ <v-native-button _id=firstButton>Native click me</v-native-button>
+ <v-native-button id = secondButton _id="localID">Another button</v-native-button>
+ <v-native-button>Yet another button</v-native-button>
+ <v-button plain-text width = "150px">Click me</v-button>
+ </v-horizontal-layout>
+ <v-text-field caption = "Text input"/>
+ <v-text-area caption = "Text area" height="200px" width="300px"/>
+ </v-vertical-layout>
+ </body>
+</html> \ No newline at end of file
diff --git a/server/src/test/resources/com/vaadin/tests/design/testFile.html b/server/src/test/resources/com/vaadin/tests/design/testFile.html
new file mode 100644
index 0000000000..ab23d1d1b2
--- /dev/null
+++ b/server/src/test/resources/com/vaadin/tests/design/testFile.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta name="package-mapping" content="my:com.addon.mypackage"/>
+ </head>
+ <body>
+ <vaadin-vertical-layout width="500px">
+ <vaadin-horizontal-layout>
+ <vaadin-label plain-text caption="FooBar"></vaadin-label>
+ <vaadin-native-button _id=firstButton>Native click me</vaadin-native-button>
+ <vaadin-native-button id = secondButton _id="localID">Another button</vaadin-native-button>
+ <vaadin-native-button>Yet another button</vaadin-native-button>
+ <vaadin-button plain-text width = "150px">Click me</vaadin-button>
+ </vaadin-horizontal-layout>
+ <vaadin-text-field caption = "Text input"/>
+ <vaadin-text-area caption = "Text area" height="200px" width="300px"/>
+ </vaadin-vertical-layout>
+ </body>
+</html> \ No newline at end of file
diff --git a/server/src/test/resources/com/vaadin/tests/design/verticallayout-one-child.html b/server/src/test/resources/com/vaadin/tests/design/verticallayout-one-child.html
new file mode 100644
index 0000000000..cf3dc65e48
--- /dev/null
+++ b/server/src/test/resources/com/vaadin/tests/design/verticallayout-one-child.html
@@ -0,0 +1,3 @@
+<vaadin-vertical-layout>
+ <vaadin-button>OK</vaadin-button>
+</vaadin-vertical-layout>
diff --git a/server/src/test/resources/com/vaadin/tests/design/verticallayout-two-children.html b/server/src/test/resources/com/vaadin/tests/design/verticallayout-two-children.html
new file mode 100644
index 0000000000..dcf71a190b
--- /dev/null
+++ b/server/src/test/resources/com/vaadin/tests/design/verticallayout-two-children.html
@@ -0,0 +1,4 @@
+<vaadin-vertical-layout>
+ <vaadin-text-field caption="Enter your name" />
+ <vaadin-button>Say hello</vaadin-button>
+</vaadin-vertical-layout>
diff --git a/server/src/test/resources/com/vaadin/tests/styles.scss b/server/src/test/resources/com/vaadin/tests/styles.scss
new file mode 100644
index 0000000000..d574243969
--- /dev/null
+++ b/server/src/test/resources/com/vaadin/tests/styles.scss
@@ -0,0 +1,5 @@
+@import "../../../../../../WebContent/VAADIN/themes/valo/valo";
+
+.my-label {
+ @include transition-property (transform);
+} \ No newline at end of file