aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeemu Suo-Anttila <teemusa@vaadin.com>2016-02-02 11:23:58 +0200
committerTeemu Suo-Anttila <teemusa@vaadin.com>2016-02-03 12:22:07 +0200
commite25dd72efe36de7e59780cda0de472c1183be028 (patch)
tree66b8a6902be8093582205062c99aff34dddbc875
parent38396def32f9c58ce8b4c4d2df42310ef9b0605e (diff)
downloadvaadin-framework-e25dd72efe36de7e59780cda0de472c1183be028.tar.gz
vaadin-framework-e25dd72efe36de7e59780cda0de472c1183be028.zip
Add simple support for generic reset for data to DataProvider
Adds a simple test that sorts the data and verifies that the content does not actually change with just sorting. Change-Id: I0d8889694a98da1d55e0335714f63abaedb5684a
-rw-r--r--client/src/com/vaadin/client/connectors/data/typed/DataSourceConnector.java3
-rw-r--r--server/src/com/vaadin/server/communication/data/typed/DataProvider.java24
-rw-r--r--uitest/src/com/vaadin/tests/dataprovider/DummyDataProviderTest.java104
-rw-r--r--uitest/src/com/vaadin/tests/dataprovider/DummyDataProviderUI.java40
4 files changed, 155 insertions, 16 deletions
diff --git a/client/src/com/vaadin/client/connectors/data/typed/DataSourceConnector.java b/client/src/com/vaadin/client/connectors/data/typed/DataSourceConnector.java
index 59d72baa67..1d4521c5b3 100644
--- a/client/src/com/vaadin/client/connectors/data/typed/DataSourceConnector.java
+++ b/client/src/com/vaadin/client/connectors/data/typed/DataSourceConnector.java
@@ -59,7 +59,8 @@ public class DataSourceConnector extends AbstractExtensionConnector {
public void resetSize(long size) {
ds.asList().clear();
// Inform the server-side that all keys are now dropped.
- for (String key : keyToJson.keySet()) {
+ Set<String> keySet = new HashSet<String>(keyToJson.keySet());
+ for (String key : keySet) {
dropKey(key);
}
sendDroppedKeys();
diff --git a/server/src/com/vaadin/server/communication/data/typed/DataProvider.java b/server/src/com/vaadin/server/communication/data/typed/DataProvider.java
index e975792713..9417d0a1f0 100644
--- a/server/src/com/vaadin/server/communication/data/typed/DataProvider.java
+++ b/server/src/com/vaadin/server/communication/data/typed/DataProvider.java
@@ -197,8 +197,10 @@ public class DataProvider<T> extends AbstractExtension {
}
}
- private Collection<T> data;
private Collection<TypedDataGenerator<T>> generators = new LinkedHashSet<TypedDataGenerator<T>>();
+ private boolean reset = false;
+
+ private Collection<T> data;
private DataProviderClientRpc rpc;
// TODO: Allow customizing the used key mapper
private DataKeyMapper<T> keyMapper = new KeyMapper<T>();
@@ -220,17 +222,17 @@ public class DataProvider<T> extends AbstractExtension {
}
/**
- * Initially we need to push all the data to the client.
- *
- * TODO: The same is true for unknown size changes.
+ * Initially and in the case of a reset all data should be pushed to the
+ * client.
*/
@Override
public void beforeClientResponse(boolean initial) {
super.beforeClientResponse(initial);
- if (initial) {
+ if (initial || reset) {
getRpcProxy(DataProviderClientRpc.class).resetSize(data.size());
pushData(0, data);
+ reset = false;
}
}
@@ -355,4 +357,16 @@ public class DataProvider<T> extends AbstractExtension {
}
}
+ /**
+ * Informs the DataProvider that the collection has changed.
+ */
+ public void reset() {
+ if (reset) {
+ return;
+ }
+
+ reset = true;
+ markAsDirty();
+ }
+
}
diff --git a/uitest/src/com/vaadin/tests/dataprovider/DummyDataProviderTest.java b/uitest/src/com/vaadin/tests/dataprovider/DummyDataProviderTest.java
index 9771f7b0f6..e82f25ba04 100644
--- a/uitest/src/com/vaadin/tests/dataprovider/DummyDataProviderTest.java
+++ b/uitest/src/com/vaadin/tests/dataprovider/DummyDataProviderTest.java
@@ -17,7 +17,11 @@ package com.vaadin.tests.dataprovider;
import static org.junit.Assert.assertEquals;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Random;
import org.junit.Test;
@@ -25,6 +29,7 @@ import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import com.vaadin.shared.data.DataProviderConstants;
+import com.vaadin.testbench.elements.ButtonElement;
import com.vaadin.tests.fieldgroup.ComplexPerson;
import com.vaadin.tests.tb3.SingleBrowserTest;
@@ -33,6 +38,32 @@ import elemental.json.JsonObject;
public class DummyDataProviderTest extends SingleBrowserTest {
+ // Each test uses a set of person objects (generated json) that is supposed
+ // to match the data sent to the client-side.
+ private List<JsonObject> personObjects = new ArrayList<JsonObject>();
+ // Persons are created exactly the same way as in the test, so we should
+ // have identical data.
+ private List<ComplexPerson> persons = DummyDataProviderUI.createPersons(
+ DummyDataProviderUI.PERSON_COUNT, new Random(
+ DummyDataProviderUI.RANDOM_SEED));
+ // For each person we generate a string key, that should match the one
+ // DataProvider gives to it.
+ private Map<ComplexPerson, String> personToKeyMap = new HashMap<ComplexPerson, String>();
+
+ {
+ int key = 0;
+ for (ComplexPerson p : persons) {
+ personToKeyMap.put(p, "" + (++key));
+ }
+ }
+
+ @Override
+ public void setup() throws Exception {
+ super.setup();
+
+ setDebug(true);
+ }
+
@Override
protected Class<?> getUIClass() {
return DummyDataProviderUI.class;
@@ -40,9 +71,7 @@ public class DummyDataProviderTest extends SingleBrowserTest {
@Test
public void testVerifyJsonContent() {
- Random r = new Random(DummyDataProviderUI.RANDOM_SEED);
- List<ComplexPerson> persons = DummyDataProviderUI.createPersons(
- DummyDataProviderUI.PERSON_COUNT, r);
+ createPersonObjects();
openTestURL();
@@ -54,13 +83,74 @@ public class DummyDataProviderTest extends SingleBrowserTest {
List<WebElement> personData = labels.subList(1, size);
- int key = 0;
- for (WebElement e : personData) {
+ for (int i = 0; i < personData.size(); ++i) {
+ WebElement e = personData.get(i);
+ JsonObject j = personObjects.get(i);
+ assertEquals("Json did not match.", j.toJson(), e.getText());
+ }
+
+ assertNoErrorNotifications();
+ }
+
+ private void createPersonObjects() {
+ for (ComplexPerson p : persons) {
JsonObject j = Json.createObject();
- ComplexPerson p = persons.get(key);
- j.put(DataProviderConstants.KEY, "" + (++key));
+ j.put(DataProviderConstants.KEY, personToKeyMap.get(p));
j.put("name", p.getLastName() + ", " + p.getFirstName());
+ personObjects.add(j);
+ }
+ }
+
+ @Test
+ public void testSortDoesNotChangeContent() {
+ // Sort our internal data to match the order after sort.
+ Collections.sort(persons, DummyDataProviderUI.nameComparator);
+ createPersonObjects();
+
+ openTestURL();
+
+ $(ButtonElement.class).id("sort").click();
+
+ // Second sort would show if any keys got destroyed/recreated.
+ $(ButtonElement.class).id("sort").click();
+
+ int size = DummyDataProviderUI.PERSON_COUNT + 1;
+ List<WebElement> labels = findElements(By.className("v-label"));
+
+ assertEquals("Label count did not match person count", size,
+ labels.size());
+
+ List<WebElement> personData = labels.subList(1, size);
+
+ for (int i = 0; i < personData.size(); ++i) {
+ WebElement e = personData.get(i);
+ JsonObject j = personObjects.get(i);
assertEquals("Json did not match.", j.toJson(), e.getText());
}
+
+ assertNoErrorNotifications();
+ }
+
+ @Test
+ public void testRemoveWorksAfterSort() {
+ // Sort our internal data to match the order after sort.
+ Collections.sort(persons, DummyDataProviderUI.nameComparator);
+ createPersonObjects();
+
+ openTestURL();
+
+ $(ButtonElement.class).id("sort").click();
+
+ String text = findElements(By.className("v-label")).get(3).getText();
+ String json = personObjects.get(2).toJson();
+ assertEquals("Data not sorted", json, text);
+
+ $(ButtonElement.class).id("remove").click();
+
+ text = findElements(By.className("v-label")).get(3).getText();
+ json = personObjects.get(3).toJson();
+ assertEquals("Data not removed", json, text);
+
+ assertNoErrorNotifications();
}
}
diff --git a/uitest/src/com/vaadin/tests/dataprovider/DummyDataProviderUI.java b/uitest/src/com/vaadin/tests/dataprovider/DummyDataProviderUI.java
index 26a0277274..095f4d694c 100644
--- a/uitest/src/com/vaadin/tests/dataprovider/DummyDataProviderUI.java
+++ b/uitest/src/com/vaadin/tests/dataprovider/DummyDataProviderUI.java
@@ -17,6 +17,8 @@ package com.vaadin.tests.dataprovider;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.List;
import java.util.Random;
@@ -41,10 +43,14 @@ public class DummyDataProviderUI extends AbstractTestUI {
public static class DummyDataComponent extends AbstractComponent {
private DataProvider<ComplexPerson> dataProvider;
- private Collection<ComplexPerson> data;
+ private List<ComplexPerson> data;
public DummyDataComponent(Collection<ComplexPerson> data) {
- this.data = data;
+ if (data instanceof List) {
+ this.data = (List<ComplexPerson>) data;
+ } else {
+ this.data = new ArrayList<ComplexPerson>(data);
+ }
dataProvider = DataProvider.create(data, this);
dataProvider
.addDataGenerator(new TypedDataGenerator<ComplexPerson>() {
@@ -74,10 +80,25 @@ public class DummyDataProviderUI extends AbstractTestUI {
dataProvider.remove(person);
}
}
+
+ public void sort(Comparator<ComplexPerson> comparator) {
+ Collections.sort(data, comparator);
+ dataProvider.reset();
+ }
}
public static final int RANDOM_SEED = 1337;
public static final int PERSON_COUNT = 20;
+ public static final Comparator<ComplexPerson> nameComparator = new Comparator<ComplexPerson>() {
+
+ @Override
+ public int compare(ComplexPerson p1, ComplexPerson p2) {
+ int fn = p1.getFirstName().compareTo(p2.getFirstName());
+ int ln = p1.getLastName().compareTo(p2.getLastName());
+ return fn != 0 ? fn : ln;
+ }
+ };
+
private Random r = new Random(RANDOM_SEED);
private List<ComplexPerson> persons = createPersons(PERSON_COUNT, r);
private DummyDataComponent dummy;
@@ -100,7 +121,20 @@ public class DummyDataProviderUI extends AbstractTestUI {
dummy.addItem(ComplexPerson.create(r));
}
});
- addComponent(new HorizontalLayout(add, remove));
+ Button sort = new Button("Sort content", new ClickListener() {
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ dummy.sort(nameComparator);
+ }
+ });
+
+ // Button Ids
+ remove.setId("remove");
+ add.setId("add");
+ sort.setId("sort");
+
+ addComponent(new HorizontalLayout(add, remove, sort));
addComponent(dummy);
}