]> source.dussan.org Git - vaadin-framework.git/blob
05e31fc0c1644f9edb8f0533742bfb1a635b57ba
[vaadin-framework.git] /
1 /*
2  * Copyright 2000-2016 Vaadin Ltd.
3  *
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
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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
14  * the License.
15  */
16 package com.vaadin.tests.server.component.abstractlisting;
17
18 import java.io.File;
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;
24
25 import org.junit.Assert;
26 import org.junit.Test;
27
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;
41
42 /**
43  * {@link AbstractListing} component declarative test.
44  * <p>
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.
50  * <p>
51  * Common {@link AbstractComponent} properties are tested in
52  * {@link AbstractComponentDeclarativeTestBase}
53  *
54  * @see AbstractComponentDeclarativeTestBase
55  *
56  * @author Vaadin Ltd
57  *
58  *
59  * @param <T>
60  *            a component type
61  */
62 @SuppressWarnings({ "unchecked", "rawtypes" })
63 public abstract class AbstractListingDeclarativeTest<T extends AbstractListing>
64         extends AbstractComponentDeclarativeTestBase<T> {
65
66     private static final String EXTERNAL_URL = "http://example.com/example.gif";
67
68     private static final String FILE_PATH = "img/example.gif";
69
70     private static final String THEME_PATH = "example.gif";
71
72     @Test
73     public abstract void dataSerialization() throws InstantiationException,
74             IllegalAccessException, InvocationTargetException;
75
76     @Test
77     public abstract void valueSerialization() throws InstantiationException,
78             IllegalAccessException, InvocationTargetException;
79
80     @Test
81     public void itemIconsSerialization() throws InstantiationException,
82             IllegalAccessException, InvocationTargetException {
83         T component = getComponentClass().newInstance();
84         Method setIconGenerator = getIconGeneratorMethod(component);
85         if (setIconGenerator == null) {
86             return;
87         }
88
89         List<String> items = Arrays.asList("foo", "bar", "foobar", "barfoo");
90
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,
97                 getComponentTag());
98
99         component.setItems(items);
100         IconGenerator generator = item -> generateIcons(item, items);
101         setIconGenerator.invoke(component, generator);
102
103         testRead(design, component);
104         testWrite(design, component, true);
105     }
106
107     @Test
108     public void enabledItemsSerialization() throws InstantiationException,
109             IllegalAccessException, InvocationTargetException {
110         T component = getComponentClass().newInstance();
111         Method setEnabledITemsGenerator = getEnabledItemsProviderMethod(
112                 component);
113         if (setEnabledITemsGenerator == null) {
114             return;
115         }
116
117         List<String> items = Arrays.asList("foo", "bar", "foobar");
118
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());
124
125         component.setItems(items);
126         SerializablePredicate predicate = item -> !item.equals("bar");
127         setEnabledITemsGenerator.invoke(component, predicate);
128
129         testRead(design, component);
130         testWrite(design, component, true);
131     }
132
133     @Test
134     public abstract void readOnlySelection() throws InstantiationException,
135             IllegalAccessException, InvocationTargetException;
136
137     @Override
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)) {
145                 return false;
146             }
147         }
148         return super.acceptProperty(clazz, readMethod, writeMethod);
149     }
150
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);
157         return context;
158     }
159
160     public T testRead(String design, T expected, boolean testWrite) {
161         T read = testRead(design, expected);
162         if (testWrite) {
163             DesignContext context = new DesignContext();
164             context.setShouldWriteDataDelegate(
165                     DeclarativeTestBaseBase.ALWAYS_WRITE_DATA);
166             testReadData(design, expected, read, context);
167         }
168         return read;
169     }
170
171     private void testReadData(String design, T expected, T read,
172             DesignContext context) {
173         assertEquals(
174                 read.getDataCommunicator().getDataProvider()
175                         .size(new Query<>()),
176                 expected.getDataCommunicator().getDataProvider()
177                         .size(new Query<>()));
178         testWrite(read, design, context);
179     }
180
181     private Method getIconGeneratorMethod(T component)
182             throws IllegalAccessException, InvocationTargetException {
183         try {
184             return component.getClass().getMethod("setItemIconGenerator",
185                     new Class[] { IconGenerator.class });
186         } catch (NoSuchMethodException ignore) {
187             // ignore if there is no such method
188             return null;
189         }
190     }
191
192     private Method getEnabledItemsProviderMethod(T component)
193             throws IllegalAccessException, InvocationTargetException {
194         try {
195             return component.getClass().getMethod("setItemEnabledProvider",
196                     new Class[] { SerializablePredicate.class });
197         } catch (NoSuchMethodException ignore) {
198             // ignore if there is no such method
199             return null;
200         }
201     }
202
203     private Resource generateIcons(Object item, List<String> items) {
204         int index = items.indexOf(item);
205         switch (index) {
206         case 0:
207             return new ExternalResource(EXTERNAL_URL);
208         case 1:
209             return new FileResource(new File(FILE_PATH));
210         case 2:
211             return new ThemeResource(THEME_PATH);
212         }
213         return null;
214     }
215
216 }