Restore tree selection
Review at http://gwt-code-reviews.appspot.com/348801
Review by: jgw@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7920 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/client/HasCell.java b/bikeshed/src/com/google/gwt/bikeshed/list/client/HasCell.java
index 30a0ef2..c4a4228 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/list/client/HasCell.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/list/client/HasCell.java
@@ -29,6 +29,8 @@
*/
public interface HasCell<T, C, V> {
+ boolean dependsOnSelection();
+
Cell<C, V> getCell();
FieldUpdater<T, C, V> getFieldUpdater();
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/shared/ProvidesKey.java b/bikeshed/src/com/google/gwt/bikeshed/list/shared/ProvidesKey.java
index 7b31f32..b86e09c 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/list/shared/ProvidesKey.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/list/shared/ProvidesKey.java
@@ -17,13 +17,16 @@
/**
* <p>
- * Implementors of {@link ProvidesKey} provide a key for list items.
+ * Implementors of {@link ProvidesKey} provide a key for list items, such that
+ * items that are to be treated as distinct (for example, for editing) have
+ * distinct keys.
* </p>
* <p>
* The key must implement a coherent set of {@link Object#equals(Object)} and
- * {@link Object#hashCode()} methods. If the item type is a not uniquely
- * identifiable, such as a list of {@link String}, the index can be used as the
- * key.
+ * {@link Object#hashCode()} methods such that if objects A and B are to be
+ * treated as identical, then A.equals(B), B.equals(A), and A.hashCode() ==
+ * B.hashCode(). If A and B are to be treated as unequal, then it must
+ * be the case that A.equals(B) == false and B.equals(A) == false.
* </p>
*
* @param <T> the data type of records in the list
diff --git a/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeNodeView.java b/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeNodeView.java
index 6818ac8..36e2b4c 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeNodeView.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeNodeView.java
@@ -250,9 +250,4 @@
setChildContainer(null);
}
-
- private <C, X> void render(StringBuilder sb, C childValue,
- HasCell<C, X, Void> hc) {
- hc.getCell().render(hc.getValue(childValue), null, sb);
- }
}
diff --git a/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeView.java b/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeView.java
index 0e0cdfa..2f048db 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeView.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeView.java
@@ -114,6 +114,15 @@
}
if (inCell) {
nodeView.fireEventToCell(event);
+
+ // TODO(jgw): Kind of a hacky way to set selection. Need to generalize
+ // this to some sort of keyboard/mouse->selection controller.
+ if (getSelectionModel() != null) {
+ String type = event.getType();
+ if ("mouseup".equals(type)) {
+ getSelectionModel().setSelected(nodeView.getValue(), true);
+ }
+ }
} else {
nodeView.setState(!nodeView.getState());
}
diff --git a/bikeshed/src/com/google/gwt/bikeshed/tree/client/StandardTreeNodeView.java b/bikeshed/src/com/google/gwt/bikeshed/tree/client/StandardTreeNodeView.java
index 483ca34..73d662b 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/tree/client/StandardTreeNodeView.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/tree/client/StandardTreeNodeView.java
@@ -133,9 +133,4 @@
protected void postClose() {
getTree().maybeAnimateTreeNode(this);
}
-
- private <C, X> void render(StringBuilder sb, C childValue,
- HasCell<C, X, Void> hc) {
- hc.getCell().render(hc.getValue(childValue), null, sb);
- }
}
diff --git a/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeNodeView.java b/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeNodeView.java
index 90d302e..344bf9d 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeNodeView.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeNodeView.java
@@ -43,6 +43,16 @@
public abstract class TreeNodeView<T> extends UIObject implements TreeNode<T> {
/**
+ * A NodeInfo and list of data items of matching type.
+ *
+ * @param <C> the data type
+ */
+ static class SavedInfo<C> {
+ NodeInfo<C> nodeInfo;
+ List<C> values;
+ }
+
+ /**
* The element used in place of an image when a node has no children.
*/
public static final String LEAF_IMAGE = "<div style='position:absolute;display:none;'></div>";
@@ -93,6 +103,11 @@
private final NodeInfo<T> parentNodeInfo;
/**
+ * The NodeInfo for this node along with saved child data values.
+ */
+ private SavedInfo<?> savedInfo;
+
+ /**
* The info about this node.
*/
private final TreeView tree;
@@ -353,6 +368,12 @@
ensureChildContainer().setInnerHTML(tree.getLoadingHtml());
ensureAnimationFrame().getStyle().setProperty("display", "");
+ // Create a SavedInfo object to store the NodeInfo and data values
+ final SavedInfo<C> localSavedInfo = new SavedInfo<C>();
+ localSavedInfo.nodeInfo = nodeInfo;
+ localSavedInfo.values = new ArrayList<C>();
+ TreeNodeView.this.savedInfo = localSavedInfo;
+
// Get the node info.
final ProvidesKey<C> providesKey = nodeInfo.getProvidesKey();
ListView<C> view = new ListView<C>() {
@@ -363,6 +384,18 @@
public void onDataChanged(ListEvent<C> event) {
// TODO - handle event start and length
+ int start = event.getStart();
+ int end = start + event.getLength();
+ // Ensure savedInfo has a place to store the data values
+ while (localSavedInfo.values.size() < end) {
+ savedInfo.values.add(null);
+ }
+ // Save child values into savedInfo
+ int index = event.getStart();
+ for (C childValue : event.getValues()) {
+ localSavedInfo.values.set(index++, childValue);
+ }
+
// Construct a map of former child views based on their value keys.
Map<Object, TreeNodeView<?>> map = new HashMap<Object, TreeNodeView<?>>();
if (children != null) {
@@ -463,6 +496,16 @@
protected void preOpen() {
}
+ /**
+ * Refresh any cells that depend on the selection state. The default
+ * implementation works for {@link StandardTreeNodeView} and
+ * {@link SideBySideTreeNodeView}; other subclasses will need to implement
+ * their own versions of this method.
+ */
+ protected void refreshSelection() {
+ refreshSelection(savedInfo);
+ }
+
protected void setChildContainer(Element childContainer) {
this.childContainer = childContainer;
}
@@ -491,4 +534,39 @@
TreeView getTree() {
return tree;
}
+
+ <C, X> void render(StringBuilder sb, C childValue,
+ HasCell<C, X, Void> hc) {
+ hc.getCell().render(hc.getValue(childValue), null, sb);
+ }
+
+ /**
+ * Refresh any cells that depend on the selection state. Note that this
+ * implementation is dependent on the particular DOM structure used by
+ * {@link StandardTreeNodeView} and {@link SideBySideTreeNodeView}.
+ *
+ * @param <C> the child data type
+ * @param savedInfo a SavedInfo object containing a NodeInfo instance
+ * and a list of saved child data values
+ */
+ private <C> void refreshSelection(SavedInfo<C> savedInfo) {
+ List<HasCell<C, ?, Void>> hasCells = savedInfo.nodeInfo.getHasCells();
+ Element outerDiv = childContainer.getFirstChildElement();
+ int index = 0;
+ while (outerDiv != null) {
+ C childValue = savedInfo.values.get(index);
+ Element span = outerDiv.getFirstChildElement().getNextSiblingElement().getFirstChildElement();
+
+ for (HasCell<C, ?, Void> hasCell : hasCells) {
+ if (hasCell.dependsOnSelection()) {
+ StringBuilder sb = new StringBuilder();
+ render(sb, childValue, hasCell);
+ span.setInnerHTML(sb.toString());
+ }
+ span = span.getNextSiblingElement();
+ }
+ outerDiv = outerDiv.getNextSibling().cast();
+ index++;
+ }
+ }
}
diff --git a/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeView.java b/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeView.java
index 563b4e0..55d9f16 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeView.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeView.java
@@ -17,6 +17,8 @@
import com.google.gwt.animation.client.Animation;
import com.google.gwt.bikeshed.list.shared.SelectionModel;
+import com.google.gwt.bikeshed.list.shared.SelectionModel.SelectionChangeEvent;
+import com.google.gwt.bikeshed.list.shared.SelectionModel.SelectionChangeHandler;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.ImageResource;
@@ -77,6 +79,12 @@
ImageResource treeOpen();
}
+ private class TreeSelectionHandler implements SelectionChangeHandler {
+ public void onSelectionChange(SelectionChangeEvent event) {
+ refreshSelection();
+ }
+ }
+
private static final Resources DEFAULT_RESOURCES = GWT.create(Resources.class);
/**
@@ -144,6 +152,10 @@
return rootNode;
}
+ /**
+ * Returns the {@link SelectionModel} containing the selection state for
+ * this tree, or null if none is present.
+ */
public SelectionModel<Object> getSelectionModel() {
return selectionModel;
}
@@ -157,6 +169,13 @@
}
/**
+ * Refresh any visible cells of this tree that depend on the selection state.
+ */
+ public void refreshSelection() {
+ refreshSelection(rootNode);
+ }
+
+ /**
* Set the animation used to open and close nodes in this tree. You must call
* {@link #setAnimationEnabled(boolean)} to enable or disable animation.
*
@@ -177,6 +196,10 @@
public void setSelectionModel(SelectionModel<Object> selectionModel) {
this.selectionModel = selectionModel;
+ // Attach a selection handler.
+ if (selectionModel != null) {
+ selectionModel.addSelectionChangeHandler(new TreeSelectionHandler());
+ }
}
/**
@@ -257,4 +280,15 @@
protected void setRootNode(TreeNodeView<?> rootNode) {
this.rootNode = rootNode;
}
+
+ private void refreshSelection(TreeNodeView<?> node) {
+ node.refreshSelection();
+ int count = node.getChildCount();
+ for (int i = 0; i < count; i++) {
+ TreeNodeView<?> child = node.getChildTreeNodeView(i);
+ if (child.isOpen()) {
+ refreshSelection(child);
+ }
+ }
+ }
}
diff --git a/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeViewModel.java b/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeViewModel.java
index b619971..332b6dc 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeViewModel.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeViewModel.java
@@ -47,10 +47,12 @@
* @param adapter the {@link AbstractListViewAdapter} that provides the
* child values
* @param cell the {@link Cell} used to render the child values
+ * @param dependsOnSelection true if the contents of the cell may require
+ * an update when the selection changes
*/
public DefaultNodeInfo(AbstractListViewAdapter<T> adapter,
- Cell<T, Void> cell) {
- this(adapter, cell, null);
+ Cell<T, Void> cell, boolean dependsOnSelection) {
+ this(adapter, cell, dependsOnSelection, null);
}
/**
@@ -60,11 +62,18 @@
* @param adapter the {@link AbstractListViewAdapter} that provides the
* child values
* @param cell the {@link Cell} used to render the child values
+ * @param dependsOnSelection true if the contents of the cell may require
+ * an update when the selection changes
* @param valueUpdater the {@link ValueUpdater}
*/
public DefaultNodeInfo(AbstractListViewAdapter<T> adapter,
- final Cell<T, Void> cell, final ValueUpdater<T, Void> valueUpdater) {
+ final Cell<T, Void> cell, final boolean dependsOnSelection,
+ final ValueUpdater<T, Void> valueUpdater) {
hasCells.add(new HasCell<T, T, Void>() {
+ public boolean dependsOnSelection() {
+ return dependsOnSelection;
+ }
+
public Cell<T, Void> getCell() {
return cell;
}
@@ -98,7 +107,6 @@
return listViewAdapter;
}
- // TODO - dispatch into cells
public void onBrowserEvent(Element elem, final T object, NativeEvent event) {
Element target = event.getEventTarget().cast();
String idxString = "";
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/Cookbook.java b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/Cookbook.java
index 6ae4be6..61fc940 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/Cookbook.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/Cookbook.java
@@ -61,12 +61,12 @@
public <T> NodeInfo<?> getNodeInfo(T value, TreeNode<T> treeNode) {
if (value == null) {
// Categories at the root.
- return new DefaultNodeInfo<Category>(adapter, new CategoryCell());
+ return new DefaultNodeInfo<Category>(adapter, new CategoryCell(), false);
} else if (value instanceof Category) {
// Demos for each category.
Category category = (Category) value;
return new DefaultNodeInfo<Recipe>(new ListViewAdapter<Recipe>(
- category.getRecipes()), new RecipeCell());
+ category.getRecipes()), new RecipeCell(), false);
}
return null;
}
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MultiSelectionModel.java b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MultiSelectionModel.java
index c5c8be2..6ebe91f 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MultiSelectionModel.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MultiSelectionModel.java
@@ -21,7 +21,7 @@
import java.util.TreeSet;
/**
- * A simple selection model that allows only multiple objects to be selected.
+ * A simple selection model that allows multiple objects to be selected.
*
* @param <T> the record data type
*/
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MyTreeViewModel.java b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MyTreeViewModel.java
index bdc6b7b..6783775 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MyTreeViewModel.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MyTreeViewModel.java
@@ -108,6 +108,10 @@
public MyTreeViewModel(final SelectionModel<Object> selectionModel) {
hasCells.add(new HasCell<String, Boolean, Void>() {
+ public boolean dependsOnSelection() {
+ return true;
+ }
+
public Cell<Boolean, Void> getCell() {
return new CheckboxCell();
}
@@ -126,6 +130,10 @@
}
});
hasCells.add(new HasCell<String, String, Void>() {
+ public boolean dependsOnSelection() {
+ return false;
+ }
+
public Cell<String, Void> getCell() {
return ButtonCell.getInstance();
}
@@ -165,7 +173,7 @@
return new DefaultNodeInfo<String>(adapter, hasCells);
} else {
AbstractListViewAdapter<Integer> adapter = new IntegerListViewAdapter(value.length());
- return new DefaultNodeInfo<Integer>(adapter, INTEGER_CELL,
+ return new DefaultNodeInfo<Integer>(adapter, INTEGER_CELL, false,
new ValueUpdater<Integer, Void>() {
public void update(Integer value, Void viewData) {
Window.alert("Integer = " + value);
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/TransactionTreeViewModel.java b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/TransactionTreeViewModel.java
index 790800d..c213e10 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/TransactionTreeViewModel.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/TransactionTreeViewModel.java
@@ -96,10 +96,10 @@
public <T> NodeInfo<?> getNodeInfo(T value, final TreeNode<T> treeNode) {
if (value == null) {
return new TreeViewModel.DefaultNodeInfo<String>(topLevelListViewAdapter,
- TextCell.getInstance());
+ TextCell.getInstance(), false);
} else if ("Favorites".equals(value)) {
return new TreeViewModel.DefaultNodeInfo<StockQuote>(stockQuoteListViewAdapter,
- STOCK_QUOTE_CELL);
+ STOCK_QUOTE_CELL, false);
} else if ("History".equals(value)) {
String ticker = ((StockQuote) treeNode.getParentNode().getValue()).getTicker();
ListViewAdapter<Transaction> adapter = transactionListViewAdaptersByTicker.get(ticker);
@@ -108,14 +108,14 @@
transactionListViewAdaptersByTicker.put(ticker, adapter);
}
return new TreeViewModel.DefaultNodeInfo<Transaction>(adapter,
- TRANSACTION_CELL);
+ TRANSACTION_CELL, false);
} else if ("Actions".equals(value)) {
ListViewAdapter<String> adapter = new ListViewAdapter<String>();
List<String> list = adapter.getList();
list.add("Buy");
list.add("Sell");
return new TreeViewModel.DefaultNodeInfo<String>(adapter,
- ButtonCell.getInstance(), new ValueUpdater<String, Void>() {
+ ButtonCell.getInstance(), false, new ValueUpdater<String, Void>() {
public void update(String value, Void viewData) {
StockQuote stockQuote = (StockQuote) treeNode.getParentNode().getValue();
if ("Buy".equals(value)) {
@@ -129,14 +129,14 @@
SectorListViewAdapter adapter = new SectorListViewAdapter((String) value);
sectorListViewAdapters.put((String) value, adapter);
return new TreeViewModel.DefaultNodeInfo<StockQuote>(adapter,
- STOCK_QUOTE_CELL);
+ STOCK_QUOTE_CELL, false);
} else if (value instanceof StockQuote) {
ListViewAdapter<String> adapter = new ListViewAdapter<String>();
List<String> list = adapter.getList();
list.add("Actions");
list.add("History");
return new TreeViewModel.DefaultNodeInfo<String>(adapter,
- TextCell.getInstance());
+ TextCell.getInstance(), false);
}
throw new IllegalArgumentException(value.toString());
diff --git a/bikeshed/src/com/google/gwt/valuestore/client/ValuesListViewTable.java b/bikeshed/src/com/google/gwt/valuestore/client/ValuesListViewTable.java
index 8107aab..19057bd 100644
--- a/bikeshed/src/com/google/gwt/valuestore/client/ValuesListViewTable.java
+++ b/bikeshed/src/com/google/gwt/valuestore/client/ValuesListViewTable.java
@@ -106,9 +106,9 @@
@Override
protected void onRangeChanged(ListView<Values<K>> view) {
Range range = view.getRange();
- Delegate delegate = getDelegate();
- if (delegate != null) {
- delegate.onRangeChanged(range.getStart(), range.getLength());
+ Delegate myDelegate = getDelegate();
+ if (myDelegate != null) {
+ myDelegate.onRangeChanged(range.getStart(), range.getLength());
}
}
};
diff --git a/bikeshed/test/com/google/gwt/collections/ObjectArrayTest.java b/bikeshed/test/com/google/gwt/collections/ObjectArrayTest.java
index 988ebc5..3b745e0 100644
--- a/bikeshed/test/com/google/gwt/collections/ObjectArrayTest.java
+++ b/bikeshed/test/com/google/gwt/collections/ObjectArrayTest.java
@@ -1,12 +1,12 @@
/*
* Copyright 2009 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
@@ -23,9 +23,9 @@
* Tests mutable arrays.
*/
public class ObjectArrayTest extends GWTTestCase {
-
+
boolean assertionsEnabled;
-
+
@Override
public String getModuleName() {
return null;
@@ -54,6 +54,14 @@
}
}
+ public void testCreateNonEmptyArray() {
+ MutableArray<String> b = createMutableArray(2, "apples");
+
+ assertEquals(2, b.size());
+ assertEquals("apples", b.get(0));
+ assertEquals("apples", b.get(1));
+ }
+
public void testInsertAtBeginning() {
final int n = 10;
MutableArray<Integer> b = createMutableArray();
@@ -99,7 +107,7 @@
assertEquals(j, b.get(i + 1).intValue());
}
}
-
+
public void testMultiElementArrayManipulations() {
MutableArray<String> b = createMutableArray();
b.add("apple");
@@ -155,6 +163,27 @@
assertEquals(4, b.get(1).intValue());
}
+ public void testSetSize() {
+ MutableArray<String> b = createMutableArray();
+
+ b.setSize(1, "fillValue");
+ assertEquals(1, b.size());
+ assertEquals("fillValue", b.get(0));
+
+ b.setSize(2, "anotherValue");
+ assertEquals(2, b.size());
+ assertEquals("fillValue", b.get(0));
+ assertEquals("anotherValue", b.get(1));
+
+ b.setSize(1, null);
+ assertEquals(1, b.size());
+ assertEquals("fillValue", b.get(0));
+
+ b.setSize(0, null);
+ assertEquals(0, b.size());
+ assertEquals(null, b.elems);
+ }
+
public void testSingleElementAddAndRemove() {
MutableArray<String> a = createMutableArray();
@@ -176,7 +205,7 @@
public void testSingleElementNull() {
MutableArray<String> b = createMutableArray();
b.add(null);
-
+
assertEquals(null, b.get(0));
}
@@ -206,11 +235,11 @@
try {
a.get(1);
- fail("That should have failed");
+ fail("That should have failed");
} catch (AssertionError e) {
- assertEquals(("Index " + 1 + " was not in the acceptable range [" + 0 + ", " + 1 + ")"),
+ assertEquals(("Index " + 1 + " was not in the acceptable range [" + 0 + ", " + 1 + ")"),
e.getMessage());
- }
+ }
}
public void testSingletonArrayManipulations() {
@@ -265,34 +294,5 @@
Array<String> a = b;
assertEquals(0, a.size());
}
-
- public void testSetSize() {
- MutableArray<String> b = createMutableArray();
-
- b.setSize(1, "fillValue");
- assertEquals(1, b.size());
- assertEquals("fillValue", b.get(0));
-
- b.setSize(2, "anotherValue");
- assertEquals(2, b.size());
- assertEquals("fillValue", b.get(0));
- assertEquals("anotherValue", b.get(1));
-
- b.setSize(1, null);
- assertEquals(1, b.size());
- assertEquals("fillValue", b.get(0));
-
- b.setSize(0, null);
- assertEquals(0, b.size());
- assertEquals(null, b.elems);
- }
-
- public void testCreateNonEmptyArray() {
- MutableArray<String> b = createMutableArray(2, "apples");
-
- assertEquals(2, b.size());
- assertEquals("apples", b.get(0));
- assertEquals("apples", b.get(1));
- }
}