summaryrefslogtreecommitdiffstats
path: root/server/src/test
diff options
context:
space:
mode:
authorDenis <denis@vaadin.com>2016-12-13 15:46:29 +0200
committerPekka Hyvönen <pekka@vaadin.com>2016-12-13 15:46:29 +0200
commita43fd9003a77f253a78b807d4ecadcd828b936a4 (patch)
tree0182ee00bba9dc69d9cacba367ac00666945390a /server/src/test
parent6d1abeb9fc1103af0a04dfd79d56b0f883de6f72 (diff)
downloadvaadin-framework-a43fd9003a77f253a78b807d4ecadcd828b936a4.tar.gz
vaadin-framework-a43fd9003a77f253a78b807d4ecadcd828b936a4.zip
Provide declarative support for Grid. (#7961)
Fixes vaadin/framework8-issues#390
Diffstat (limited to 'server/src/test')
-rw-r--r--server/src/test/java/com/vaadin/tests/design/DeclarativeTestBaseBase.java4
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentDeclarativeTestBase.java23
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/grid/GridDeclarativeTest.java731
3 files changed, 748 insertions, 10 deletions
diff --git a/server/src/test/java/com/vaadin/tests/design/DeclarativeTestBaseBase.java b/server/src/test/java/com/vaadin/tests/design/DeclarativeTestBaseBase.java
index 1bab760530..041df2deee 100644
--- a/server/src/test/java/com/vaadin/tests/design/DeclarativeTestBaseBase.java
+++ b/server/src/test/java/com/vaadin/tests/design/DeclarativeTestBaseBase.java
@@ -221,9 +221,9 @@ public abstract class DeclarativeTestBaseBase<T extends Component> {
return context;
}
- public void testWrite(String design, T expected) {
+ public void testWrite(String expected, T component) {
TestLogHandler l = new TestLogHandler();
- testWrite(design, expected, false);
+ testWrite(expected, component, false);
Assert.assertEquals("", l.getMessages());
}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentDeclarativeTestBase.java b/server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentDeclarativeTestBase.java
index 7733855e95..ea7e9c77a3 100644
--- a/server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentDeclarativeTestBase.java
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentDeclarativeTestBase.java
@@ -92,16 +92,24 @@ public abstract class AbstractComponentDeclarativeTestBase<T extends AbstractCom
boolean visible = false;
boolean requiredIndicator = true;
+ T component = getComponentClass().newInstance();
+
+ boolean hasReadOnly = callBooleanSetter(readOnly, "setReadOnly",
+ component);
+ boolean hasRequiredIndicator = callBooleanSetter(requiredIndicator,
+ "setRequiredIndicatorVisible", component);
+
String design = String.format(
"<%s id='%s' caption='%s' caption-as-html description='%s' "
+ "error='%s' enabled='false' width='%s' height='%s' "
+ "icon='%s' locale='%s' primary-style-name='%s' "
- + "readonly responsive style-name='%s' visible='false' "
- + "required-indicator-visible/>",
+ + "%s responsive style-name='%s' visible='false' "
+ + "%s/>",
getComponentTag(), id, caption, description, error, width,
- height, icon, locale.toString(), primaryStyle, styleName);
+ height, icon, locale.toString(), primaryStyle,
+ hasReadOnly ? "readonly" : "", styleName,
+ hasRequiredIndicator ? "required-indicator-visible" : "");
- T component = getComponentClass().newInstance();
component.setId(id);
component.setCaption(caption);
component.setCaptionAsHtml(captionAsHtml);
@@ -115,9 +123,6 @@ public abstract class AbstractComponentDeclarativeTestBase<T extends AbstractCom
component.setIcon(new FileResource(new File(icon)));
component.setLocale(locale);
component.setPrimaryStyleName(primaryStyle);
- callBooleanSetter(readOnly, "setReadOnly", component);
- callBooleanSetter(requiredIndicator, "setRequiredIndicatorVisible",
- component);
component.setResponsive(responsive);
component.setStyleName(styleName);
component.setVisible(visible);
@@ -126,15 +131,17 @@ public abstract class AbstractComponentDeclarativeTestBase<T extends AbstractCom
testWrite(design, component);
}
- private void callBooleanSetter(boolean value, String setterName,
+ private boolean callBooleanSetter(boolean value, String setterName,
T component)
throws IllegalAccessException, InvocationTargetException {
try {
Method method = component.getClass().getMethod(setterName,
new Class[] { boolean.class });
method.invoke(component, value);
+ return true;
} catch (NoSuchMethodException ignore) {
// ignore if there is no such method
+ return false;
}
}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/GridDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/grid/GridDeclarativeTest.java
new file mode 100644
index 0000000000..9cdab40e01
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tests/server/component/grid/GridDeclarativeTest.java
@@ -0,0 +1,731 @@
+/*
+ * Copyright 2000-2016 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF 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.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Locale;
+
+import org.jsoup.nodes.Element;
+import org.jsoup.parser.Tag;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.SelectionModel.Multi;
+import com.vaadin.data.SelectionModel.Single;
+import com.vaadin.server.data.DataProvider;
+import com.vaadin.shared.ui.grid.HeightMode;
+import com.vaadin.shared.ui.label.ContentMode;
+import com.vaadin.tests.data.bean.Person;
+import com.vaadin.tests.server.component.abstractlisting.AbstractListingDeclarativeTest;
+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;
+import com.vaadin.ui.Grid.SelectionMode;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.declarative.DesignContext;
+import com.vaadin.ui.declarative.DesignException;
+
+/**
+ * @author Vaadin Ltd
+ *
+ */
+public class GridDeclarativeTest extends AbstractListingDeclarativeTest<Grid> {
+
+ @Test
+ public void gridAttributes() {
+ Grid<Person> grid = new Grid<>();
+ int frozenColumns = 1;
+ HeightMode heightMode = HeightMode.ROW;
+ double heightByRows = 13.7d;
+
+ grid.addColumn(Person::getFirstName);
+ grid.addColumn("id", Person::getLastName);
+
+ grid.setFrozenColumnCount(frozenColumns);
+ grid.setSelectionMode(SelectionMode.MULTI);
+ grid.setHeightMode(heightMode);
+ grid.setHeightByRows(heightByRows);
+
+ String design = String.format(
+ "<%s height-mode='%s' frozen-columns='%d' rows='%s' selection-mode='%s'><table><colgroup>"
+ + "<col column-id='generatedColumn0' sortable>"
+ + "<col column-id='id' sortable>" + "</colgroup><thead>"
+ + "<tr default><th plain-text column-ids='generatedColumn0'>Generated Column0</th>"
+ + "<th plain-text column-ids='id'>Id</th></tr>"
+ + "</thead></table></%s>",
+ getComponentTag(),
+ heightMode.toString().toLowerCase(Locale.ENGLISH),
+ frozenColumns, heightByRows,
+ SelectionMode.MULTI.toString().toLowerCase(Locale.ENGLISH),
+ getComponentTag());
+
+ testRead(design, grid);
+ testWrite(design, grid);
+ }
+
+ @Test
+ public void mergedHeaderCells() {
+ Grid<Person> grid = new Grid<>();
+
+ Column<Person, String> column1 = grid.addColumn(Person::getFirstName);
+ Column<Person, String> column2 = grid.addColumn("id",
+ Person::getLastName);
+ Column<Person, String> column3 = grid.addColumn("mail",
+ Person::getEmail);
+
+ HeaderRow header = grid.addHeaderRowAt(1);
+ String headerRowText1 = "foo";
+ header.getCell(column1).setText(headerRowText1);
+ HeaderCell cell2 = header.getCell(column2);
+ HeaderCell join = header.join(cell2, header.getCell(column3));
+ String headerRowText3 = "foobar";
+ join.setText(headerRowText3);
+
+ String design = String.format("<%s><table><colgroup>"
+ + "<col column-id='generatedColumn0' sortable>"
+ + "<col column-id='id' sortable>"
+ + "<col column-id='mail' sortable>" + "</colgroup><thead>"
+ + "<tr default><th plain-text column-ids='generatedColumn0'>Generated Column0</th>"
+ + "<th plain-text column-ids='id'>Id</th>"
+ + "<th plain-text column-ids='mail'>Mail</th></tr>"
+ + "<tr><th plain-text column-ids='generatedColumn0'>%s</th>"
+ + "<th colspan='2' plain-text column-ids='id,mail'>foobar</th></tr>"
+ + "</thead></table></%s>", getComponentTag(), headerRowText1,
+ headerRowText3, getComponentTag());
+
+ testRead(design, grid);
+ testWrite(design, grid);
+ }
+
+ @Test
+ public void mergedFooterCells() {
+ Grid<Person> grid = new Grid<>();
+
+ Column<Person, String> column1 = grid.addColumn(Person::getFirstName);
+ Column<Person, String> column2 = grid.addColumn("id",
+ Person::getLastName);
+ Column<Person, String> column3 = grid.addColumn("mail",
+ Person::getEmail);
+
+ FooterRow footer = grid.addFooterRowAt(0);
+
+ FooterCell cell1 = footer.getCell(column1);
+ String footerRowText1 = "foo";
+ cell1.setText(footerRowText1);
+
+ FooterCell cell2 = footer.getCell(column2);
+
+ FooterCell cell3 = footer.getCell(column3);
+ String footerRowText2 = "foobar";
+ footer.join(cell2, cell3).setHtml(footerRowText2);
+
+ String design = String.format("<%s><table><colgroup>"
+ + "<col column-id='generatedColumn0' sortable>"
+ + "<col column-id='id' sortable>"
+ + "<col column-id='mail' sortable>" + "</colgroup><thead>"
+ + "<tr default><th plain-text column-ids='generatedColumn0'>Generated Column0</th>"
+ + "<th plain-text column-ids='id'>Id</th>"
+ + "<th plain-text column-ids='mail'>Mail</th></tr></thead>"
+ + "<tfoot><tr><td plain-text column-ids='generatedColumn0'>%s</td>"
+ + "<td colspan='2' column-ids='id,mail'>%s</td></tr></tfoot>"
+ + "</table></%s>", getComponentTag(), footerRowText1,
+ footerRowText2, getComponentTag());
+
+ testRead(design, grid);
+ testWrite(design, grid);
+ }
+
+ @Test
+ public void columnAttributes() {
+ Grid<Person> grid = new Grid<>();
+
+ String secondColumnId = "id";
+ Column<Person, String> column1 = grid.addColumn(Person::getFirstName);
+ Column<Person, String> column2 = grid.addColumn(secondColumnId,
+ Person::getLastName);
+
+ String caption = "test-caption";
+ column1.setCaption(caption);
+ boolean sortable = false;
+ column1.setSortable(sortable);
+ boolean editable = true;
+ column1.setEditorComponentGenerator(component -> null);
+ column1.setEditable(editable);
+ boolean resizable = false;
+ column1.setResizable(resizable);
+ boolean hidable = true;
+ column1.setHidable(hidable);
+ boolean hidden = true;
+ column1.setHidden(hidden);
+
+ String hidingToggleCaption = "toggle-caption";
+ column2.setHidingToggleCaption(hidingToggleCaption);
+ double width = 17.3;
+ column2.setWidth(width);
+ double minWidth = 37.3;
+ column2.setMinimumWidth(minWidth);
+ double maxWidth = 63.4;
+ column2.setMaximumWidth(maxWidth);
+ int expandRatio = 83;
+ column2.setExpandRatio(expandRatio);
+
+ String design = String.format(
+ "<%s><table><colgroup>"
+ + "<col column-id='generatedColumn0' sortable='%s' editable resizable='%s' hidable hidden>"
+ + "<col column-id='id' sortable hiding-toggle-caption='%s' width='%s' min-width='%s' max-width='%s' expand='%s'>"
+ + "</colgroup><thead>"
+ + "<tr default><th plain-text column-ids='generatedColumn0'>%s</th>"
+ + "<th plain-text column-ids='id'>%s</th>"
+ + "</tr></thead>" + "</table></%s>",
+ getComponentTag(), sortable, resizable, hidingToggleCaption,
+ width, minWidth, maxWidth, expandRatio, caption, "Id",
+ getComponentTag());
+
+ testRead(design, grid, true);
+ testWrite(design, grid);
+ }
+
+ @Test
+ public void headerFooterSerialization() {
+ Grid<Person> grid = new Grid<>();
+
+ Column<Person, String> column1 = grid.addColumn(Person::getFirstName);
+ Column<Person, String> column2 = grid.addColumn("id",
+ Person::getLastName);
+
+ FooterRow footerRow = grid.addFooterRowAt(0);
+ footerRow.getCell(column1).setText("x");
+ footerRow.getCell(column2).setHtml("y");
+
+ String design = String.format("<%s><table><colgroup>"
+ + "<col column-id='generatedColumn0' sortable>"
+ + "<col column-id='id' sortable></colgroup><thead>"
+ + "<tr default><th plain-text column-ids='generatedColumn0'>Generated Column0</th>"
+ + "<th plain-text column-ids='id'>Id</th></tr>"
+ + "</thead><tbody></tbody>"
+ + "<tfoot><tr><td plain-text column-ids='generatedColumn0'>x</td>"
+ + "<td column-ids='id'>y</td></tr></tfoot>" + "</table></%s>",
+ getComponentTag(), getComponentTag());
+
+ testRead(design, grid);
+ testWrite(design, grid, true);
+ }
+
+ @Override
+ public void dataSerialization() throws InstantiationException,
+ IllegalAccessException, InvocationTargetException {
+ Grid<Person> grid = new Grid<>();
+
+ Person person1 = createPerson("foo", "bar");
+ Person person2 = createPerson("name", "last-name");
+ grid.setItems(person1, person2);
+
+ grid.addColumn(Person::getFirstName);
+ grid.addColumn("id", Person::getLastName);
+
+ String design = String.format(
+ "<%s><table><colgroup>"
+ + "<col column-id='generatedColumn0' sortable>"
+ + "<col column-id='id' sortable></colgroup><thead>"
+ + "<tr default><th plain-text column-ids='generatedColumn0'>Generated Column0</th>"
+ + "<th plain-text column-ids='id'>Id</th></tr>"
+ + "</thead><tbody>"
+ + "<tr item='%s'><td>%s</td><td>%s</td></tr>"
+ + "<tr item='%s'><td>%s</td><td>%s</td></tr>"
+ + "</tbody></table></%s>",
+ getComponentTag(), person1.toString(), person1.getFirstName(),
+ person1.getLastName(), person2.toString(),
+ person2.getFirstName(), person2.getLastName(),
+ getComponentTag());
+
+ testRead(design, grid);
+ testWrite(design, grid, true);
+ }
+
+ /**
+ * Value for single select
+ */
+ @Override
+ @Test
+ public void valueSerialization() throws InstantiationException,
+ IllegalAccessException, InvocationTargetException {
+ valueSingleSelectSerialization();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void valueMultiSelectSerialization() throws InstantiationException,
+ IllegalAccessException, InvocationTargetException {
+ Grid<Person> grid = new Grid<>();
+
+ Person person1 = createPerson("foo", "bar");
+ Person person2 = createPerson("name", "last-name");
+ Person person3 = createPerson("foo", "last-name");
+ grid.setItems(person1, person2, person3);
+
+ grid.addColumn(Person::getFirstName);
+ grid.addColumn("id", Person::getLastName);
+
+ Multi<Person> model = (Multi<Person>) grid
+ .setSelectionMode(SelectionMode.MULTI);
+ model.selectItems(person1, person3);
+
+ String design = String.format(
+ "<%s selection-mode='multi'><table><colgroup>"
+ + "<col column-id='generatedColumn0' sortable>"
+ + "<col column-id='id' sortable></colgroup><thead>"
+ + "<tr default><th plain-text column-ids='generatedColumn0'>Generated Column0</th>"
+ + "<th plain-text column-ids='id'>Id</th></tr>"
+ + "</thead><tbody>"
+ + "<tr item='%s' selected><td>%s</td><td>%s</td></tr>"
+ + "<tr item='%s'><td>%s</td><td>%s</td></tr>"
+ + "<tr item='%s' selected><td>%s</td><td>%s</td></tr>"
+ + "</tbody></table></%s>",
+ getComponentTag(), person1.toString(), person1.getFirstName(),
+ person1.getLastName(), person2.toString(),
+ person2.getFirstName(), person2.getLastName(),
+ person3.toString(), person3.getFirstName(),
+ person3.getLastName(), getComponentTag());
+
+ testRead(design, grid);
+ testWrite(design, grid, true);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void valueSingleSelectSerialization() throws InstantiationException,
+ IllegalAccessException, InvocationTargetException {
+ Grid<Person> grid = new Grid<>();
+
+ Person person1 = createPerson("foo", "bar");
+ Person person2 = createPerson("name", "last-name");
+ grid.setItems(person1, person2);
+
+ grid.addColumn(Person::getFirstName);
+ grid.addColumn("id", Person::getLastName);
+
+ Single<Person> model = (Single<Person>) grid
+ .setSelectionMode(SelectionMode.SINGLE);
+ model.select(person2);
+
+ String design = String.format(
+ "<%s><table><colgroup>"
+ + "<col column-id='generatedColumn0' sortable>"
+ + "<col column-id='id' sortable></colgroup><thead>"
+ + "<tr default><th plain-text column-ids='generatedColumn0'>Generated Column0</th>"
+ + "<th plain-text column-ids='id'>Id</th></tr>"
+ + "</thead><tbody>"
+ + "<tr item='%s'><td>%s</td><td>%s</td></tr>"
+ + "<tr item='%s' selected><td>%s</td><td>%s</td></tr>"
+ + "</tbody></table></%s>",
+ getComponentTag(), person1.toString(), person1.getFirstName(),
+ person1.getLastName(), person2.toString(),
+ person2.getFirstName(), person2.getLastName(),
+ getComponentTag());
+
+ testRead(design, grid);
+ testWrite(design, grid, true);
+ }
+
+ @Override
+ public void readOnlySelection() throws InstantiationException,
+ IllegalAccessException, InvocationTargetException {
+ Grid<Person> grid = new Grid<>();
+
+ Person person1 = createPerson("foo", "bar");
+ Person person2 = createPerson("name", "last-name");
+ grid.setItems(person1, person2);
+
+ grid.addColumn(Person::getFirstName);
+ grid.addColumn("id", Person::getLastName);
+
+ grid.setSelectionMode(SelectionMode.MULTI);
+ grid.asMultiSelect().setReadOnly(true);
+
+ String formatString = "<%s %s selection-allowed><table><colgroup>"
+ + "<col column-id='generatedColumn0' sortable>"
+ + "<col column-id='id' sortable>" + "</colgroup><thead>"
+ + "<tr default><th plain-text column-ids='generatedColumn0'>Generated Column0</th>"
+ + "<th plain-text column-ids='id'>Id</th></tr>"
+ + "</thead><tbody>"
+ + "<tr item='%s'><td>%s</td><td>%s</td></tr>"
+ + "<tr item='%s'><td>%s</td><td>%s</td></tr>"
+ + "</tbody></table></%s>";
+
+ String design = String.format(formatString, getComponentTag(),
+ "selection-mode='multi'", person1.toString(),
+ person1.getFirstName(), person1.getLastName(),
+ person2.toString(), person2.getFirstName(),
+ person2.getLastName(), getComponentTag());
+
+ testRead(design, grid);
+ testWrite(design, grid, true);
+
+ grid.setSelectionMode(SelectionMode.SINGLE);
+ grid.asSingleSelect().setReadOnly(true);
+
+ design = String.format(formatString, getComponentTag(), "",
+ person1.toString(), person1.getFirstName(),
+ person1.getLastName(), person2.toString(),
+ person2.getFirstName(), person2.getLastName(),
+ getComponentTag());
+
+ testRead(design, grid);
+ testWrite(design, grid, true);
+ }
+
+ @Test
+ public void testComponentInGridHeader() {
+ Grid<Person> grid = new Grid<>();
+ Column<Person, String> column = grid.addColumn(Person::getFirstName);
+
+ String html = "<b>Foo</b>";
+ Label component = new Label(html);
+ component.setContentMode(ContentMode.HTML);
+
+ //@formatter:off
+ String design = String.format( "<%s><table>"
+ + "<colgroup>"
+ + " <col sortable column-id='generatedColumn0'>"
+ + "</colgroup>"
+ + "<thead>"
+ + "<tr default><th column-ids='generatedColumn0'><vaadin-label>%s</vaadin-label></th></tr>"
+ + "</thead>"
+ + "</table></%s>", getComponentTag(), html, getComponentTag());
+ //@formatter:on
+
+ grid.getDefaultHeaderRow().getCell(column.getId())
+ .setComponent(component);
+
+ testRead(design, grid, true);
+ testWrite(design, grid);
+ }
+
+ @Test
+ public void testComponentInGridFooter() {
+ Grid<Person> grid = new Grid<>();
+ Column<Person, String> column = grid.addColumn(Person::getFirstName);
+
+ String html = "<b>Foo</b>";
+ Label component = new Label(html);
+ component.setContentMode(ContentMode.HTML);
+
+ grid.prependFooterRow().getCell(column).setComponent(component);
+ grid.removeHeaderRow(grid.getDefaultHeaderRow());
+
+ //@formatter:off
+ String design = String.format( "<%s><table>"
+ + "<colgroup>"
+ + " <col sortable column-id='generatedColumn0'>"
+ + "</colgroup>"
+ + "<thead>"
+ +"<tfoot>"
+ + "<tr><td column-ids='generatedColumn0'><vaadin-label>%s</vaadin-label></td></tr>"
+ + "</tfoot>"
+ + "</table>"
+ + "</%s>", getComponentTag(), html, getComponentTag());
+ //@formatter:on
+
+ testRead(design, grid, true);
+ testWrite(design, grid);
+ }
+
+ @Test
+ public void testNoHeaderRows() {
+ //@formatter:off
+ String design = "<vaadin-grid><table>"
+ + "<colgroup>"
+ + " <col sortable column-id='generatedColumn0'>"
+ + "</colgroup>"
+ + "<thead />"
+ + "</table>"
+ + "</vaadin-grid>";
+ //@formatter:on
+ Grid<Person> grid = new Grid<>();
+ grid.addColumn(Person::getFirstName);
+ grid.removeHeaderRow(grid.getDefaultHeaderRow());
+
+ testWrite(design, grid);
+ testRead(design, grid, true);
+ }
+
+ @Test
+ public void testReadEmptyGrid() {
+ String design = "<vaadin-grid />";
+ testRead(design, new Grid<String>(), false);
+ }
+
+ @Test
+ public void testEmptyGrid() {
+ String design = "<vaadin-grid></vaadin-grid>";
+ Grid<String> 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<String>());
+ }
+
+ @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<String>());
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testHtmlEntitiesinGridHeaderFooter() {
+ String id = "> id";
+ String plainText = "plain-text";
+ //@formatter:off
+ String design = String.format( "<%s><table>"
+ + "<colgroup>"
+ + " <col sortable column-id='%s'>"
+ + "</colgroup>"
+ + "<thead>"
+ +" <tr default><th %s column-ids='%s'>&gt; Test</th>"
+ + "</thead>"
+ + "<tfoot>"
+ + "<tr><td %s column-ids='%s'>&gt; Test</td></tr>"
+ + "</tfoot>"
+ + "<tbody />"
+ + "</table></%s>",
+ getComponentTag() , id, plainText, id, plainText, id, getComponentTag());
+ //@formatter:on
+
+ Grid<Person> grid = read(design);
+ String actualHeader = grid.getHeaderRow(0).getCell(id).getText();
+ String actualFooter = grid.getFooterRow(0).getCell(id).getText();
+ String expected = "> Test";
+
+ Assert.assertEquals(expected, actualHeader);
+ Assert.assertEquals(expected, actualFooter);
+
+ design = design.replace(plainText, "");
+ grid = read(design);
+ actualHeader = grid.getHeaderRow(0).getCell(id).getHtml();
+ actualFooter = grid.getFooterRow(0).getCell(id).getHtml();
+ expected = "&gt; Test";
+
+ Assert.assertEquals(expected, actualHeader);
+ Assert.assertEquals(expected, actualFooter);
+
+ grid = new Grid<>();
+ Column<Person, String> column = grid.addColumn(id,
+ Person::getFirstName);
+ 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(column).setText("&amp; Test");
+ footer.getCell(column).setText("&amp; Test");
+
+ Element root = new Element(Tag.valueOf(getComponentTag()), "");
+ grid.writeDesign(root, new DesignContext());
+
+ Assert.assertEquals("&amp;amp; Test",
+ root.getElementsByTag("th").get(0).html());
+ Assert.assertEquals("&amp;amp; Test",
+ root.getElementsByTag("td").get(0).html());
+
+ header = grid.addHeaderRowAt(0);
+ footer = grid.addFooterRowAt(0);
+
+ // entities should not be encoded, this is already given as HTML
+ header.getCell(id).setHtml("&amp; Test");
+ footer.getCell(id).setHtml("&amp; Test");
+
+ root = new Element(Tag.valueOf(getComponentTag()), "");
+ 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());
+
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public Grid<?> testRead(String design, Grid expected) {
+ return testRead(design, expected, false);
+ }
+
+ @SuppressWarnings("rawtypes")
+ public Grid<?> testRead(String design, Grid expected, boolean retestWrite) {
+ return testRead(design, expected, retestWrite, false);
+ }
+
+ @SuppressWarnings("rawtypes")
+ 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<?, ?> column : expected.getColumns()) {
+ String baseError = "Difference when comparing cell for "
+ + column.toString() + " on header row " + i + ": ";
+ HeaderCell expectedCell = expectedRow.getCell(column);
+ HeaderCell actualCell = actualRow.getCell(column);
+
+ 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<?, ?> column : expected.getColumns()) {
+ String baseError = "Difference when comparing cell for "
+ + column.toString() + " on footer row " + i + ": ";
+ FooterCell expectedCell = expectedRow.getCell(column);
+ FooterCell actualCell = actualRow.getCell(column);
+
+ 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<?> columns = expected.getColumns();
+ List<?> actualColumns = actual.getColumns();
+ Assert.assertEquals("Different amount of columns", columns.size(),
+ actualColumns.size());
+ for (int i = 0; i < columns.size(); ++i) {
+ Column<?, ?> col1 = (Column<?, ?>) columns.get(i);
+ Column<?, ?> col2 = (Column<?, ?>) actualColumns.get(i);
+ String baseError = "Error when comparing columns for property "
+ + col1.getId() + ": ";
+ 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());
+ }
+ }
+
+ @Override
+ protected String getComponentTag() {
+ return "vaadin-grid";
+ }
+
+ @Override
+ protected Class<? extends Grid> getComponentClass() {
+ return Grid.class;
+ }
+
+ @Override
+ protected boolean acceptProperty(Class<?> clazz, Method readMethod,
+ Method writeMethod) {
+ if (readMethod != null) {
+ Class<?> returnType = readMethod.getReturnType();
+ if (HeaderRow.class.equals(returnType)
+ || DataProvider.class.equals(returnType)) {
+ return false;
+ }
+ }
+ return super.acceptProperty(clazz, readMethod, writeMethod);
+ }
+
+ private Person createPerson(String name, String lastName) {
+ Person person = new Person() {
+ @Override
+ public String toString() {
+ return getFirstName() + " " + getLastName();
+ }
+ };
+ person.setFirstName(name);
+ person.setLastName(lastName);
+ return person;
+ }
+
+}