2 * Copyright 2000-2016 Vaadin Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
16 package com.vaadin.tests.server.component.abstractlisting;
19 import java.lang.reflect.InvocationTargetException;
20 import java.lang.reflect.Method;
21 import java.util.Arrays;
22 import java.util.List;
23 import java.util.function.Consumer;
25 import org.junit.Assert;
26 import org.junit.Test;
28 import com.vaadin.data.provider.Query;
29 import com.vaadin.server.ExternalResource;
30 import com.vaadin.server.FileResource;
31 import com.vaadin.server.Resource;
32 import com.vaadin.server.SerializablePredicate;
33 import com.vaadin.server.ThemeResource;
34 import com.vaadin.tests.design.DeclarativeTestBaseBase;
35 import com.vaadin.tests.server.component.abstractcomponent.AbstractComponentDeclarativeTestBase;
36 import com.vaadin.ui.AbstractComponent;
37 import com.vaadin.ui.AbstractListing;
38 import com.vaadin.ui.IconGenerator;
39 import com.vaadin.ui.ItemCaptionGenerator;
40 import com.vaadin.ui.declarative.DesignContext;
43 * {@link AbstractListing} component declarative test.
45 * Test ignores comparison for {@link ItemCaptionGenerator},
46 * {@link IconGenerator} and {@link SerializablePredicate} "properties" since
47 * they are functions and it doesn't matter which implementation is chosen. But
48 * test checks generated item captions, item icon generation and enabled items
49 * generations if they are available in the component as public methods.
51 * Common {@link AbstractComponent} properties are tested in
52 * {@link AbstractComponentDeclarativeTestBase}
54 * @see AbstractComponentDeclarativeTestBase
62 @SuppressWarnings({ "unchecked", "rawtypes" })
63 public abstract class AbstractListingDeclarativeTest<T extends AbstractListing>
64 extends AbstractComponentDeclarativeTestBase<T> {
66 private static final String EXTERNAL_URL = "http://example.com/example.gif";
68 private static final String FILE_PATH = "img/example.gif";
70 private static final String THEME_PATH = "example.gif";
73 public abstract void dataSerialization() throws InstantiationException,
74 IllegalAccessException, InvocationTargetException;
77 public abstract void valueSerialization() throws InstantiationException,
78 IllegalAccessException, InvocationTargetException;
81 public void itemIconsSerialization() throws InstantiationException,
82 IllegalAccessException, InvocationTargetException {
83 T component = getComponentClass().newInstance();
84 Method setIconGenerator = getIconGeneratorMethod(component);
85 if (setIconGenerator == null) {
89 List<String> items = Arrays.asList("foo", "bar", "foobar", "barfoo");
91 String design = String.format(
92 "<%s>\n" + "<option item='foo' icon='%s'>foo</option>\n"
93 + "<option item='bar' icon='%s'>bar</option>"
94 + "<option item='foobar' icon='theme://%s'>foobar</option>"
95 + "<option item='barfoo'>barfoo</option>" + "</%s>",
96 getComponentTag(), EXTERNAL_URL, FILE_PATH, THEME_PATH,
99 component.setItems(items);
100 IconGenerator generator = item -> generateIcons(item, items);
101 setIconGenerator.invoke(component, generator);
103 testRead(design, component);
104 testWrite(design, component, true);
108 public void enabledItemsSerialization() throws InstantiationException,
109 IllegalAccessException, InvocationTargetException {
110 T component = getComponentClass().newInstance();
111 Method setEnabledITemsGenerator = getEnabledItemsProviderMethod(
113 if (setEnabledITemsGenerator == null) {
117 List<String> items = Arrays.asList("foo", "bar", "foobar");
119 String design = String.format(
120 "<%s>\n" + "<option item='foo'>foo</option>\n"
121 + "<option item='bar' disabled>bar</option>"
122 + "<option item='foobar'>foobar</option>",
123 getComponentTag(), getComponentTag());
125 component.setItems(items);
126 SerializablePredicate predicate = item -> !item.equals("bar");
127 setEnabledITemsGenerator.invoke(component, predicate);
129 testRead(design, component);
130 testWrite(design, component, true);
134 public abstract void readOnlySelection() throws InstantiationException,
135 IllegalAccessException, InvocationTargetException;
138 protected boolean acceptProperty(Class<?> clazz, Method readMethod,
139 Method writeMethod) {
140 if (readMethod != null) {
141 Class<?> returnType = readMethod.getReturnType();
142 if (ItemCaptionGenerator.class.equals(returnType)
143 || IconGenerator.class.equals(returnType)
144 || SerializablePredicate.class.equals(returnType)) {
148 return super.acceptProperty(clazz, readMethod, writeMethod);
151 public DesignContext readComponentAndCompare(String design, T expected,
152 Consumer<DesignContext> configureContext) {
153 DesignContext context = super.readComponentAndCompare(design, expected);
154 configureContext.accept(context);
155 T read = (T) context.getRootComponent();
156 testReadData(design, expected, read, context);
160 public T testRead(String design, T expected, boolean testWrite) {
161 T read = testRead(design, expected);
163 DesignContext context = new DesignContext();
164 context.setShouldWriteDataDelegate(
165 DeclarativeTestBaseBase.ALWAYS_WRITE_DATA);
166 testReadData(design, expected, read, context);
171 private void testReadData(String design, T expected, T read,
172 DesignContext context) {
174 read.getDataCommunicator().getDataProvider()
175 .size(new Query<>()),
176 expected.getDataCommunicator().getDataProvider()
177 .size(new Query<>()));
178 testWrite(read, design, context);
181 private Method getIconGeneratorMethod(T component)
182 throws IllegalAccessException, InvocationTargetException {
184 return component.getClass().getMethod("setItemIconGenerator",
185 new Class[] { IconGenerator.class });
186 } catch (NoSuchMethodException ignore) {
187 // ignore if there is no such method
192 private Method getEnabledItemsProviderMethod(T component)
193 throws IllegalAccessException, InvocationTargetException {
195 return component.getClass().getMethod("setItemEnabledProvider",
196 new Class[] { SerializablePredicate.class });
197 } catch (NoSuchMethodException ignore) {
198 // ignore if there is no such method
203 private Resource generateIcons(Object item, List<String> items) {
204 int index = items.indexOf(item);
207 return new ExternalResource(EXTERNAL_URL);
209 return new FileResource(new File(FILE_PATH));
211 return new ThemeResource(THEME_PATH);