Browse Source

Redesign RpcDataSourceConnector pinning RPC requests (#18692)

This patch removes DataProviderKeyMapper which was mostly dead code
already. Uses a regular KeyMapper instead.

Change-Id: Ic97d1dc827d45fde65bcddc0414bfe711032620c
tags/7.6.0.alpha5
Teemu Suo-Anttila 8 years ago
parent
commit
ac66a3d174

+ 49
- 26
client/src/com/vaadin/client/connectors/MultiSelectionModelConnector.java View File

@@ -156,19 +156,16 @@ public class MultiSelectionModelConnector extends
public void selectAll() {
assert !isBeingBatchSelected() : "Can't select all in middle of a batch selection.";

Set<RowHandle<JsonObject>> rows = new HashSet<DataSource.RowHandle<JsonObject>>();
DataSource<JsonObject> dataSource = getGrid().getDataSource();
for (int i = availableRows.getStart(); i < availableRows.getEnd(); ++i) {
final JsonObject row = dataSource.getRow(i);
if (row != null) {
RowHandle<JsonObject> handle = dataSource.getHandle(row);
markAsSelected(handle, true);
rows.add(handle);
}
}

getRpcProxy(MultiSelectionModelServerRpc.class).selectAll();
cleanRowCache(rows);
}

@Override
@@ -205,19 +202,16 @@ public class MultiSelectionModelConnector extends
public boolean deselectAll() {
assert !isBeingBatchSelected() : "Can't select all in middle of a batch selection.";

Set<RowHandle<JsonObject>> rows = new HashSet<DataSource.RowHandle<JsonObject>>();
DataSource<JsonObject> dataSource = getGrid().getDataSource();
for (int i = availableRows.getStart(); i < availableRows.getEnd(); ++i) {
final JsonObject row = dataSource.getRow(i);
if (row != null) {
RowHandle<JsonObject> handle = dataSource.getHandle(row);
markAsSelected(handle, false);
rows.add(handle);
}
}

getRpcProxy(MultiSelectionModelServerRpc.class).deselectAll();
cleanRowCache(rows);

return true;
}
@@ -235,8 +229,9 @@ public class MultiSelectionModelConnector extends

for (JsonObject row : rows) {
RowHandle<JsonObject> rowHandle = getRowHandle(row);
markAsSelected(rowHandle, true);
selected.add(rowHandle);
if (markAsSelected(rowHandle, true)) {
selected.add(rowHandle);
}
}

if (!isBeingBatchSelected()) {
@@ -246,23 +241,35 @@ public class MultiSelectionModelConnector extends
}

/**
* Marks the JsonObject pointed by RowHandle to have selected
* information equal to given boolean
* Marks the given row to be selected or deselected. Returns true if the
* value actually changed.
* <p>
* Note: If selection model is in batch select state, the row will be
* pinned on select.
*
* @param row
* row handle
* @param selected
* should row be selected
* {@code true} if row should be selected; {@code false} if
* not
* @return {@code true} if selected status changed; {@code false} if not
*/
protected void markAsSelected(RowHandle<JsonObject> row,
protected boolean markAsSelected(RowHandle<JsonObject> row,
boolean selected) {
row.pin();
if (selected) {
if (selected && !isSelected(row.getRow())) {
row.getRow().put(GridState.JSONKEY_SELECTED, true);
} else {
} else if (!selected && isSelected(row.getRow())) {
row.getRow().remove(GridState.JSONKEY_SELECTED);
} else {
return false;
}

row.updateRow();

if (isBeingBatchSelected()) {
row.pin();
}
return true;
}

/**
@@ -278,8 +285,9 @@ public class MultiSelectionModelConnector extends

for (JsonObject row : rows) {
RowHandle<JsonObject> rowHandle = getRowHandle(row);
markAsSelected(rowHandle, false);
deselected.add(rowHandle);
if (markAsSelected(rowHandle, false)) {
deselected.add(rowHandle);
}
}

if (!isBeingBatchSelected()) {
@@ -288,16 +296,38 @@ public class MultiSelectionModelConnector extends
return true;
}

/**
* Sends a deselect RPC call to server-side containing all deselected
* rows. Unpins any pinned rows.
*/
private void sendDeselected() {
getRpcProxy(MultiSelectionModelServerRpc.class).deselect(
getRowKeys(deselected));
cleanRowCache(deselected);

if (isBeingBatchSelected()) {
for (RowHandle<JsonObject> row : deselected) {
row.unpin();
}
}

deselected.clear();
}

/**
* Sends a select RPC call to server-side containing all selected rows.
* Unpins any pinned rows.
*/
private void sendSelected() {
getRpcProxy(MultiSelectionModelServerRpc.class).select(
getRowKeys(selected));
cleanRowCache(selected);

if (isBeingBatchSelected()) {
for (RowHandle<JsonObject> row : selected) {
row.unpin();
}
}

selected.clear();
}

private List<String> getRowKeys(Set<RowHandle<JsonObject>> handles) {
@@ -316,13 +346,6 @@ public class MultiSelectionModelConnector extends
return rows;
}

private void cleanRowCache(Set<RowHandle<JsonObject>> handles) {
for (RowHandle<JsonObject> handle : handles) {
handle.unpin();
}
handles.clear();
}

@Override
public void startBatchSelect() {
assert selected.isEmpty() && deselected.isEmpty() : "Row caches were not clear.";

+ 7
- 13
client/src/com/vaadin/client/connectors/RpcDataSourceConnector.java View File

@@ -189,24 +189,16 @@ public class RpcDataSourceConnector extends AbstractExtensionConnector {
return new RowHandleImpl(row, key);
}

@Override
protected void pinHandle(RowHandleImpl handle) {
// Server only knows if something is pinned or not. No need to pin
// multiple times.
boolean pinnedBefore = handle.isPinned();
super.pinHandle(handle);
if (!pinnedBefore) {
rpcProxy.setPinned(getRowKey(handle.getRow()), true);
}
}

@Override
protected void unpinHandle(RowHandleImpl handle) {
// Row data is no longer available after it has been unpinned.
String key = getRowKey(handle.getRow());
super.unpinHandle(handle);
if (!handle.isPinned()) {
rpcProxy.setPinned(key, false);
if (indexOfKey(key) == -1) {
// Row out of view has been unpinned. drop it
droppedRowKeys.set(droppedRowKeys.length(), key);
}
}
}

@@ -244,7 +236,9 @@ public class RpcDataSourceConnector extends AbstractExtensionConnector {

@Override
protected void onDropFromCache(int rowIndex, JsonObject row) {
droppedRowKeys.set(droppedRowKeys.length(), getRowKey(row));
if (!((RowHandleImpl) getHandle(row)).isPinned()) {
droppedRowKeys.set(droppedRowKeys.length(), getRowKey(row));
}
}
}


+ 1
- 9
client/src/com/vaadin/client/data/AbstractRemoteDataSource.java View File

@@ -16,8 +16,6 @@

package com.vaadin.client.data;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -120,12 +118,7 @@ public abstract class AbstractRemoteDataSource<T> implements DataSource<T> {

@Override
public T getRow() throws IllegalStateException {
if (isPinned()) {
return row;
} else {
throw new IllegalStateException("The row handle for key " + key
+ " was not pinned");
}
return row;
}

public boolean isPinned() {
@@ -197,7 +190,6 @@ public abstract class AbstractRemoteDataSource<T> implements DataSource<T> {

private Map<Object, Integer> pinnedCounts = new HashMap<Object, Integer>();
private Map<Object, RowHandleImpl> pinnedRows = new HashMap<Object, RowHandleImpl>();
protected Collection<T> temporarilyPinnedRows = Collections.emptySet();

// Size not yet known
private int size = -1;

+ 22
- 227
server/src/com/vaadin/data/RpcDataProviderExtension.java View File

@@ -21,14 +21,11 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.gwt.thirdparty.guava.common.collect.BiMap;
import com.google.gwt.thirdparty.guava.common.collect.HashBiMap;
import com.google.gwt.thirdparty.guava.common.collect.ImmutableSet;
import com.google.gwt.thirdparty.guava.common.collect.Maps;
import com.google.gwt.thirdparty.guava.common.collect.Sets;
@@ -43,6 +40,7 @@ import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.Property.ValueChangeNotifier;
import com.vaadin.server.AbstractExtension;
import com.vaadin.server.ClientConnector;
import com.vaadin.server.KeyMapper;
import com.vaadin.shared.data.DataProviderRpc;
import com.vaadin.shared.data.DataRequestRpc;
import com.vaadin.shared.ui.grid.GridClientRpc;
@@ -70,215 +68,22 @@ import elemental.json.JsonObject;
*/
public class RpcDataProviderExtension extends AbstractExtension {

/**
* ItemId to Key to ItemId mapper.
* <p>
* This class is used when transmitting information about items in container
* related to Grid. It introduces a consistent way of mapping ItemIds and
* its container to a String that can be mapped back to ItemId.
* <p>
* <em>Technical note:</em> This class also keeps tabs on which indices are
* being shown/selected, and is able to clean up after itself once the
* itemId &lrarr; key mapping is not needed anymore. In other words, this
* doesn't leak memory.
*/
public class DataProviderKeyMapper implements Serializable, DataGenerator {
private final BiMap<Object, String> itemIdToKey = HashBiMap.create();
private Set<Object> pinnedItemIds = new HashSet<Object>();
private long rollingIndex = 0;

private DataProviderKeyMapper() {
// private implementation
}

private String nextKey() {
return String.valueOf(rollingIndex++);
}

/**
* Gets the key for a given item id. Creates a new key mapping if no
* existing mapping was found for the given item id.
*
* @since 7.5.0
* @param itemId
* the item id to get the key for
* @return the key for the given item id
*/
public String getKey(Object itemId) {
String key = itemIdToKey.get(itemId);
if (key == null) {
key = nextKey();
itemIdToKey.put(itemId, key);
}
return key;
}

/**
* Gets keys for a collection of item ids.
* <p>
* If the itemIds are currently cached, the existing keys will be used.
* Otherwise new ones will be created.
*
* @param itemIds
* the item ids for which to get keys
* @return keys for the {@code itemIds}
*/
public List<String> getKeys(Collection<?> itemIds) {
if (itemIds == null) {
throw new IllegalArgumentException("itemIds can't be null");
}

ArrayList<String> keys = new ArrayList<String>(itemIds.size());
for (Object itemId : itemIds) {
keys.add(getKey(itemId));
}
return keys;
}

/**
* Gets the registered item id based on its key.
* <p>
* A key is used to identify a particular row on both a server and a
* client. This method can be used to get the item id for the row key
* that the client has sent.
*
* @param key
* the row key for which to retrieve an item id
* @return the item id corresponding to {@code key}
* @throws IllegalStateException
* if the key mapper does not have a record of {@code key} .
*/
public Object getItemId(String key) throws IllegalStateException {
Object itemId = itemIdToKey.inverse().get(key);
if (itemId != null) {
return itemId;
} else {
throw new IllegalStateException("No item id for key " + key
+ " found.");
}
}

/**
* Gets corresponding item ids for each of the keys in a collection.
*
* @param keys
* the keys for which to retrieve item ids
* @return a collection of item ids for the {@code keys}
* @throws IllegalStateException
* if one or more of keys don't have a corresponding item id
* in the cache
*/
public Collection<Object> getItemIds(Collection<String> keys)
throws IllegalStateException {
if (keys == null) {
throw new IllegalArgumentException("keys may not be null");
}

ArrayList<Object> itemIds = new ArrayList<Object>(keys.size());
for (String key : keys) {
itemIds.add(getItemId(key));
}
return itemIds;
}

/**
* Pin an item id to be cached indefinitely.
* <p>
* Normally when an itemId is not an active row, it is discarded from
* the cache. Pinning an item id will make sure that it is kept in the
* cache.
* <p>
* In effect, while an item id is pinned, it always has the same key.
*
* @param itemId
* the item id to pin
* @throws IllegalStateException
* if {@code itemId} was already pinned
* @see #unpin(Object)
* @see #isPinned(Object)
* @see #getItemIds(Collection)
*/
public void pin(Object itemId) throws IllegalStateException {
if (isPinned(itemId)) {
throw new IllegalStateException("Item id " + itemId
+ " was pinned already");
}
pinnedItemIds.add(itemId);
}

/**
* Unpin an item id.
* <p>
* This cancels the effect of pinning an item id. If the item id is
* currently inactive, it will be immediately removed from the cache.
*
* @param itemId
* the item id to unpin
* @throws IllegalStateException
* if {@code itemId} was not pinned
* @see #pin(Object)
* @see #isPinned(Object)
* @see #getItemIds(Collection)
*/
public void unpin(Object itemId) throws IllegalStateException {
if (!isPinned(itemId)) {
throw new IllegalStateException("Item id " + itemId
+ " was not pinned");
}

pinnedItemIds.remove(itemId);
}

/**
* Checks whether an item id is pinned or not.
*
* @param itemId
* the item id to check for pin status
* @return {@code true} iff the item id is currently pinned
*/
public boolean isPinned(Object itemId) {
return pinnedItemIds.contains(itemId);
}

/**
* {@inheritDoc}
*
* @since 7.6
*/
@Override
public void generateData(Object itemId, Item item, JsonObject rowData) {
rowData.put(GridState.JSONKEY_ROWKEY, getKey(itemId));
}

/**
* Removes all inactive item id to key mapping from the key mapper.
*
* @since 7.6
*/
public void dropInactiveItems() {
Collection<Object> active = activeItemHandler.getActiveItemIds();
Iterator<Object> itemIter = itemIdToKey.keySet().iterator();
while (itemIter.hasNext()) {
Object itemId = itemIter.next();
if (!active.contains(itemId) && !isPinned(itemId)) {
itemIter.remove();
}
}
}
}

/**
* Class for keeping track of current items and ValueChangeListeners.
*
* @since 7.6
*/
private class ActiveItemHandler implements Serializable {
private class ActiveItemHandler implements Serializable, DataGenerator {

private final Map<Object, GridValueChangeListener> activeItemMap = new HashMap<Object, GridValueChangeListener>();
private final KeyMapper<Object> keyMapper = new KeyMapper<Object>();
private final Set<Object> droppedItems = new HashSet<Object>();

/**
* Registers ValueChangeListeners for given items ids.
* Registers ValueChangeListeners for given item ids.
* <p>
* Note: This method will clean up any unneeded listeners and key
* mappings
*
* @param itemIds
* collection of new active item ids
@@ -293,7 +98,7 @@ public class RpcDataProviderExtension extends AbstractExtension {

// Remove still active rows that were "dropped"
droppedItems.removeAll(itemIds);
dropListeners(droppedItems);
internalDropActiveItems(droppedItems);
droppedItems.clear();
}

@@ -310,11 +115,12 @@ public class RpcDataProviderExtension extends AbstractExtension {
}
}

private void dropListeners(Collection<Object> itemIds) {
private void internalDropActiveItems(Collection<Object> itemIds) {
for (Object itemId : droppedItems) {
assert activeItemMap.containsKey(itemId) : "Item ID should exist in the activeItemMap";

activeItemMap.remove(itemId).removeListener();
keyMapper.remove(itemId);
}
}

@@ -335,6 +141,12 @@ public class RpcDataProviderExtension extends AbstractExtension {
public Collection<GridValueChangeListener> getValueChangeListeners() {
return new HashSet<GridValueChangeListener>(activeItemMap.values());
}

@Override
public void generateData(Object itemId, Item item, JsonObject rowData) {
rowData.put(GridState.JSONKEY_ROWKEY, keyMapper.key(itemId));
}

}

/**
@@ -635,8 +447,6 @@ public class RpcDataProviderExtension extends AbstractExtension {
}
};

private final DataProviderKeyMapper keyMapper = new DataProviderKeyMapper();

/** RpcDataProvider should send the current cache again. */
private boolean refreshCache = false;

@@ -683,25 +493,11 @@ public class RpcDataProviderExtension extends AbstractExtension {
cacheSize);
}

@Override
public void setPinned(String key, boolean isPinned) {
Object itemId = keyMapper.getItemId(key);
if (isPinned) {
// Row might already be pinned if it was selected from the
// server
if (!keyMapper.isPinned(itemId)) {
keyMapper.pin(itemId);
}
} else {
keyMapper.unpin(itemId);
}
}

@Override
public void dropRows(JsonArray rowKeys) {
for (int i = 0; i < rowKeys.length(); ++i) {
activeItemHandler.dropActiveItem(keyMapper
.getItemId(rowKeys.getString(i)));
activeItemHandler.dropActiveItem(getKeyMapper().get(
rowKeys.getString(i)));
}
}
});
@@ -711,7 +507,7 @@ public class RpcDataProviderExtension extends AbstractExtension {
.addItemSetChangeListener(itemListener);
}

addDataGenerator(keyMapper);
addDataGenerator(activeItemHandler);
addDataGenerator(detailComponentManager);
}

@@ -787,7 +583,6 @@ public class RpcDataProviderExtension extends AbstractExtension {
rpc.setRowData(firstRowToPush, rows);

activeItemHandler.addActiveItems(itemIds);
keyMapper.dropInactiveItems();
}

private JsonObject getRowData(Collection<Column> columns, Object itemId) {
@@ -939,7 +734,7 @@ public class RpcDataProviderExtension extends AbstractExtension {
public void setParent(ClientConnector parent) {
if (parent == null) {
// We're being detached, release various listeners
activeItemHandler.dropListeners(activeItemHandler
activeItemHandler.internalDropActiveItems(activeItemHandler
.getActiveItemIds());

if (container instanceof ItemSetChangeNotifier) {
@@ -987,8 +782,8 @@ public class RpcDataProviderExtension extends AbstractExtension {
refreshCache();
}

public DataProviderKeyMapper getKeyMapper() {
return keyMapper;
public KeyMapper<Object> getKeyMapper() {
return activeItemHandler.keyMapper;
}

protected Grid getGrid() {

+ 9
- 10
server/src/com/vaadin/ui/Grid.java View File

@@ -57,7 +57,6 @@ import com.vaadin.data.DataGenerator;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.RpcDataProviderExtension;
import com.vaadin.data.RpcDataProviderExtension.DataProviderKeyMapper;
import com.vaadin.data.RpcDataProviderExtension.DetailComponentManager;
import com.vaadin.data.Validator.InvalidValueException;
import com.vaadin.data.fieldgroup.DefaultFieldGroupFieldFactory;
@@ -3856,7 +3855,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
* @return the item id corresponding to {@code key}
*/
protected Object getItemId(String rowKey) {
return getParentGrid().getKeyMapper().getItemId(rowKey);
return getParentGrid().getKeyMapper().get(rowKey);
}

/**
@@ -4139,7 +4138,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
@Override
public void itemClick(String rowKey, String columnId,
MouseEventDetails details) {
Object itemId = getKeyMapper().getItemId(rowKey);
Object itemId = getKeyMapper().get(rowKey);
Item item = datasource.getItem(itemId);
Object propertyId = getPropertyIdByColumnId(columnId);
fireEvent(new ItemClickEvent(Grid.this, item, itemId,
@@ -4222,20 +4221,20 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,

@Override
public void editorOpen(String rowKey) {
fireEvent(new EditorOpenEvent(Grid.this, getKeyMapper()
.getItemId(rowKey)));
fireEvent(new EditorOpenEvent(Grid.this, getKeyMapper().get(
rowKey)));
}

@Override
public void editorMove(String rowKey) {
fireEvent(new EditorMoveEvent(Grid.this, getKeyMapper()
.getItemId(rowKey)));
fireEvent(new EditorMoveEvent(Grid.this, getKeyMapper().get(
rowKey)));
}

@Override
public void editorClose(String rowKey) {
fireEvent(new EditorCloseEvent(Grid.this, getKeyMapper()
.getItemId(rowKey)));
fireEvent(new EditorCloseEvent(Grid.this, getKeyMapper().get(
rowKey)));
}
});

@@ -5299,7 +5298,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
*
* @return the key mapper being used by the data source
*/
DataProviderKeyMapper getKeyMapper() {
KeyMapper<Object> getKeyMapper() {
return datasourceExtension.getKeyMapper();
}


+ 0
- 88
server/tests/src/com/vaadin/tests/server/component/grid/DataProviderExtension.java View File

@@ -1,88 +0,0 @@
/*
* Copyright 2000-2014 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 static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.Arrays;

import org.junit.Before;
import org.junit.Test;

import com.vaadin.data.Container;
import com.vaadin.data.Container.Indexed;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.RpcDataProviderExtension;
import com.vaadin.data.RpcDataProviderExtension.DataProviderKeyMapper;
import com.vaadin.data.util.IndexedContainer;

public class DataProviderExtension {
private RpcDataProviderExtension dataProvider;
private DataProviderKeyMapper keyMapper;
private Container.Indexed container;

private static final Object ITEM_ID1 = "itemid1";
private static final Object ITEM_ID2 = "itemid2";
private static final Object ITEM_ID3 = "itemid3";

private static final Object PROPERTY_ID1_STRING = "property1";

@Before
public void setup() {
container = new IndexedContainer();
populate(container);

dataProvider = new RpcDataProviderExtension(container);
keyMapper = dataProvider.getKeyMapper();
}

private static void populate(Indexed container) {
container.addContainerProperty(PROPERTY_ID1_STRING, String.class, "");
for (Object itemId : Arrays.asList(ITEM_ID1, ITEM_ID2, ITEM_ID3)) {
final Item item = container.addItem(itemId);
@SuppressWarnings("unchecked")
final Property<String> stringProperty = item
.getItemProperty(PROPERTY_ID1_STRING);
stringProperty.setValue(itemId.toString());
}
}

@Test
public void pinBasics() {
assertFalse("itemId1 should not start as pinned",
keyMapper.isPinned(ITEM_ID2));

keyMapper.pin(ITEM_ID1);
assertTrue("itemId1 should now be pinned", keyMapper.isPinned(ITEM_ID1));

keyMapper.unpin(ITEM_ID1);
assertFalse("itemId1 should not be pinned anymore",
keyMapper.isPinned(ITEM_ID2));
}

@Test(expected = IllegalStateException.class)
public void doublePinning() {
keyMapper.pin(ITEM_ID1);
keyMapper.pin(ITEM_ID1);
}

@Test(expected = IllegalStateException.class)
public void nonexistentUnpin() {
keyMapper.unpin(ITEM_ID1);
}
}

+ 0
- 14
shared/src/com/vaadin/shared/data/DataRequestRpc.java View File

@@ -46,20 +46,6 @@ public interface DataRequestRpc extends ServerRpc {
public void requestRows(int firstRowIndex, int numberOfRows,
int firstCachedRowIndex, int cacheSize);

/**
* Informs the server that an item referenced with a key pinned status has
* changed. This is a delayed call that happens along with next rpc call to
* server.
*
* @param key
* key mapping to item
* @param isPinned
* pinned status of referenced item
*/
@Delayed
@NoLoadingIndicator
public void setPinned(String key, boolean isPinned);

/**
* Informs the server that items have been dropped from the client cache.
*

+ 2
- 2
uitest/src/com/vaadin/tests/components/grid/CustomRendererTest.java View File

@@ -47,8 +47,8 @@ public class CustomRendererTest extends MultiBrowserTest {
.getText());

grid.getCell(0, 1).click();
assertEquals("row: 0, key: 0", grid.getCell(0, 1).getText());
assertEquals("key: 0, itemId: " + CustomRenderer.ITEM_ID,
assertEquals("row: 0, key: 1", grid.getCell(0, 1).getText());
assertEquals("key: 1, itemId: " + CustomRenderer.ITEM_ID,
findDebugLabel().getText());
}


+ 1
- 1
uitest/src/com/vaadin/tests/components/grid/JavaScriptRenderersTest.java View File

@@ -43,6 +43,6 @@ public class JavaScriptRenderersTest extends MultiBrowserTest {
// Verify onbrowserevent
cell_1_1.click();
Assert.assertTrue(cell_1_1.getText().startsWith(
"Clicked 1 with key 1 at"));
"Clicked 1 with key 2 at"));
}
}

Loading…
Cancel
Save