aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeif Åstrand <legioth@gmail.com>2017-02-02 12:33:57 +0200
committerDenis <denis@vaadin.com>2017-02-02 12:33:57 +0200
commit700742c85872c018af017f757fde64d564050811 (patch)
tree601e638e6a46b9636a8d267a685832a222a8d53c
parent567a43038a64b1acef395cc248bcda31b0a72949 (diff)
downloadvaadin-framework-700742c85872c018af017f757fde64d564050811.tar.gz
vaadin-framework-700742c85872c018af017f757fde64d564050811.zip
Add helpers for dealing with columns based on its id (#8411)
* Add helpers for dealing with columns based on its id setColumns(Column...) is removed since it's not possible to re-add a removed column instance. Fixes #8361
-rw-r--r--server/src/main/java/com/vaadin/ui/Grid.java120
-rw-r--r--server/src/main/java/com/vaadin/ui/components/grid/Footer.java32
-rw-r--r--server/src/main/java/com/vaadin/ui/components/grid/FooterRow.java33
-rw-r--r--server/src/main/java/com/vaadin/ui/components/grid/Header.java31
-rw-r--r--server/src/main/java/com/vaadin/ui/components/grid/HeaderRow.java32
-rw-r--r--server/src/test/java/com/vaadin/tests/components/grid/GridNullValueSort.java37
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/grid/GridTest.java124
-rw-r--r--server/src/test/java/com/vaadin/ui/components/grid/StaticSectionTest.java137
8 files changed, 506 insertions, 40 deletions
diff --git a/server/src/main/java/com/vaadin/ui/Grid.java b/server/src/main/java/com/vaadin/ui/Grid.java
index daf1cd1c69..bab686ed7f 100644
--- a/server/src/main/java/com/vaadin/ui/Grid.java
+++ b/server/src/main/java/com/vaadin/ui/Grid.java
@@ -34,6 +34,7 @@ import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.function.BinaryOperator;
+import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -2175,6 +2176,19 @@ public class Grid<T> extends AbstractListing<T> implements HasComponents,
}
/**
+ * Removes the column with the given column id.
+ *
+ * @see #removeColumn(Column)
+ * @see Column#setId(String)
+ *
+ * @param columnId
+ * the id of the column to remove, not <code>null</code>
+ */
+ public void removeColumn(String columnId) {
+ removeColumn(getColumnOrThrow(columnId));
+ }
+
+ /**
* Sets the details component generator.
*
* @param generator
@@ -2235,6 +2249,16 @@ public class Grid<T> extends AbstractListing<T> implements HasComponents,
return columnIds.get(columnId);
}
+ private Column<T, ?> getColumnOrThrow(String columnId) {
+ Objects.requireNonNull(columnId, "Column id cannot be null");
+ Column<T, ?> column = getColumn(columnId);
+ if (column == null) {
+ throw new IllegalStateException(
+ "There is no column with the id " + columnId);
+ }
+ return column;
+ }
+
@Override
public Iterator<Component> iterator() {
Set<Component> componentSet = new LinkedHashSet<>(extensionComponents);
@@ -2804,26 +2828,35 @@ public class Grid<T> extends AbstractListing<T> implements HasComponents,
}
/**
- * Sets the columns and their order for the grid. Columns currently in this
- * grid that are not present in columns are removed. Similarly, any new
- * column in columns will be added to this grid.
+ * Sets the columns and their order based on their column ids. Columns
+ * currently in this grid that are not present in the list of column ids are
+ * removed. This includes any column that has no id. Similarly, any new
+ * column in columns will be added to this grid. New columns can only be
+ * added for a <code>Grid</code> created using {@link Grid#Grid(Class)} or
+ * {@link #withPropertySet(PropertySet)}.
*
- * @param columns
- * the columns to set
+ *
+ * @param columnIds
+ * the column ids to set
+ *
+ * @see Column#setId(String)
*/
- public void setColumns(Column<T, ?>... columns) {
- List<Column<T, ?>> currentColumns = getColumns();
- Set<Column<T, ?>> removeColumns = new HashSet<>(currentColumns);
- Set<Column<T, ?>> addColumns = Arrays.stream(columns)
- .collect(Collectors.toSet());
+ public void setColumns(String... columnIds) {
+ // Must extract to an explicitly typed variable because otherwise javac
+ // cannot determine which overload of setColumnOrder to use
+ Column<T, ?>[] newColumnOrder = Stream.of(columnIds)
+ .map((Function<String, Column<T, ?>>) id -> {
+ Column<T, ?> column = getColumn(id);
+ if (column == null) {
+ column = addColumn(id);
+ }
+ return column;
+ }).toArray(Column[]::new);
+ setColumnOrder(newColumnOrder);
- removeColumns.removeAll(addColumns);
- removeColumns.stream().forEach(this::removeColumn);
-
- addColumns.removeAll(currentColumns);
- addColumns.stream().forEach(c -> addColumn(getIdentifier(c), c));
-
- setColumnOrder(columns);
+ // The columns to remove are now at the end of the column list
+ getColumns().stream().skip(columnIds.length)
+ .forEach(this::removeColumn);
}
private String getIdentifier(Column<T, ?> column) {
@@ -2848,16 +2881,21 @@ public class Grid<T> extends AbstractListing<T> implements HasComponents,
* the columns in the order they should be
*/
public void setColumnOrder(Column<T, ?>... columns) {
+ setColumnOrder(Stream.of(columns));
+ }
+
+ private void setColumnOrder(Stream<Column<T, ?>> columns) {
List<String> columnOrder = new ArrayList<>();
- for (Column<T, ?> column : columns) {
+ columns.forEach(column -> {
if (columnSet.contains(column)) {
columnOrder.add(column.getInternalId());
} else {
- throw new IllegalArgumentException(
+ throw new IllegalStateException(
"setColumnOrder should not be called "
+ "with columns that are not in the grid.");
}
- }
+
+ });
List<String> stateColumnOrder = getState().columnOrder;
if (stateColumnOrder.size() != columnOrder.size()) {
@@ -2870,6 +2908,20 @@ public class Grid<T> extends AbstractListing<T> implements HasComponents,
}
/**
+ * Sets a new column order for the grid based on their column ids. All
+ * columns which are not ordered here will remain in the order they were
+ * before as the last columns of grid.
+ *
+ * @param columnIds
+ * the column ids in the order they should be
+ *
+ * @see Column#setId(String)
+ */
+ public void setColumnOrder(String... columnIds) {
+ setColumnOrder(Stream.of(columnIds).map(this::getColumnOrThrow));
+ }
+
+ /**
* Returns the selection model for this grid.
*
* @return the selection model, not null
@@ -3029,7 +3081,7 @@ public class Grid<T> extends AbstractListing<T> implements HasComponents,
}
/**
- * Sort this Grid in user-specified {@link QuerySortOrder} by a column.
+ * Sort this Grid in user-specified direction by a column.
*
* @param column
* a column to sort against
@@ -3043,6 +3095,32 @@ public class Grid<T> extends AbstractListing<T> implements HasComponents,
}
/**
+ * Sort this Grid in ascending order by a specified column defined by id.
+ *
+ * @param columnId
+ * the id of the column to sort against
+ *
+ * @see Column#setId(String)
+ */
+ public void sort(String columnId) {
+ sort(columnId, SortDirection.ASCENDING);
+ }
+
+ /**
+ * Sort this Grid in a user-specified direction by a column defined by id.
+ *
+ * @param columnId
+ * the id of the column to sort against
+ * @param direction
+ * a sort order value (ascending/descending)
+ *
+ * @see Column#setId(String)
+ */
+ public void sort(String columnId, SortDirection direction) {
+ sort(getColumnOrThrow(columnId), direction);
+ }
+
+ /**
* Clear the current sort order, and re-sort the grid.
*/
public void clearSortOrder() {
diff --git a/server/src/main/java/com/vaadin/ui/components/grid/Footer.java b/server/src/main/java/com/vaadin/ui/components/grid/Footer.java
index ddc36c1efa..807efd4a5f 100644
--- a/server/src/main/java/com/vaadin/ui/components/grid/Footer.java
+++ b/server/src/main/java/com/vaadin/ui/components/grid/Footer.java
@@ -15,9 +15,13 @@
*/
package com.vaadin.ui.components.grid;
-import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.Column;
/**
* Represents the footer section of a Grid.
@@ -112,9 +116,29 @@ public abstract class Footer extends StaticSection<Footer.Row> {
*/
@Override
public FooterCell join(FooterCell... cellsToMerge) {
- Set<FooterCell> footerCells = new HashSet<>(
- Arrays.asList(cellsToMerge));
- return join(footerCells);
+ return join(Stream.of(cellsToMerge));
+ }
+
+ private FooterCell join(Stream<FooterCell> cellStream) {
+ return join(cellStream.collect(Collectors.toSet()));
+ }
+
+ @Override
+ public FooterCell join(Column<?, ?>... columnsToMerge) {
+ return join(Stream.of(columnsToMerge).map(this::getCell));
+ }
+
+ @Override
+ public FooterCell join(String... columnIdsToMerge) {
+ Grid<?> grid = getGrid();
+ return join(Stream.of(columnIdsToMerge).map(columnId -> {
+ Column<?, ?> column = grid.getColumn(columnId);
+ if (column == null) {
+ throw new IllegalStateException(
+ "There is no column with the id " + columnId);
+ }
+ return getCell(column);
+ }));
}
}
diff --git a/server/src/main/java/com/vaadin/ui/components/grid/FooterRow.java b/server/src/main/java/com/vaadin/ui/components/grid/FooterRow.java
index 23971c3b36..1234c270e3 100644
--- a/server/src/main/java/com/vaadin/ui/components/grid/FooterRow.java
+++ b/server/src/main/java/com/vaadin/ui/components/grid/FooterRow.java
@@ -82,4 +82,37 @@ public interface FooterRow extends Serializable {
* @see com.vaadin.ui.AbstractComponent#setCaption(String) setCaption
*/
FooterCell join(FooterCell... cellsToMerge);
+
+ /**
+ * Merges cells corresponding to the given columns in the row. Original
+ * cells are hidden, and new merged cell is shown instead. The cell has a
+ * width of all merged cells together, inherits styles of the first merged
+ * cell but has empty caption.
+ *
+ * @param columnsToMerge
+ * the columns of the cells that should be merged. The cells
+ * should not be merged to any other cell set.
+ * @return the remaining visible cell after the merge
+ *
+ * @see #join(Set)
+ * @see com.vaadin.ui.AbstractComponent#setCaption(String) setCaption
+ */
+ FooterCell join(Grid.Column<?, ?>... columnsToMerge);
+
+ /**
+ * Merges cells corresponding to the given column ids in the row. Original
+ * cells are hidden, and new merged cell is shown instead. The cell has a
+ * width of all merged cells together, inherits styles of the first merged
+ * cell but has empty caption.
+ *
+ * @param columnIdsToMerge
+ * the ids of the columns of the cells that should be merged. The
+ * cells should not be merged to any other cell set.
+ * @return the remaining visible cell after the merge
+ *
+ * @see #join(Set)
+ * @see com.vaadin.ui.AbstractComponent#setCaption(String) setCaption
+ * @see Column#setId(String)
+ */
+ FooterCell join(String... columnIdsToMerge);
}
diff --git a/server/src/main/java/com/vaadin/ui/components/grid/Header.java b/server/src/main/java/com/vaadin/ui/components/grid/Header.java
index 69c23c6818..421d616387 100644
--- a/server/src/main/java/com/vaadin/ui/components/grid/Header.java
+++ b/server/src/main/java/com/vaadin/ui/components/grid/Header.java
@@ -15,12 +15,15 @@
*/
package com.vaadin.ui.components.grid;
-import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import org.jsoup.nodes.Element;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.Column;
import com.vaadin.ui.declarative.DesignAttributeHandler;
import com.vaadin.ui.declarative.DesignContext;
@@ -137,9 +140,29 @@ public abstract class Header extends StaticSection<Header.Row> {
*/
@Override
public HeaderCell join(HeaderCell... cellsToMerge) {
- Set<HeaderCell> headerCells = new HashSet<>(
- Arrays.asList(cellsToMerge));
- return join(headerCells);
+ return join(Stream.of(cellsToMerge));
+ }
+
+ private HeaderCell join(Stream<HeaderCell> cellStream) {
+ return join(cellStream.collect(Collectors.toSet()));
+ }
+
+ @Override
+ public HeaderCell join(Column<?, ?>... columnsToMerge) {
+ return join(Stream.of(columnsToMerge).map(this::getCell));
+ }
+
+ @Override
+ public HeaderCell join(String... columnIdsToMerge) {
+ Grid<?> grid = getGrid();
+ return join(Stream.of(columnIdsToMerge).map(columnId -> {
+ Column<?, ?> column = grid.getColumn(columnId);
+ if (column == null) {
+ throw new IllegalStateException(
+ "There is no column with the id " + columnId);
+ }
+ return getCell(column);
+ }));
}
@Override
diff --git a/server/src/main/java/com/vaadin/ui/components/grid/HeaderRow.java b/server/src/main/java/com/vaadin/ui/components/grid/HeaderRow.java
index e07c44ba0e..a25d6f2595 100644
--- a/server/src/main/java/com/vaadin/ui/components/grid/HeaderRow.java
+++ b/server/src/main/java/com/vaadin/ui/components/grid/HeaderRow.java
@@ -83,4 +83,36 @@ public interface HeaderRow extends Serializable {
*/
HeaderCell join(HeaderCell... cellsToMerge);
+ /**
+ * Merges cells corresponding to the given columns in the row. Original
+ * cells are hidden, and new merged cell is shown instead. The cell has a
+ * width of all merged cells together, inherits styles of the first merged
+ * cell but has empty caption.
+ *
+ * @param columnsToMerge
+ * the columns of the cells that should be merged. The cells
+ * should not be merged to any other cell set.
+ * @return the remaining visible cell after the merge
+ *
+ * @see #join(Set)
+ * @see com.vaadin.ui.AbstractComponent#setCaption(String) setCaption
+ */
+ HeaderCell join(Grid.Column<?, ?>... columnsToMerge);
+
+ /**
+ * Merges cells corresponding to the given column ids in the row. Original
+ * cells are hidden, and new merged cell is shown instead. The cell has a
+ * width of all merged cells together, inherits styles of the first merged
+ * cell but has empty caption.
+ *
+ * @param columnIdsToMerge
+ * the ids of the columns of the cells that should be merged. The
+ * cells should not be merged to any other cell set.
+ * @return the remaining visible cell after the merge
+ *
+ * @see #join(Set)
+ * @see com.vaadin.ui.AbstractComponent#setCaption(String) setCaption
+ * @see Column#setId(String)
+ */
+ HeaderCell join(String... columnIdsToMerge);
}
diff --git a/server/src/test/java/com/vaadin/tests/components/grid/GridNullValueSort.java b/server/src/test/java/com/vaadin/tests/components/grid/GridNullValueSort.java
index 57cc19fa1b..c68cb2901c 100644
--- a/server/src/test/java/com/vaadin/tests/components/grid/GridNullValueSort.java
+++ b/server/src/test/java/com/vaadin/tests/components/grid/GridNullValueSort.java
@@ -1,18 +1,19 @@
package com.vaadin.tests.components.grid;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
import com.vaadin.server.SerializableComparator;
import com.vaadin.server.VaadinSession;
import com.vaadin.shared.data.sort.SortDirection;
import com.vaadin.ui.Grid;
import com.vaadin.ui.renderers.AbstractRenderer;
import com.vaadin.ui.renderers.NumberRenderer;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
public class GridNullValueSort {
@@ -49,6 +50,28 @@ public class GridNullValueSort {
}
@Test
+ public void testSortByColumnId() {
+ grid.sort("int");
+ performSort(Arrays.asList(2, 1, 3), Arrays.asList(1, 2, 3));
+ }
+
+ @Test
+ public void testSortByColumnIdAndDirection() {
+ grid.sort("int", SortDirection.DESCENDING);
+ performSort(Arrays.asList(2, 1, 3), Arrays.asList(3, 2, 1));
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testSortByMissingColumnId() {
+ grid.sort("notHere");
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testSortByMissingColumnIdAndDirection() {
+ grid.sort("notHere", SortDirection.DESCENDING);
+ }
+
+ @Test
public void testNumbers() {
grid.sort(grid.getColumn("int"), SortDirection.ASCENDING);
performSort(Arrays.asList(1, 2, null, 3, null, null),
diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/GridTest.java b/server/src/test/java/com/vaadin/tests/server/component/grid/GridTest.java
index fc644761bf..f216593c2f 100644
--- a/server/src/test/java/com/vaadin/tests/server/component/grid/GridTest.java
+++ b/server/src/test/java/com/vaadin/tests/server/component/grid/GridTest.java
@@ -40,15 +40,21 @@ import elemental.json.JsonObject;
public class GridTest {
private Grid<String> grid;
+ private Column<String, String> fooColumn;
+ private Column<String, Number> lengthColumn;
+ private Column<String, String> objectColumn;
+ private Column<String, String> randomColumn;
@Before
public void setUp() {
grid = new Grid<>();
- grid.addColumn(ValueProvider.identity()).setId("foo");
- grid.addColumn(String::length, new NumberRenderer());
- grid.addColumn(string -> new Object());
- grid.addColumn(ValueProvider.identity()).setId("randomColumnId");
+ fooColumn = grid.addColumn(ValueProvider.identity()).setId("foo");
+ lengthColumn = grid.addColumn(String::length, new NumberRenderer())
+ .setId("length");
+ objectColumn = grid.addColumn(string -> new Object());
+ randomColumn = grid.addColumn(ValueProvider.identity())
+ .setId("randomColumnId");
}
@Test
@@ -337,6 +343,116 @@ public class GridTest {
grid.addColumn("name");
}
+ @Test
+ public void removeByColumn_readdById() {
+ Grid<Person> grid = new Grid<>(Person.class);
+ grid.removeColumn(grid.getColumn("name"));
+
+ grid.addColumn("name");
+
+ List<Column<Person, ?>> columns = grid.getColumns();
+ Assert.assertEquals(2, columns.size());
+ Assert.assertEquals("born", columns.get(0).getId());
+ Assert.assertEquals("name", columns.get(1).getId());
+ }
+
+ @Test
+ public void removeColumnByColumn() {
+ grid.removeColumn(fooColumn);
+
+ Assert.assertEquals(
+ Arrays.asList(lengthColumn, objectColumn, randomColumn),
+ grid.getColumns());
+ }
+
+ @Test
+ public void removeColumnByColumn_alreadyRemoved() {
+ grid.removeColumn(fooColumn);
+ // Questionable that this doesn't throw, but that's a separate ticket...
+ grid.removeColumn(fooColumn);
+
+ Assert.assertEquals(
+ Arrays.asList(lengthColumn, objectColumn, randomColumn),
+ grid.getColumns());
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void removeColumnById_alreadyRemoved() {
+ grid.removeColumn("foo");
+ grid.removeColumn("foo");
+ }
+
+ @Test
+ public void removeColumnById() {
+ grid.removeColumn("foo");
+
+ Assert.assertEquals(
+ Arrays.asList(lengthColumn, objectColumn, randomColumn),
+ grid.getColumns());
+ }
+
+ @Test
+ public void setColumns_reorder() {
+ // Will remove other columns
+ grid.setColumns("length", "foo");
+
+ List<Column<String, ?>> columns = grid.getColumns();
+
+ Assert.assertEquals(2, columns.size());
+ Assert.assertEquals("length", columns.get(0).getId());
+ Assert.assertEquals("foo", columns.get(1).getId());
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void setColumns_addColumn_notBeangrid() {
+ // Not possible to add a column in a grid that cannot add columns based
+ // on a string
+ grid.setColumns("notHere");
+ }
+
+ @Test
+ public void setColumns_addColumns_beangrid() {
+ Grid<Person> grid = new Grid<>(Person.class);
+
+ // Remove so we can add it back
+ grid.removeColumn("name");
+
+ grid.setColumns("born", "name");
+
+ List<Column<Person, ?>> columns = grid.getColumns();
+ Assert.assertEquals(2, columns.size());
+ Assert.assertEquals("born", columns.get(0).getId());
+ Assert.assertEquals("name", columns.get(1).getId());
+ }
+
+ @Test
+ public void setColumnOrder_byColumn() {
+ grid.setColumnOrder(randomColumn, lengthColumn);
+
+ Assert.assertEquals(Arrays.asList(randomColumn, lengthColumn, fooColumn,
+ objectColumn), grid.getColumns());
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void setColumnOrder_byColumn_removedColumn() {
+ grid.removeColumn(randomColumn);
+ grid.setColumnOrder(randomColumn, lengthColumn);
+ }
+
+ @Test
+ public void setColumnOrder_byString() {
+ grid.setColumnOrder("randomColumnId", "length");
+
+ Assert.assertEquals(Arrays.asList(randomColumn, lengthColumn, fooColumn,
+ objectColumn), grid.getColumns());
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void setColumnOrder_byString_removedColumn() {
+ grid.removeColumn("randomColumnId");
+ grid.setColumnOrder("randomColumnId", "length");
+ }
+
private static <T> JsonObject getRowData(Grid<T> grid, T row) {
JsonObject json = Json.createObject();
if (grid.getColumns().isEmpty()) {
diff --git a/server/src/test/java/com/vaadin/ui/components/grid/StaticSectionTest.java b/server/src/test/java/com/vaadin/ui/components/grid/StaticSectionTest.java
new file mode 100644
index 0000000000..1223cfaef8
--- /dev/null
+++ b/server/src/test/java/com/vaadin/ui/components/grid/StaticSectionTest.java
@@ -0,0 +1,137 @@
+/*
+ * 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.ui.components.grid;
+
+import java.util.Arrays;
+import java.util.HashSet;
+
+import org.jsoup.nodes.Element;
+import org.jsoup.parser.Tag;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.ValueProvider;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.Column;
+
+public class StaticSectionTest {
+ private final Grid<String> grid = new Grid<>();
+ private final Column<String, String> col1 = grid
+ .addColumn(ValueProvider.identity()).setId("col1");
+ private final Column<String, String> col2 = grid
+ .addColumn(ValueProvider.identity()).setId("col2");
+ private final Column<String, String> col3 = grid
+ .addColumn(ValueProvider.identity()).setId("col3");
+
+ private HeaderRow headerRow;
+ private FooterRow footerRow;
+
+ @Before
+ public void setUp() {
+ footerRow = grid.addFooterRowAt(0);
+ headerRow = grid.addHeaderRowAt(0);
+ }
+
+ @Test
+ public void joinFootersBySet() {
+ footerRow.join(new HashSet<>(Arrays.asList(footerRow.getCell(col1),
+ footerRow.getCell(col2))));
+
+ assertFootersJoined();
+ }
+
+ @Test
+ public void joinFootersByCells() {
+ footerRow.join(footerRow.getCell(col1), footerRow.getCell(col2));
+
+ assertFootersJoined();
+ }
+
+ @Test
+ public void joinFootersByColumns() {
+ footerRow.join(col1, col2);
+
+ assertFootersJoined();
+ }
+
+ @Test
+ public void joinFootersByIds() {
+ footerRow.join("col1", "col2");
+
+ assertFootersJoined();
+ }
+
+ @Test
+ public void joinHeadersBySet() {
+ headerRow.join(new HashSet<>(Arrays.asList(headerRow.getCell(col1),
+ headerRow.getCell(col2))));
+
+ assertHeadersJoined();
+ }
+
+ @Test
+ public void joinHeadersByCells() {
+ headerRow.join(headerRow.getCell(col1), headerRow.getCell(col2));
+
+ assertHeadersJoined();
+ }
+
+ @Test
+ public void joinHeadersByColumns() {
+ headerRow.join(col1, col2);
+
+ assertHeadersJoined();
+ }
+
+ @Test
+ public void joinHeadersByIds() {
+ headerRow.join("col1", "col2");
+
+ assertHeadersJoined();
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void joinHeadersByMissingIds() {
+ headerRow.join("col1", "col4");
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void joinFootersByMissingIds() {
+ headerRow.join("col1", "col4");
+ }
+
+ private void assertFootersJoined() {
+ assertJoined((StaticSection.StaticRow<?>) footerRow);
+ }
+
+ private void assertHeadersJoined() {
+ assertJoined((StaticSection.StaticRow<?>) headerRow);
+ }
+
+ private static void assertJoined(StaticSection.StaticRow<?> staticRow) {
+ // There doesn't seem to be any direct API for checking what's joined,
+ // so verifying the merging by checking the declarative output
+ Element container = new Element(Tag.valueOf("container"), "");
+
+ staticRow.writeDesign(container, null);
+
+ Assert.assertEquals(2, container.children().size());
+ Assert.assertEquals("col1,col2", container.child(0).attr("column-ids"));
+ Assert.assertEquals("col3", container.child(1).attr("column-ids"));
+ }
+
+}