Browse Source

Add a typed version of the Grid component

Change-Id: I00cbe80ac72787de0c4cc88e1c223badc2c4ae89
tags/8.0.0.alpha1
Teemu Suo-Anttila 7 years ago
parent
commit
87e0a08b60

+ 85
- 0
client/src/main/java/com/vaadin/client/connectors/grid/ColumnConnector.java View File

@@ -0,0 +1,85 @@
/*
* 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.client.connectors.grid;

import com.vaadin.client.ServerConnector;
import com.vaadin.client.annotations.OnStateChange;
import com.vaadin.client.extensions.AbstractExtensionConnector;
import com.vaadin.client.widgets.Grid.Column;
import com.vaadin.shared.data.DataCommunicatorConstants;
import com.vaadin.shared.ui.Connect;
import com.vaadin.shared.ui.grid.ColumnState;

import elemental.json.JsonObject;
import elemental.json.JsonValue;

/**
* A connector class for columns of the Grid component.
*
* @author Vaadin Ltd
* @since
*/
@Connect(com.vaadin.ui.Grid.Column.class)
public class ColumnConnector extends AbstractExtensionConnector {

private Column<JsonValue, JsonObject> column;

/* This parent is needed because it's no longer available in onUnregister */
private GridConnector parent;

@Override
protected void extend(ServerConnector target) {
parent = getParent();
column = new Column<JsonValue, JsonObject>() {

@Override
public JsonValue getValue(JsonObject row) {
return row.getObject(DataCommunicatorConstants.DATA)
.get(getState().id);
}
};
getParent().addColumn(column, getState().id);
}

@OnStateChange("caption")
void updateCaption() {
column.setHeaderCaption(getState().caption);
}

@OnStateChange("sortable")
void updateSortable() {
column.setSortable(getState().sortable);
}

@Override
public void onUnregister() {
super.onUnregister();

parent.removeColumn(column);
column = null;
}

@Override
public GridConnector getParent() {
return (GridConnector) super.getParent();
}

@Override
public ColumnState getState() {
return (ColumnState) super.getState();
}

}

+ 136
- 0
client/src/main/java/com/vaadin/client/connectors/grid/GridConnector.java View File

@@ -0,0 +1,136 @@
/*
* 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.client.connectors.grid;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.vaadin.client.DeferredWorker;
import com.vaadin.client.connectors.AbstractListingConnector;
import com.vaadin.client.data.DataSource;
import com.vaadin.client.ui.SimpleManagedLayout;
import com.vaadin.client.widget.grid.selection.ClickSelectHandler;
import com.vaadin.client.widget.grid.sort.SortEvent;
import com.vaadin.client.widget.grid.sort.SortOrder;
import com.vaadin.client.widgets.Grid;
import com.vaadin.client.widgets.Grid.Column;
import com.vaadin.shared.data.sort.SortDirection;
import com.vaadin.shared.ui.Connect;
import com.vaadin.shared.ui.grid.GridServerRpc;

import elemental.json.JsonObject;

/**
* A connector class for the typed Grid component.
*
* @author Vaadin Ltd
* @since
*/
@Connect(com.vaadin.ui.Grid.class)
public class GridConnector extends AbstractListingConnector
implements SimpleManagedLayout, DeferredWorker {
/* Map to keep track of all added columns */
private Map<Column<?, JsonObject>, String> columnToIdMap = new HashMap<>();

@Override
public Grid<JsonObject> getWidget() {
return (Grid<JsonObject>) super.getWidget();
}

@Override
protected void init() {
super.init();

new ClickSelectHandler<JsonObject>(getWidget());
getWidget().addSortHandler(this::handleSortEvent);

layout();
}

@Override
public void setDataSource(DataSource<JsonObject> dataSource) {
getWidget().setDataSource(dataSource);
}

/**
* Adds a column to the Grid widget. For each column a communication id
* stored for client to server communication.
*
* @param column
* column to add
* @param id
* communication id
*/
public void addColumn(Column<?, JsonObject> column, String id) {
assert !columnToIdMap.containsKey(column) && !columnToIdMap
.containsValue(id) : "Column with given id already exists.";
getWidget().addColumn(column);
columnToIdMap.put(column, id);
}

/**
* Removes a column from Grid widget. This method also removes communication
* id mapping for the column.
*
* @param column
* column to remove
*/
public void removeColumn(Column<?, JsonObject> column) {
assert columnToIdMap
.containsKey(column) : "Given Column does not exist.";
getWidget().removeColumn(column);
columnToIdMap.remove(column);
}

@Override
public void onUnregister() {
super.onUnregister();

columnToIdMap.clear();
}

@Override
public boolean isWorkPending() {
return getWidget().isWorkPending();
}

@Override
public void layout() {
getWidget().onResize();
}

/**
* Sends sort information from an event to the server-side of the Grid.
*
* @param event
* the sort event
*/
private void handleSortEvent(SortEvent<JsonObject> event) {
List<String> columnIds = new ArrayList<>();
List<SortDirection> sortDirections = new ArrayList<>();
for (SortOrder so : event.getOrder()) {
if (columnToIdMap.containsKey(so.getColumn())) {
columnIds.add(columnToIdMap.get(so.getColumn()));
sortDirections.add(so.getDirection());
}
}
getRpcProxy(GridServerRpc.class).sort(columnIds.toArray(new String[0]),
sortDirections.toArray(new SortDirection[0]),
event.isUserOriginated());
}
}

+ 26
- 2
server/src/main/java/com/vaadin/ui/AbstractListing.java View File

@@ -21,7 +21,7 @@ import com.vaadin.server.data.DataSource;
import com.vaadin.server.data.TypedDataGenerator;

/**
* Base class for Listing components. Provides common handling for
* Base class for {@link Listing} components. Provides common handling for
* {@link DataCommunicator} and {@link TypedDataGenerator}s.
*
* @param <T>
@@ -31,7 +31,31 @@ public abstract class AbstractListing<T> extends AbstractComponent
implements Listing<T> {

/* DataCommunicator for this Listing component */
private final DataCommunicator<T> dataCommunicator = new DataCommunicator<>();
private final DataCommunicator<T> dataCommunicator;

/**
* Constructs an {@link AbstractListing}, extending it with a
* {@link DataCommunicator}.
*/
protected AbstractListing() {
this(new DataCommunicator<>());
}

/**
* Constructs an {@link AbstractListing}, extending it with given
* {@link DataCommunicator}.
* <p>
* <strong>Note:</strong> This method is for creating an
* {@link AbstractListing} with a custom {@link DataCommunicator}. In the
* common case {@link AbstractListing#AbstractListing()} should be used.
*
* @param dataCommunicator
* a customized data communicator instance
*/
protected AbstractListing(DataCommunicator<T> dataCommunicator) {
this.dataCommunicator = dataCommunicator;
addExtension(dataCommunicator);
}

@Override
public void setDataSource(DataSource<T> dataSource) {

+ 408
- 0
server/src/main/java/com/vaadin/ui/Grid.java View File

@@ -0,0 +1,408 @@
/*
* 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;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Stream;

import com.vaadin.server.AbstractExtension;
import com.vaadin.server.KeyMapper;
import com.vaadin.server.data.DataSource;
import com.vaadin.server.data.SortOrder;
import com.vaadin.server.data.TypedDataGenerator;
import com.vaadin.shared.MouseEventDetails;
import com.vaadin.shared.data.DataCommunicatorConstants;
import com.vaadin.shared.data.sort.SortDirection;
import com.vaadin.shared.ui.grid.ColumnState;
import com.vaadin.shared.ui.grid.GridConstants.Section;
import com.vaadin.shared.ui.grid.GridServerRpc;

import elemental.json.Json;
import elemental.json.JsonObject;

/**
* A grid component for displaying tabular data.
*
* @author Vaadin Ltd
* @since
*
* @param <T>
* the grid bean type
*/
public class Grid<T> extends AbstractListing<T> {

private final class GridServerRpcImpl implements GridServerRpc {
@Override
public void sort(String[] columnIds, SortDirection[] directions,
boolean isUserOriginated) {
assert columnIds.length == directions.length : "Column and sort direction counts don't match.";
sortOrder.clear();
if (columnIds.length == 0) {
// Grid is not sorted anymore.
getDataCommunicator()
.setBackEndSorting(Collections.emptyList());
getDataCommunicator().setInMemorySorting(null);
return;
}

for (int i = 0; i < columnIds.length; ++i) {
Column<T, ?> column = columnKeys.get(columnIds[i]);
sortOrder.add(new SortOrder<>(column, directions[i]));
}

// Set sort orders
// In-memory comparator
Comparator<T> comparator = sortOrder.stream()
.map(order -> order.getSorted()
.getComparator(order.getDirection()))
.reduce((x, y) -> 0, Comparator::thenComparing);
getDataCommunicator().setInMemorySorting(comparator);

// Back-end sort properties
List<SortOrder<String>> sortProperties = new ArrayList<>();
sortOrder.stream()
.map(order -> order.getSorted()
.getSortOrder(order.getDirection()))
.forEach(s -> s.forEach(sortProperties::add));
getDataCommunicator().setBackEndSorting(sortProperties);
}

@Override
public void itemClick(String rowKey, String columnId,
MouseEventDetails details) {
// TODO Auto-generated method stub
}

@Override
public void contextClick(int rowIndex, String rowKey, String columnId,
Section section, MouseEventDetails details) {
// TODO Auto-generated method stub
}

@Override
public void columnsReordered(List<String> newColumnOrder,
List<String> oldColumnOrder) {
// TODO Auto-generated method stub
}

@Override
public void columnVisibilityChanged(String id, boolean hidden,
boolean userOriginated) {
// TODO Auto-generated method stub
}

@Override
public void columnResized(String id, double pixels) {
// TODO Auto-generated method stub
}
}

/**
* This extension manages the configuration and data communication for a
* Column inside of a Grid component.
*
* @param <T>
* the grid bean type
* @param <V>
* the column value type
*/
public static class Column<T, V> extends AbstractExtension
implements TypedDataGenerator<T> {

private Function<T, V> valueProvider;
private Function<SortDirection, Stream<SortOrder<String>>> sortOrderProvider;
private Comparator<T> comparator;

/**
* Constructs a new Column configuration with given header caption and
* value provider.
*
* @param caption
* the header caption
* @param valueType
* the type of value
* @param valueProvider
* the function to get values from data objects
*/
protected Column(String caption, Class<V> valueType,
Function<T, V> valueProvider) {
Objects.requireNonNull(caption, "Header caption can't be null");
Objects.requireNonNull(valueProvider,
"Value provider can't be null");
Objects.requireNonNull(valueType, "Value type can't be null");

this.valueProvider = valueProvider;
getState().caption = caption;
sortOrderProvider = d -> Stream.of();

if (Comparable.class.isAssignableFrom(valueType)) {
comparator = (a, b) -> {
Comparable<V> comp = (Comparable<V>) valueProvider.apply(a);
return comp.compareTo(valueProvider.apply(b));
};
getState().sortable = true;
} else {
getState().sortable = false;
}
}

@Override
public void generateData(T data, JsonObject jsonObject) {
assert getState(
false).id != null : "No communication ID set for column "
+ getState(false).caption;

if (!jsonObject.hasKey(DataCommunicatorConstants.DATA)) {
jsonObject.put(DataCommunicatorConstants.DATA,
Json.createObject());
}
JsonObject obj = jsonObject
.getObject(DataCommunicatorConstants.DATA);
// Since we dont' have renderers yet, use a dummy toString for data.
obj.put(getState(false).id, valueProvider.apply(data).toString());
}

@Override
public void destroyData(T data) {
}

@Override
protected ColumnState getState() {
return getState(true);
}

@Override
protected ColumnState getState(boolean markAsDirty) {
return (ColumnState) super.getState(markAsDirty);
}

/**
* This method extends the given Grid with this Column.
*
* @param grid
* the grid to extend
*/
private void extend(Grid<T> grid) {
super.extend(grid);
}

/**
* Sets the identifier to use with this Column in communication.
*
* @param id
* the identifier string
*/
private void setId(String id) {
Objects.requireNonNull(id, "Communication ID can't be null");
getState().id = id;
}

/**
* Sets whether the user can sort this column or not.
*
* @param sortable
* {@code true} if the column can be sorted by the user;
* {@code false} if not
* @return this column
*/
public Column<T, V> setSortable(boolean sortable) {
getState().sortable = sortable;
return this;
}

/**
* Gets whether the user can sort this column or not.
*
* @return {@code true} if the column can be sorted by the user;
* {@code false} if not
*/
public boolean isSortable() {
return getState(false).sortable;
}

/**
* Sets the header caption for this column.
*
* @param caption
* the header caption
*
* @return this column
*/
public Column<T, V> setCaption(String caption) {
Objects.requireNonNull(caption, "Header caption can't be null");
getState().caption = caption;
return this;
}

/**
* Gets the header caption for this column.
*
* @return header caption
*/
public String getCaption() {
return getState(false).caption;
}

/**
* Sets a comparator to use with in-memory sorting with this column.
* Sorting with a back-end is done using
* {@link Column#setSortProperty(String...)}.
*
* @param comparator
* the comparator to use when sorting data in this column
* @return this column
*/
public Column<T, V> setComparator(Comparator<T> comparator) {
Objects.requireNonNull(comparator, "Comparator can't be null");
this.comparator = comparator;
return this;
}

/**
* Gets the comparator to use with in-memory sorting for this column
* when sorting in the given direction.
*
* @param sortDirection
* the direction this column is sorted by
* @return comparator for this column
*/
public Comparator<T> getComparator(SortDirection sortDirection) {
Objects.requireNonNull(comparator,
"No comparator defined for sorted column.");
boolean reverse = sortDirection != SortDirection.ASCENDING;
return reverse ? comparator.reversed() : comparator;
}

/**
* Sets strings describing back end properties to be used when sorting
* this column. This method is a short hand for
* {@link #setSortBuilder(Function)} that takes an array of strings and
* uses the same sorting direction for all of them.
*
* @param properties
* the array of strings describing backend properties
* @return this column
*/
public Column<T, V> setSortProperty(String... properties) {
Objects.requireNonNull(properties, "Sort properties can't be null");
sortOrderProvider = dir -> Arrays.stream(properties)
.map(s -> new SortOrder<>(s, dir));
return this;
}

/**
* Sets the sort orders when sorting this column. The sort order
* provider is a function which provides {@link SortOrder} objects to
* describe how to sort by this column.
*
* @param provider
* the function to use when generating sort orders with the
* given direction
* @return this column
*/
public Column<T, V> setSortOrderProvider(
Function<SortDirection, Stream<SortOrder<String>>> provider) {
Objects.requireNonNull(provider,
"Sort order provider can't be null");
sortOrderProvider = provider;
return this;
}

/**
* Gets the sort orders to use with back-end sorting for this column
* when sorting in the given direction.
*
* @param direction
* the sorting direction
* @return stream of sort orders
*/
public Stream<SortOrder<String>> getSortOrder(SortDirection direction) {
return sortOrderProvider.apply(direction);
}
}

private KeyMapper<Column<T, ?>> columnKeys = new KeyMapper<>();
private Set<Column<T, ?>> columnSet = new HashSet<>();
private List<SortOrder<Column<T, ?>>> sortOrder = new ArrayList<>();

/**
* Constructor for the {@link Grid} component.
*/
public Grid() {
setDataSource(DataSource.create());
registerRpc(new GridServerRpcImpl());
}

/**
* Adds a new column to this {@link Grid} with given header caption and
* value provider.
*
* @param caption
* the header caption
* @param valueType
* the column value class
* @param valueProvider
* the value provider
* @param <V>
* the column value type
*
* @return the new column
*/
public <V> Column<T, V> addColumn(String caption, Class<V> valueType,
Function<T, V> valueProvider) {
Column<T, V> c = new Column<T, V>(caption, valueType, valueProvider);

c.extend(this);
c.setId(columnKeys.key(c));
columnSet.add(c);
addDataGenerator(c);

return c;
}

/**
* Removes the given column from this {@link Grid}.
*
* @param column
* the column to remove
*/
public void removeColumn(Column<T, ?> column) {
if (columnSet.remove(column)) {
columnKeys.remove(column);
removeDataGenerator(column);
column.remove();
}
}

/**
* Gets an unmodifiable collection of all columns currently in this
* {@link Grid}.
*
* @return unmodifiable collection of columns
*/
public Collection<Column<T, ?>> getColumns() {
return Collections.unmodifiableSet(columnSet);
}
}

+ 25
- 0
shared/src/main/java/com/vaadin/shared/ui/grid/ColumnState.java View File

@@ -0,0 +1,25 @@
/*
* 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.shared.ui.grid;

import com.vaadin.shared.communication.SharedState;

public class ColumnState extends SharedState {

public String caption;
public String id;
public boolean sortable;
}

+ 93
- 0
uitest/src/main/java/com/vaadin/tests/components/grid/basics/DataObject.java View File

@@ -0,0 +1,93 @@
package com.vaadin.tests.components.grid.basics;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

class DataObject {

private static final int ROWS = 1000;

private Integer rowNumber;
private String coordinates;
private String htmlString;
private Integer smallRandom;
private Integer bigRandom;
private Date date;

public Integer getRowNumber() {
return rowNumber;
}

public void setRowNumber(Integer rowNumber) {
this.rowNumber = rowNumber;
}

public String getCoordinates() {
return coordinates;
}

public void setCoordinates(String coordinates) {
this.coordinates = coordinates;
}

public String getHtmlString() {
return htmlString;
}

public void setHtmlString(String htmlString) {
this.htmlString = htmlString;
}

public Integer getSmallRandom() {
return smallRandom;
}

public void setSmallRandom(Integer smallRandom) {
this.smallRandom = smallRandom;
}

public Integer getBigRandom() {
return bigRandom;
}

public void setBigRandom(Integer bigRandom) {
this.bigRandom = bigRandom;
}

public Date getDate() {
return date;
}

public void setDate(Date date) {
this.date = date;
}

static List<DataObject> generateObjects() {
List<DataObject> data = new ArrayList<>();

{
Random rand = new Random();
rand.setSeed(13334);
long timestamp = 0;
for (int row = 0; row < ROWS; row++) {
DataObject obj = new DataObject();
obj.setRowNumber(row);
obj.setCoordinates("(" + row + ", " + 0 + ")");
obj.setHtmlString("<b>" + row + "</b>");
// Random numbers
obj.setBigRandom(rand.nextInt());
obj.setSmallRandom(rand.nextInt(5));

obj.setDate(new Date(timestamp));
timestamp += 91250000; // a bit over a day, just to get
// variation

data.add(obj);
}
}
return data;
}

}

+ 32
- 0
uitest/src/main/java/com/vaadin/tests/components/grid/basics/GridBasics.java View File

@@ -0,0 +1,32 @@
package com.vaadin.tests.components.grid.basics;

import java.util.Date;
import java.util.List;

import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUIWithLog;
import com.vaadin.ui.Grid;

public class GridBasics extends AbstractTestUIWithLog {

private Grid<DataObject> grid;

@Override
protected void setup(VaadinRequest request) {
List<DataObject> data = DataObject.generateObjects();

// Create grid
grid = new Grid<>();
grid.setItems(data);

grid.addColumn("Row Number", Integer.class, DataObject::getRowNumber);
grid.addColumn("Date", Date.class, DataObject::getDate);
grid.addColumn("HTML String", String.class, DataObject::getHtmlString);
grid.addColumn("Big Random", Integer.class, DataObject::getBigRandom);
grid.addColumn("Small Random", Integer.class,
DataObject::getSmallRandom);

addComponent(grid);
}

}

+ 45
- 0
uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridBasicsTest.java View File

@@ -0,0 +1,45 @@
package com.vaadin.tests.components.grid.basics;

import java.util.List;
import java.util.stream.Stream;

import org.junit.Before;
import org.openqa.selenium.remote.DesiredCapabilities;

import com.vaadin.testbench.elements.GridElement;
import com.vaadin.testbench.parallel.Browser;
import com.vaadin.tests.tb3.MultiBrowserTest;

/**
* Base class for all {@link GridBasics} UI tests
*/
public abstract class GridBasicsTest extends MultiBrowserTest {

/* Identical List of test data */
private List<DataObject> testData;

@Override
public List<DesiredCapabilities> getBrowsersToTest() {
// Most tests are run with only one browser.
return getBrowserCapabilities(Browser.PHANTOMJS);
}

@Override
protected Class<?> getUIClass() {
return GridBasics.class;
}

@Before
public void setUp() {
openTestURL();
testData = DataObject.generateObjects();
}

protected GridElement getGrid() {
return $(GridElement.class).first();
}

protected Stream<DataObject> getTestData() {
return testData.stream();
}
}

+ 17
- 0
uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridContentTest.java View File

@@ -0,0 +1,17 @@
package com.vaadin.tests.components.grid.basics;

import org.junit.Assert;
import org.junit.Test;

public class GridContentTest extends GridBasicsTest {

@Test(expected = AssertionError.class)
public void testHtmlRenderer() {
DataObject first = getTestData().findFirst().orElse(null);
Assert.assertEquals("Text content should match row number",
first.getRowNumber().toString(),
getGrid().getCell(0, 2).getText());
Assert.assertEquals("HTML content did not match", first.getHtmlString(),
getGrid().getCell(0, 2).getAttribute("innerHTML"));
}
}

+ 52
- 0
uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridSortingTest.java View File

@@ -0,0 +1,52 @@
package com.vaadin.tests.components.grid.basics;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

import org.junit.Assert;
import org.junit.Test;
import org.openqa.selenium.Keys;
import org.openqa.selenium.remote.DesiredCapabilities;

public class GridSortingTest extends GridBasicsTest {

public static final Comparator<DataObject> BIG_RANDOM = Comparator
.comparing(DataObject::getBigRandom);
public static final Comparator<DataObject> SMALL_RANDOM = Comparator
.comparing(DataObject::getSmallRandom);

@Override
public List<DesiredCapabilities> getBrowsersToTest() {
return getBrowsersSupportingShiftClick();
}

@Test
public void testSortBySingleColumnByUser() {
getGrid().getHeaderCell(0, 3).click();
int i = 0;
for (Integer rowNumber : getTestData().sorted(BIG_RANDOM)
.map(DataObject::getRowNumber).limit(5)
.collect(Collectors.toList())) {
Assert.assertEquals(
"Grid was not sorted as expected, row number mismatch",
rowNumber.toString(), getGrid().getCell(i++, 0).getText());
}
}

@Test
public void testSortByMultipleColumnsByUser() {
getGrid().getHeaderCell(0, 4).click();
getGrid().getHeaderCell(0, 3).click(15, 15, Keys.SHIFT);

int i = 0;
for (Integer rowNumber : getTestData()
.sorted(SMALL_RANDOM.thenComparing(BIG_RANDOM))
.map(DataObject::getRowNumber).limit(5)
.collect(Collectors.toList())) {
Assert.assertEquals(
"Grid was not sorted as expected, row number mismatch",
rowNumber.toString(), getGrid().getCell(i++, 0).getText());
}
}
}

Loading…
Cancel
Save