Adding AbstractListViewAdapter#getViews() to get the views associated with an adapter. Also adding some tests for com.google.gwt.view.client.
Review at http://gwt-code-reviews.appspot.com/601801
Review by: jgw@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@8292 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/cellview/client/CellListImpl.java b/user/src/com/google/gwt/user/cellview/client/CellListImpl.java
index 3ac00f5..6ab24d4 100644
--- a/user/src/com/google/gwt/user/cellview/client/CellListImpl.java
+++ b/user/src/com/google/gwt/user/cellview/client/CellListImpl.java
@@ -22,7 +22,6 @@
import com.google.gwt.view.client.PagingListView;
import com.google.gwt.view.client.Range;
import com.google.gwt.view.client.SelectionModel;
-import com.google.gwt.view.client.AbstractListViewAdapter.DefaultRange;
import com.google.gwt.view.client.ListView.Delegate;
import com.google.gwt.view.client.PagingListView.Pager;
import com.google.gwt.view.client.SelectionModel.SelectionChangeEvent;
@@ -196,7 +195,7 @@
* @return the range of data being displayed
*/
public Range getRange() {
- return new DefaultRange(pageStart, pageSize);
+ return new Range(pageStart, pageSize);
}
public SelectionModel<? super T> getSelectionModel() {
diff --git a/user/src/com/google/gwt/view/client/AbstractListViewAdapter.java b/user/src/com/google/gwt/view/client/AbstractListViewAdapter.java
index 370aae4..bf3dc38 100644
--- a/user/src/com/google/gwt/view/client/AbstractListViewAdapter.java
+++ b/user/src/com/google/gwt/view/client/AbstractListViewAdapter.java
@@ -1,12 +1,12 @@
/*
* Copyright 2010 Google Inc.
- *
+ *
* 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
@@ -15,14 +15,14 @@
*/
package com.google.gwt.view.client;
-import java.io.Serializable;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* A base implementation of a data source for list views.
- *
+ *
* <p>
* Note: This class is new and its interface subject to change.
* </p>
@@ -31,39 +31,6 @@
*/
public abstract class AbstractListViewAdapter<T> implements ProvidesKey<T> {
- /**
- * The range of interest for a single handler.
- */
- public static class DefaultRange implements Range, Serializable {
- private int length;
- private int start;
-
- /**
- * TODO: doc.
- *
- * @param start
- * @param length
- */
- public DefaultRange(int start, int length) {
- this.start = start;
- this.length = length;
- }
-
- /**
- * Used by RPC.
- */
- DefaultRange() {
- }
-
- public int getLength() {
- return length;
- }
-
- public int getStart() {
- return start;
- }
- }
-
private class Delegate implements ListView.Delegate<T> {
public void onRangeChanged(ListView<T> view) {
AbstractListViewAdapter.this.onRangeChanged(view);
@@ -80,9 +47,9 @@
private ProvidesKey<T> keyProvider;
/**
- * Adds a view to this adapter. The current range of interest of the view
- * will be populated with data.
- *
+ * Adds a view to this adapter. The current range of interest of the view will
+ * be populated with data.
+ *
* @param view a {@Link ListView}.
*/
public void addView(ListView<T> view) {
@@ -97,7 +64,7 @@
/**
* Get the key for a list item. The default implementation returns the item
* itself.
- *
+ *
* @param item the list item
* @return the key that represents the item
*/
@@ -107,7 +74,7 @@
/**
* Get the {@link ProvidesKey} that provides keys for list items.
- *
+ *
* @return the {@link ProvidesKey}
*/
public ProvidesKey<T> getKeyProvider() {
@@ -116,7 +83,7 @@
/**
* Get the current ranges of all views.
- *
+ *
* @return the ranges
*/
public Range[] getRanges() {
@@ -128,6 +95,15 @@
return ranges;
}
+ /**
+ * Get the set of views currently assigned to this adapter.
+ *
+ * @return the set of {@link ListView}
+ */
+ public Set<ListView<T>> getViews() {
+ return Collections.unmodifiableSet(views);
+ }
+
public void removeView(ListView<T> view) {
if (!views.contains(view)) {
throw new IllegalStateException("ListView not present");
@@ -138,7 +114,7 @@
/**
* Set the {@link ProvidesKey} that provides keys for list items.
- *
+ *
* @param keyProvider the {@link ProvidesKey}
*/
public void setKeyProvider(ProvidesKey<T> keyProvider) {
@@ -147,14 +123,14 @@
/**
* Called when a view changes its range of interest.
- *
+ *
* @param view the view whose range has changed
*/
protected abstract void onRangeChanged(ListView<T> view);
/**
* Inform the views of the total number of items that are available.
- *
+ *
* @param size the new size
* @param exact true if the size is exact, false if it is a guess
*/
@@ -166,7 +142,7 @@
/**
* Inform the views of the new data.
- *
+ *
* @param start the start index
* @param length the length of the data
* @param values the data values
@@ -179,13 +155,14 @@
/**
* Informs a single view of new data.
- *
+ *
* @param view the view to be updated
* @param start the start index
* @param length the length of the data
* @param values the data values
*/
- protected void updateViewData(ListView<T> view, int start, int length, List<T> values) {
+ protected void updateViewData(ListView<T> view, int start, int length,
+ List<T> values) {
int end = start + length;
Range range = view.getRange();
int curStart = range.getStart();
@@ -196,8 +173,8 @@
int realStart = curStart < start ? start : curStart;
int realEnd = curEnd > end ? end : curEnd;
int realLength = realEnd - realStart;
- List<T> realValues = values.subList(realStart - start, realStart
- - start + realLength);
+ List<T> realValues = values.subList(realStart - start, realStart - start
+ + realLength);
view.setData(realStart, realLength, realValues);
}
}
diff --git a/user/src/com/google/gwt/view/client/DefaultSelectionModel.java b/user/src/com/google/gwt/view/client/DefaultSelectionModel.java
index 84afb56..4284be8 100644
--- a/user/src/com/google/gwt/view/client/DefaultSelectionModel.java
+++ b/user/src/com/google/gwt/view/client/DefaultSelectionModel.java
@@ -86,9 +86,13 @@
/**
* Copies the exceptions map into a user-supplied map.
+ *
+ * @param output the user supplied map
+ * @return the user supplied map
*/
- protected void getExceptions(Map<Object, Boolean> output) {
+ protected Map<Object, Boolean> getExceptions(Map<Object, Boolean> output) {
output.clear();
output.putAll(exceptions);
+ return output;
}
}
diff --git a/user/src/com/google/gwt/view/client/Range.java b/user/src/com/google/gwt/view/client/Range.java
index 2ae98a0..8e38509 100644
--- a/user/src/com/google/gwt/view/client/Range.java
+++ b/user/src/com/google/gwt/view/client/Range.java
@@ -1,12 +1,12 @@
/*
* Copyright 2010 Google Inc.
- *
+ *
* 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
@@ -15,6 +15,8 @@
*/
package com.google.gwt.view.client;
+import java.io.Serializable;
+
/**
* The range of interest for a single handler.
*
@@ -22,19 +24,58 @@
* Note: This class is new and its interface subject to change.
* </p>
*/
-public interface Range {
+public class Range implements Serializable {
+
+ private int length;
+ private int start;
/**
- * Get the start index of the range.
- *
- * @return the start index
+ * Construct a new {@link Range}.
+ *
+ * @param start the start index
+ * @param length the length
*/
- int getStart();
+ public Range(int start, int length) {
+ this.start = start;
+ this.length = length;
+ }
+
+ /**
+ * Used by RPC.
+ */
+ Range() {
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || !(o instanceof Range)) {
+ return false;
+ }
+ Range r = (Range) o;
+ return start == r.getStart() && length == r.getLength();
+ }
/**
* Get the length of the range.
- *
+ *
* @return the length
*/
- int getLength();
+ public int getLength() {
+ return length;
+ }
+
+ /**
+ * Get the start index of the range.
+ *
+ * @return the start index
+ */
+ public int getStart() {
+ return start;
+ }
+
+ @Override
+ public int hashCode() {
+ return length == 0 ? new Double(start).hashCode() : new Double(start
+ + (1.0 / length)).hashCode();
+ }
}
diff --git a/user/test/com/google/gwt/view/client/AbstractListViewAdapterTest.java b/user/test/com/google/gwt/view/client/AbstractListViewAdapterTest.java
new file mode 100644
index 0000000..274e846
--- /dev/null
+++ b/user/test/com/google/gwt/view/client/AbstractListViewAdapterTest.java
@@ -0,0 +1,311 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * 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.google.gwt.view.client;
+
+import com.google.gwt.junit.client.GWTTestCase;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Test cases for {@link AbstractListViewAdapter}.
+ */
+public class AbstractListViewAdapterTest extends GWTTestCase {
+
+ /**
+ * A mock {@link AbstractListViewAdapter} used for testing.
+ *
+ * @param <T> the data type
+ */
+ static class MockListViewAdapter<T> extends AbstractListViewAdapter<T> {
+
+ private ListView<T> lastChanged;
+
+ public void assertLastRangeChanged(ListView<T> expected) {
+ assertEquals(expected, lastChanged);
+ }
+
+ public void clearLastRangeChanged() {
+ lastChanged = null;
+ }
+
+ @Override
+ protected void onRangeChanged(ListView<T> view) {
+ lastChanged = view;
+ }
+ }
+
+ @Override
+ public String getModuleName() {
+ return "com.google.gwt.view.View";
+ }
+
+ public void testAddRemoveView() {
+ MockListViewAdapter<String> adapter = new MockListViewAdapter<String>();
+
+ // Test with no views.
+ adapter.updateDataSize(10, true);
+ adapter.assertLastRangeChanged(null);
+
+ // Add the first view.
+ MockPagingListView<String> view0 = new MockPagingListView<String>();
+ adapter.addView(view0);
+ adapter.assertLastRangeChanged(view0);
+
+ // Add a second view.
+ MockPagingListView<String> view1 = new MockPagingListView<String>();
+ adapter.addView(view1);
+ adapter.assertLastRangeChanged(view1);
+
+ // Try to remove an invalid view.
+ MockPagingListView<String> invalidView = new MockPagingListView<String>();
+ try {
+ adapter.removeView(invalidView);
+ fail("Expected IllegalStateException");
+ } catch (IllegalStateException e) {
+ // Expected.
+ }
+
+ // Remove a valid view.
+ adapter.removeView(view1);
+
+ // Make sure the remaining view triggers the delegate.
+ adapter.assertLastRangeChanged(view1);
+ view0.setRange(100, 20);
+ view1.setRange(100, 20); // Shouldn't affect the adapter.
+ adapter.assertLastRangeChanged(view0);
+ }
+
+ public void testGetRanges() {
+ AbstractListViewAdapter<String> adapter = createListViewAdapter();
+
+ // No ranges.
+ {
+ Range[] ranges = adapter.getRanges();
+ assertEquals(0, ranges.length);
+ }
+
+ // One range.
+ {
+ MockPagingListView<String> view0 = new MockPagingListView<String>();
+ view0.setRange(0, 10);
+ adapter.addView(view0);
+ Range[] ranges = adapter.getRanges();
+ assertEquals(1, ranges.length);
+ assertEquals(new Range(0, 10), ranges[0]);
+ }
+
+ // Multiple ranges.
+ {
+ MockPagingListView<String> view1 = new MockPagingListView<String>();
+ view1.setRange(3, 10);
+ adapter.addView(view1);
+ MockPagingListView<String> view2 = new MockPagingListView<String>();
+ view2.setRange(30, 35);
+ adapter.addView(view2);
+ Set<Range> ranges = new HashSet<Range>();
+ for (Range range : adapter.getRanges()) {
+ ranges.add(range);
+ }
+ assertEquals(3, ranges.size());
+ assertTrue(ranges.contains(new Range(0, 10)));
+ assertTrue(ranges.contains(new Range(3, 10)));
+ assertTrue(ranges.contains(new Range(30, 35)));
+ }
+ }
+
+ public void testGetViews() {
+ AbstractListViewAdapter<String> adapter = createListViewAdapter();
+ MockPagingListView<String> view0 = new MockPagingListView<String>();
+ MockPagingListView<String> view1 = new MockPagingListView<String>();
+ assertEquals(0, adapter.getViews().size());
+
+ // Add two views.
+ adapter.addView(view0);
+ adapter.addView(view1);
+ Set<ListView<String>> views = adapter.getViews();
+ assertEquals(2, views.size());
+ assertTrue(views.contains(view0));
+ assertTrue(views.contains(view1));
+
+ // Remove one view.
+ adapter.removeView(view0);
+ views = adapter.getViews();
+ assertEquals(1, views.size());
+ assertTrue(views.contains(view1));
+ }
+
+ public void testSetKeyProvider() {
+ AbstractListViewAdapter<String> adapter = createListViewAdapter();
+
+ // By default, use the object as a key.
+ assertNull(adapter.getKeyProvider());
+ assertEquals("test", adapter.getKey("test"));
+ assertEquals(null, adapter.getKey(null));
+
+ // Defer to the key provider if one is set.
+ ProvidesKey<String> keyProvider = new ProvidesKey<String>() {
+ public Object getKey(String item) {
+ return item == null ? item : item.toUpperCase();
+ }
+ };
+ adapter.setKeyProvider(keyProvider);
+ assertEquals(keyProvider, adapter.getKeyProvider());
+ assertEquals("TEST", adapter.getKey("test"));
+ assertEquals(null, adapter.getKey(null));
+ }
+
+ public void testUpdateDataSize() {
+ AbstractListViewAdapter<String> adapter = createListViewAdapter();
+
+ // Test with no views.
+ adapter.updateDataSize(10, true);
+
+ // Add the first view.
+ MockPagingListView<String> view0 = new MockPagingListView<String>();
+ adapter.addView(view0);
+ adapter.updateDataSize(20, true);
+ assertEquals(20, view0.getDataSize());
+ assertTrue(view0.isDataSizeExact());
+
+ // Add another view.
+ MockPagingListView<String> view1 = new MockPagingListView<String>();
+ adapter.addView(view1);
+ adapter.updateDataSize(30, false);
+ assertEquals(30, view0.getDataSize());
+ assertFalse(view0.isDataSizeExact());
+ assertEquals(30, view1.getDataSize());
+ assertFalse(view1.isDataSizeExact());
+ }
+
+ public void testUpdateViewData() {
+ AbstractListViewAdapter<String> adapter = createListViewAdapter();
+ MockPagingListView<String> view = new MockPagingListView<String>();
+ view.setRange(10, 5);
+ adapter.addView(view);
+
+ // Data equal to range.
+ {
+ List<String> values = createData(10, 5);
+ adapter.updateViewData(10, 5, values);
+ assertEquals(values, view.getLastData());
+ assertEquals(new Range(10, 5), view.getLastDataRange());
+ view.clearLastDataAndRange();
+ }
+
+ // Data contained within range.
+ {
+ List<String> values = createData(12, 2);
+ adapter.updateViewData(12, 2, values);
+ assertEquals(values, view.getLastData());
+ assertEquals(new Range(12, 2), view.getLastDataRange());
+ view.clearLastDataAndRange();
+ }
+
+ // Data before range.
+ {
+ List<String> values = createData(5, 5);
+ adapter.updateViewData(5, 5, values);
+ assertNull(view.getLastData());
+ assertNull(view.getLastDataRange());
+ view.clearLastDataAndRange();
+ }
+
+ // Data after range.
+ {
+ List<String> values = createData(15, 5);
+ adapter.updateViewData(15, 5, values);
+ assertNull(view.getLastData());
+ assertNull(view.getLastDataRange());
+ view.clearLastDataAndRange();
+ }
+
+ // Data overlaps entire range.
+ {
+ List<String> values = createData(5, 15);
+ adapter.updateViewData(5, 15, values);
+ assertEquals(values.subList(5, 10), view.getLastData());
+ assertEquals(new Range(10, 5), view.getLastDataRange());
+ view.clearLastDataAndRange();
+ }
+
+ // Data overlaps start of range.
+ {
+ List<String> values = createData(5, 7);
+ adapter.updateViewData(5, 7, values);
+ assertEquals(values.subList(5, 7), view.getLastData());
+ assertEquals(new Range(10, 2), view.getLastDataRange());
+ view.clearLastDataAndRange();
+ }
+
+ // Data overlaps end of range.
+ {
+ List<String> values = createData(13, 5);
+ adapter.updateViewData(13, 5, values);
+ assertEquals(values.subList(0, 2), view.getLastData());
+ assertEquals(new Range(13, 2), view.getLastDataRange());
+ view.clearLastDataAndRange();
+ }
+ }
+
+ public void testUpdateViewDataMultipleViews() {
+ AbstractListViewAdapter<String> adapter = createListViewAdapter();
+ MockPagingListView<String> view0 = new MockPagingListView<String>();
+ view0.setRange(10, 5);
+ adapter.addView(view0);
+ MockPagingListView<String> view1 = new MockPagingListView<String>();
+ view1.setRange(0, 5);
+ adapter.addView(view1);
+ MockPagingListView<String> view2 = new MockPagingListView<String>();
+ view2.setRange(12, 10);
+ adapter.addView(view2);
+
+ List<String> values = createData(10, 5);
+ adapter.updateViewData(10, 5, values);
+ assertEquals(values, view0.getLastData());
+ assertEquals(new Range(10, 5), view0.getLastDataRange());
+ assertNull(view1.getLastData());
+ assertNull(view1.getLastDataRange());
+ assertEquals(values.subList(2, 5), view2.getLastData());
+ assertEquals(new Range(12, 3), view2.getLastDataRange());
+ }
+
+ /**
+ * Create an {@link AbstractListViewAdapter} for testing.
+ *
+ * @return the adapter
+ */
+ protected AbstractListViewAdapter<String> createListViewAdapter() {
+ return new MockListViewAdapter<String>();
+ }
+
+ /**
+ * Create a list of data for testing.
+ *
+ * @param start the start index
+ * @param length the length
+ * @return a list of data
+ */
+ protected List<String> createData(int start, int length) {
+ List<String> toRet = new ArrayList<String>();
+ for (int i = 0; i < length; i++) {
+ toRet.add("test " + (i + start));
+ }
+ return toRet;
+ }
+}
diff --git a/user/test/com/google/gwt/view/client/AsyncListViewAdapterTest.java b/user/test/com/google/gwt/view/client/AsyncListViewAdapterTest.java
new file mode 100644
index 0000000..d3fc895
--- /dev/null
+++ b/user/test/com/google/gwt/view/client/AsyncListViewAdapterTest.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * 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.google.gwt.view.client;
+
+/**
+ * Test cases for {@link AsyncListViewAdapter}.
+ */
+public class AsyncListViewAdapterTest extends AbstractListViewAdapterTest {
+
+ @Override
+ protected AsyncListViewAdapter<String> createListViewAdapter() {
+ return new AsyncListViewAdapter<String>() {
+ @Override
+ protected void onRangeChanged(ListView<String> view) {
+ }
+ };
+ }
+}
diff --git a/user/test/com/google/gwt/view/client/DefaultNodeInfoTest.java b/user/test/com/google/gwt/view/client/DefaultNodeInfoTest.java
new file mode 100644
index 0000000..8adb27b
--- /dev/null
+++ b/user/test/com/google/gwt/view/client/DefaultNodeInfoTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * 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.google.gwt.view.client;
+
+import com.google.gwt.cell.client.TextCell;
+import com.google.gwt.cell.client.ValueUpdater;
+import com.google.gwt.view.client.AbstractListViewAdapterTest.MockListViewAdapter;
+import com.google.gwt.view.client.TreeViewModel.DefaultNodeInfo;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link DefaultNodeInfo}.
+ */
+public class DefaultNodeInfoTest extends TestCase {
+
+ public void testAccessors() {
+ ListViewAdapter<String> adapter = new ListViewAdapter<String>();
+ TextCell cell = new TextCell();
+ SingleSelectionModel<String> selectionModel = new SingleSelectionModel<String>();
+ ValueUpdater<String> valueUpdater = new ValueUpdater<String>() {
+ public void update(String value) {
+ }
+ };
+ DefaultNodeInfo<String> nodeInfo = new DefaultNodeInfo<String>(adapter,
+ cell, selectionModel, valueUpdater);
+
+ assertEquals(adapter, nodeInfo.getProvidesKey());
+ assertEquals(cell, nodeInfo.getCell());
+ assertEquals(selectionModel, nodeInfo.getSelectionModel());
+ assertEquals(valueUpdater, nodeInfo.getValueUpdater());
+ }
+
+ public void testSetView() {
+ MockListViewAdapter<String> adapter = new MockListViewAdapter<String>();
+ DefaultNodeInfo<String> nodeInfo = new DefaultNodeInfo<String>(adapter,
+ new TextCell());
+ MockPagingListView<String> view = new MockPagingListView<String>();
+ view.setRange(0, 10);
+ view.clearLastDataAndRange();
+
+ // setView.
+ nodeInfo.setView(view);
+ adapter.assertLastRangeChanged(view);
+ adapter.clearLastRangeChanged();
+
+ view.setRange(0, 5);
+ adapter.assertLastRangeChanged(view);
+ adapter.clearLastRangeChanged();
+
+ // unsetView.
+ nodeInfo.unsetView();
+ view.setRange(0, 5);
+ adapter.assertLastRangeChanged(null);
+ }
+}
diff --git a/user/test/com/google/gwt/view/client/MockPagingListView.java b/user/test/com/google/gwt/view/client/MockPagingListView.java
new file mode 100644
index 0000000..b916ae5
--- /dev/null
+++ b/user/test/com/google/gwt/view/client/MockPagingListView.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * 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.google.gwt.view.client;
+
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.view.client.SelectionModel.SelectionChangeEvent;
+import com.google.gwt.view.client.SelectionModel.SelectionChangeHandler;
+
+import java.util.List;
+
+/**
+ * A mock {@link PagingListView} used for testing.
+ *
+ * @param <T> the data type
+ */
+public class MockPagingListView<T> implements PagingListView<T> {
+
+ private static final int DEFAULT_PAGE_SIZE = 10;
+
+ private int dataSize;
+ private boolean dataSizeExact;
+ private Delegate<T> delegate;
+ private List<T> lastData;
+ private Range lastRange;
+ private Pager<T> pager;
+ private int pageStart;
+ private int pageSize = DEFAULT_PAGE_SIZE;
+ private HandlerRegistration selectionHandler;
+ private SelectionModel<? super T> selectionModel;
+
+ /**
+ * Clear the last data set by {@link #setData(int, int, List)}.
+ */
+ public void clearLastDataAndRange() {
+ lastData = null;
+ lastRange = null;
+ }
+
+ public int getDataSize() {
+ return dataSize;
+ }
+
+ /**
+ * Get the last data set in {@link #setData(int, int, List)}.
+ *
+ * @return the last data set
+ */
+ public List<T> getLastData() {
+ return lastData;
+ }
+
+ /**
+ * Get the last data range set in {@link #setData(int, int, List)}.
+ *
+ * @return the last data range
+ */
+ public Range getLastDataRange() {
+ return lastRange;
+ }
+
+ public int getPageSize() {
+ return pageSize;
+ }
+
+ public int getPageStart() {
+ return pageStart;
+ }
+
+ public Range getRange() {
+ return new Range(pageStart, pageSize);
+ }
+
+ public SelectionModel<? super T> getSelectionModel() {
+ return selectionModel;
+ }
+
+ public boolean isDataSizeExact() {
+ return dataSizeExact;
+ }
+
+ public void setData(int start, int length, List<T> values) {
+ lastRange = new Range(start, length);
+ lastData = values;
+ }
+
+ public void setDataSize(int size, boolean isExact) {
+ if (this.dataSize == size && this.dataSizeExact == isExact) {
+ return;
+ }
+ this.dataSize = size;
+ this.dataSizeExact = isExact;
+ updatePager();
+ }
+
+ public void setDelegate(Delegate<T> delegate) {
+ this.delegate = delegate;
+ }
+
+ public void setPager(Pager<T> pager) {
+ this.pager = pager;
+ }
+
+ public void setPageSize(int pageSize) {
+ setRange(pageStart, pageSize);
+ }
+
+ public void setPageStart(int pageStart) {
+ setRange(pageStart, pageSize);
+ }
+
+ public void setRange(int start, int length) {
+ if (this.pageStart == start && this.pageSize == length) {
+ return;
+ }
+ this.pageStart = start;
+ this.pageSize = length;
+ updatePager();
+ updateDelegate();
+ }
+
+ public void setSelectionModel(SelectionModel<? super T> selectionModel) {
+ // Remove the old selection handler.
+ if (selectionHandler != null) {
+ selectionHandler.removeHandler();
+ selectionHandler = null;
+ }
+
+ // Add the new selection model.
+ this.selectionModel = selectionModel;
+ if (selectionModel != null) {
+ selectionHandler = selectionModel.addSelectionChangeHandler(new SelectionChangeHandler() {
+ public void onSelectionChange(SelectionChangeEvent event) {
+ }
+ });
+ }
+ }
+
+ /**
+ * Inform the delegate of the new range.
+ */
+ private void updateDelegate() {
+ if (delegate != null) {
+ delegate.onRangeChanged(this);
+ }
+ }
+
+ /**
+ * Inform the pager of the new range.
+ */
+ private void updatePager() {
+ if (pager != null) {
+ pager.onRangeOrSizeChanged(this);
+ }
+ }
+}
diff --git a/user/test/com/google/gwt/view/client/RangeTest.java b/user/test/com/google/gwt/view/client/RangeTest.java
new file mode 100644
index 0000000..e117fed
--- /dev/null
+++ b/user/test/com/google/gwt/view/client/RangeTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * 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.google.gwt.view.client;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link Range}.
+ */
+public class RangeTest extends TestCase {
+
+ public void testAccessors() {
+ Range range = new Range(10, 20);
+ assertEquals(10, range.getStart());
+ assertEquals(20, range.getLength());
+ }
+
+ public void testEquals() {
+ Range range0 = new Range(10, 20);
+ Range range1 = new Range(10, 20);
+ assertEquals(range0, range1);
+ assertTrue(range0.equals(range1));
+ assertEquals(range0.hashCode(), range1.hashCode());
+ }
+
+ public void testEqualsNull() {
+ Range range0 = new Range(10, 20);
+ assertFalse(range0.equals(null));
+ }
+
+ public void testEqualsObject() {
+ Range range0 = new Range(10, 20);
+ assertFalse(range0.equals("not a range"));
+ }
+
+ public void testNotEqualsLength() {
+ Range range0 = new Range(10, 20);
+ Range range1 = new Range(10, 19);
+ assertNotSame(range0, range1);
+ assertFalse(range0.equals(range1));
+ assertNotSame(range0.hashCode(), range1.hashCode());
+ }
+
+ public void testNotEqualsStart() {
+ Range range0 = new Range(10, 20);
+ Range range1 = new Range(9, 20);
+ assertNotSame(range0, range1);
+ assertFalse(range0.equals(range1));
+ assertNotSame(range0.hashCode(), range1.hashCode());
+ }
+}