You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2012/11/14 03:36:19 UTC
svn commit: r1409062 - in /sis/branches/JDK7/sis-utility/src:
main/java/org/apache/sis/internal/util/
main/java/org/apache/sis/util/collection/ test/java/org/apache/sis/test/
test/java/org/apache/sis/test/suite/
test/java/org/apache/sis/util/collection/
Author: desruisseaux
Date: Wed Nov 14 02:36:18 2012
New Revision: 1409062
URL: http://svn.apache.org/viewvc?rev=1409062&view=rev
Log:
Added a test case for DefaultTreeTable.
Added:
sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/TestStep.java (with props)
sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/DefaultTreeTableTest.java (with props)
Modified:
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/ColumnConstant.java
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeNodeList.java
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTable.java
sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/ColumnConstant.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/ColumnConstant.java?rev=1409062&r1=1409061&r2=1409062&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/ColumnConstant.java (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/ColumnConstant.java Wed Nov 14 02:36:18 2012
@@ -101,6 +101,14 @@ public final class ColumnConstant<T> imp
}
/**
+ * Returns the name of the field declaring this constant.
+ */
+ @Override
+ public String toString() {
+ return name;
+ }
+
+ /**
* Invoked on deserialization for resolving this instance to one of the predefined constants.
*
* @return One of the predefined constants.
Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java?rev=1409062&r1=1409061&r2=1409062&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java Wed Nov 14 02:36:18 2012
@@ -179,7 +179,8 @@ public class DefaultTreeTable implements
public void setRoot(final TreeTable.Node root) {
ArgumentChecks.ensureNonNull("root", root);
if (root instanceof Node) {
- if (columnIndex.keySet().containsAll(((Node) root).columnIndex.keySet())) {
+ final Map<TableColumn<?>,Integer> other = ((Node) root).columnIndex;
+ if (other != columnIndex && !columnIndex.keySet().containsAll(other.keySet())) {
throw new IllegalArgumentException(Errors.format(Errors.Keys.InconsistentTableColumns));
}
}
@@ -286,6 +287,10 @@ public class DefaultTreeTable implements
* Creates a new node for the given table. The new node will be able to store a value
* for each {@linkplain TreeTable#getColumns() columns} defined in the given table.
*
+ * <p>This method does not set the new node as the root of the given table. If desired, it
+ * is the caller responsibility to {@linkplain DefaultTreeTable#setRoot set the table root
+ * node}.</p>
+ *
* @param table The table for which this node is created.
*/
public Node(final TreeTable table) {
@@ -300,15 +305,23 @@ public class DefaultTreeTable implements
}
/**
- * Creates a new node with the given parent. The new node will be able to store
- * values for the same columns than the parent node.
+ * Creates a new node with the given parent. The new node is added to the parent
+ * {@linkplain #getChildren() list of children} at the given index. The new node
+ * will be able to store values for the same columns than the parent node.
*
* @param parent The parent of the new node.
+ * @param index The index where to add the new node in the parent list of children,
+ * or -1 for adding the new node at the end of the list.
*/
- public Node(final Node parent) {
+ public Node(final Node parent, int index) {
ArgumentChecks.ensureNonNull("parent", parent);
this.parent = parent;
columnIndex = parent.columnIndex;
+ final TreeNodeList addTo = (TreeNodeList) parent.getChildren();
+ if (index < 0) {
+ index = addTo.size();
+ }
+ addTo.addChild(index, this);
}
/**
@@ -317,7 +330,7 @@ public class DefaultTreeTable implements
* added as a child of another {@code Node} instance.
*/
@Override
- public TreeTable.Node getParent() {
+ public final TreeTable.Node getParent() {
return parent;
}
@@ -327,7 +340,8 @@ public class DefaultTreeTable implements
*/
final void setParent(final TreeTable.Node node) {
if (node instanceof Node) {
- if (((Node) node).columnIndex.keySet().containsAll(columnIndex.keySet())) {
+ final Map<TableColumn<?>,Integer> other = ((Node) node).columnIndex;
+ if (other != columnIndex && !other.keySet().containsAll(columnIndex.keySet())) {
throw new IllegalArgumentException(Errors.format(Errors.Keys.InconsistentTableColumns));
}
}
@@ -339,8 +353,12 @@ public class DefaultTreeTable implements
* {@linkplain #getParent() parent} reference of any {@code Node} instance added to
* ore removed from this list.
*/
+ /* NOTE: If a future version removes the "final" keyword, then search for calls to
+ * this method where the return value is casted to TreeNodeList. Any unconditional
+ * cast will need to be replaced by an "instanceof" check.
+ */
@Override
- public List<TreeTable.Node> getChildren() {
+ public final List<TreeTable.Node> getChildren() {
if (children == null) {
children = new Children(this);
}
@@ -410,5 +428,33 @@ public class DefaultTreeTable implements
public Object getUserObject() {
return null;
}
+
+ /**
+ * Returns a string representation of this node, for identification in error message
+ * or in debugger.
+ *
+ * @return A string representation of this node.
+ */
+ @Override
+ public String toString() {
+ Object value = getUserObject();
+ if (value instanceof CharSequence) {
+ return value.toString();
+ }
+ final Object[] values = this.values;
+ if (values != null) {
+ for (int i=0; i<values.length; i++) {
+ value = values[i];
+ if (value instanceof CharSequence) {
+ return value.toString();
+ }
+ }
+ }
+ String name = getClass().getSimpleName();
+ if (parent != null) {
+ name = name + '-' + parent.getChildren().indexOf(this);
+ }
+ return name;
+ }
}
}
Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeNodeList.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeNodeList.java?rev=1409062&r1=1409061&r2=1409062&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeNodeList.java (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeNodeList.java Wed Nov 14 02:36:18 2012
@@ -216,6 +216,15 @@ abstract class TreeNodeList extends Abst
} else {
setParentOf(node, THIS);
}
+ addChild(index, node);
+ }
+
+ /**
+ * Adds the given node at the given index in this list, without any check for the parent.
+ * The {@linkplain TreeTable.Node#getParent() parent} of the given node shall already be
+ * set to {@code this} before this method is invoked.
+ */
+ final void addChild(final int index, final TreeTable.Node node) {
if (children == null) {
children = new TreeTable.Node[4];
} else if (size == children.length) {
Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTable.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTable.java?rev=1409062&r1=1409061&r2=1409062&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTable.java (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTable.java Wed Nov 14 02:36:18 2012
@@ -97,7 +97,7 @@ public interface TreeTable {
* @return The children, or an empty list if none.
* @category tree
*/
- List<? extends Node> getChildren();
+ List<Node> getChildren();
/**
* Returns the value in the given column, or {@code null}Â if none.
Added: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/TestStep.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/TestStep.java?rev=1409062&view=auto
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/TestStep.java (added)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/TestStep.java Wed Nov 14 02:36:18 2012
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.sis.test;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+
+/**
+ * A test method producing an object to be used by another test method.
+ * Such methods are annotated with this {@code TestStep} annotation instead than the
+ * JUnit {@link org.junit.Test} one. However in current implementation, those methods
+ * must be explicitely invoked from another method. This is because JUnit 4 does not
+ * support tests chaining, so this annotation is currently used only for documentation
+ * purpose.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @since 0.3
+ * @version 0.3
+ * @module
+ */
+@Documented
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.SOURCE)
+public @interface TestStep {
+}
Propchange: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/TestStep.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/TestStep.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java?rev=1409062&r1=1409061&r2=1409062&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java (original)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java Wed Nov 14 02:36:18 2012
@@ -51,6 +51,7 @@ import org.junit.runners.Suite;
org.apache.sis.util.collection.CacheTest.class,
org.apache.sis.util.collection.DerivedSetTest.class,
org.apache.sis.util.collection.DerivedMapTest.class,
+ org.apache.sis.util.collection.DefaultTreeTableTest.class,
// GeoAPI most basic types.
org.apache.sis.util.type.TypesTest.class,
Added: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/DefaultTreeTableTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/DefaultTreeTableTest.java?rev=1409062&view=auto
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/DefaultTreeTableTest.java (added)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/DefaultTreeTableTest.java Wed Nov 14 02:36:18 2012
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.sis.util.collection;
+
+import java.util.List;
+import org.junit.Test;
+import org.apache.sis.test.TestCase;
+import org.apache.sis.test.TestStep;
+
+import static org.junit.Assert.*;
+import static org.apache.sis.test.TestUtilities.getSingleton;
+import static org.apache.sis.internal.util.ColumnConstant.*;
+
+
+/**
+ * Tests the {@link DefaultTreeTable} class.
+ * This will also test indirectly the {@link TreeNodeList} class.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @since 0.3
+ * @version 0.3
+ * @module
+ */
+public final strictfp class DefaultTreeTableTest extends TestCase {
+ /**
+ * Tests the creation of an {@link DefaultTreeTable} with initially no root node.
+ * The columns are {@code NAME} and {@code TYPE}.
+ *
+ * <p>This method is part of a chain.
+ * The next method is {@link #testNodeCreation(DefaultTreeTable)}.</p>
+ *
+ * @return The created table, for chaining with methods testing the next step
+ * after this one.
+ */
+ @TestStep
+ private static DefaultTreeTable testTableCreation() {
+ final DefaultTreeTable table = new DefaultTreeTable(NAME, TYPE);
+ assertEquals("Number of columns:", 2, table.columnIndex.size());
+ assertEquals("Index of first column:", Integer.valueOf(0), table.columnIndex.get(NAME));
+ assertEquals("Index of second column:", Integer.valueOf(1), table.columnIndex.get(TYPE));
+ assertArrayEquals(new TableColumn<?>[] {NAME, TYPE}, table.getColumns().toArray());
+ try {
+ assertNull(table.getRoot());
+ fail("Expected an IllegalStateException.");
+ } catch (IllegalStateException e) {
+ // This is the expected exception.
+ assertTrue(e.getMessage().contains("root"));
+ }
+ return table;
+ }
+
+ /**
+ * Tests the creation of children nodes.
+ * The root node has only one child, which itself has only one child.
+ *
+ * <p>This method is part of a chain.
+ * The previous method is {@link #testTableCreation()} and
+ * the next method is {@link #testNodeDisplacement(TreeTable.Node)}.</p>
+ *
+ * @param table An initially empty table where to set the root.
+ * @return The root node produced by this method.
+ */
+ @TestStep
+ private static DefaultTreeTable.Node testNodeCreation(final DefaultTreeTable table) {
+ /*
+ * Create a root node with an initially empty list of children.
+ */
+ final DefaultTreeTable.Node root = new DefaultTreeTable.Node(table);
+ assertSame("Internal table sharing:", table.columnIndex, root.columnIndex);
+ assertTrue("Initial children list:", root.getChildren().isEmpty());
+ table.setRoot(root);
+ /*
+ * Create a first child node, which should be added automatically
+ * to the root list of children.
+ */
+ final DefaultTreeTable.Node node1 = new DefaultTreeTable.Node(root, -1);
+ assertSame("Internal table sharing:", table.columnIndex, node1.columnIndex);
+ assertTrue("Initial children list:", node1.getChildren().isEmpty());
+ assertSame("Specified parent:", root, node1.getParent());
+ assertSame("Children list after add:", node1, getSingleton(root.getChildren()));
+ /*
+ * Create a child of the previous child.
+ */
+ final DefaultTreeTable.Node node2 = new DefaultTreeTable.Node(node1, 0);
+ assertSame("Internal table sharing:", table.columnIndex, node2.columnIndex);
+ assertTrue("Initial children list:", node2.getChildren().isEmpty());
+ assertSame("Specified parent:", node1, node2.getParent());
+ assertSame("Children list after add:", node2, getSingleton(node1.getChildren()));
+ assertSame("Independent children list:", node1, getSingleton(root.getChildren()));
+ /*
+ * For chaining with next tests.
+ */
+ assertSame(root, table.getRoot());
+ return root;
+ }
+
+ /**
+ * Tests the displacement of nodes, in particular ensures that the parent is updated.
+ *
+ * <p>This method is part of a chain.
+ * The previous method is {@link #testNodeCreation(DefaultTreeTable)}.</p>
+ *
+ * @param root The root node where to move children.
+ */
+ @TestStep
+ private static void testNodeDisplacement(final TreeTable.Node root) {
+ final List<TreeTable.Node> rootChildren, nodeChildren;
+ final TreeTable.Node node1 = getSingleton(rootChildren = root .getChildren());
+ final TreeTable.Node node2 = getSingleton(nodeChildren = node1.getChildren());
+ try {
+ assertTrue(rootChildren.add(node2));
+ fail("Should not be allowed to add a child before we removed it from its previous parent.");
+ } catch (IllegalArgumentException e) {
+ // This is the expected exception.
+ assertTrue(e.getMessage().contains("Node-0"));
+ }
+ assertSame("Initial parent:", node1, node2.getParent());
+ assertTrue( nodeChildren.remove(node2));
+ assertTrue("Children list after removal:", nodeChildren.isEmpty());
+ assertNull("Parent after removal:", node2.getParent());
+ assertTrue( rootChildren.add(node2));
+ assertSame("Parent after add:", root, node2.getParent());
+ assertArrayEquals("Children list after add:",
+ new TreeTable.Node[] {node1, node2}, rootChildren.toArray());
+ }
+
+ /**
+ * Tests the creation of a tree table with a few nodes, and tests the displacement of a node
+ * from one branch to another. This test is actually a chain of {@link TestStep} methods.
+ */
+ @Test
+ public void testTreeTableCreation() {
+ testNodeDisplacement(testNodeCreation(testTableCreation()));
+ }
+}
Propchange: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/DefaultTreeTableTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/DefaultTreeTableTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain