diff options
Diffstat (limited to 'server/src')
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 Binary files differindex 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 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 Binary files differindex 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 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¶m2=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¶m2=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¶m2=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\">> One</option>" + + " <option>> 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("> 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\"><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); + } + + 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\">> 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>> One</vaadin-button>"; + String expectedCaptionHtml = "> 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("& Test"); + read.setHtmlContentAllowed(true); + Element root = new Element(Tag.valueOf("vaadin-button"), ""); + read.writeDesign(root, new DesignContext()); + assertEquals("& Test", root.html()); + + read.setHtmlContentAllowed(false); + root = new Element(Tag.valueOf("vaadin-button"), ""); + read.writeDesign(root, new DesignContext()); + assertEquals("&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\">> Test</th></tr>" + + "</thead>" + + "<tfoot>" + + " <tr><td plain-text=\"true\">> 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 = "> 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("& Test"); + footer.getCell("test").setText("& Test"); + + Element 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()); + + header = grid.addHeaderRowAt(0); + footer = grid.addFooterRowAt(0); + + // entities should not be encoded, this is already given as HTML + header.getCell("test").setHtml("& Test"); + footer.getCell("test").setHtml("& Test"); + + root = new Element(Tag.valueOf("vaadin-grid"), ""); + grid.writeDesign(root, new DesignContext()); + + Assert.assertEquals("& Test", root.getElementsByTag("th").get(0) + .html()); + Assert.assertEquals("& 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>&Test</tr></td>" + + "</tbody>" + + "</table></vaadin-grid>"; + + Grid read = read(design); + Container cds = read.getContainerDataSource(); + Assert.assertEquals("&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 <b>text</b>" + + " 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\">> Test</vaadin-label>"; + Label read = read(design); + Assert.assertEquals("> Test", read.getValue()); + + design = design.replace("plain-text=\"true\"", ""); + read = read(design); + Assert.assertEquals("> Test", read.getValue()); + + Label label = new Label("& Test"); + label.setContentMode(ContentMode.TEXT); + + Element root = new Element(Tag.valueOf("vaadin-label"), ""); + label.writeDesign(root, new DesignContext()); + Assert.assertEquals("&amp; Test", root.html()); + + label.setContentMode(ContentMode.HTML); + root = new Element(Tag.valueOf("vaadin-label"), ""); + label.writeDesign(root, new DesignContext()); + Assert.assertEquals("& 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>& Test</th></tr>" + + " </thead>" + + " <tbody>" + + " <tr item-id=\"test\"><td>& Test</tr>" + + " </tbody>" + + " <tfoot>" + + " <tr><td>& Test</td></tr>" + + " </tfoot>" + + "</table>" + + "</v-table>"; + Table read = read(design); + + Assert.assertEquals("& Test", + read.getContainerProperty("test", "test").getValue()); + Assert.assertEquals("& Test", read.getColumnHeader("test")); + Assert.assertEquals("& Test", read.getColumnFooter("test")); + } +} diff --git a/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>& Test</vaadin-text-area>"; + TextArea read = read(design); + Assert.assertEquals("& Test", read.getValue()); + + read.setValue("& Test"); + + DesignContext dc = new DesignContext(); + Element root = new Element(Tag.valueOf("vaadin-text-area"), ""); + read.writeDesign(root, dc); + + Assert.assertEquals("&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 |