blob: fd2b4799c13c1ead388d340459377cd6c47c1259 [file] [log] [blame]
/*
* 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.commons.configuration2.tree;
import static org.apache.commons.configuration2.tree.NodeStructureHelper.ROOT_AUTHORS_TREE;
import static org.apache.commons.configuration2.tree.NodeStructureHelper.ROOT_PERSONAE_TREE;
import static org.apache.commons.configuration2.tree.NodeStructureHelper.nodeForKey;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.junit.Test;
/**
* A base test class for {@code NodeHandler} implementations for immutable nodes. Concrete sub classes have to implement
* a method which creates a new handler object for a given nodes structure.
*
*/
public abstract class AbstractImmutableNodeHandlerTest {
/**
* A dummy NodeMatcher implementation that will simply accept all passed in nodes.
*/
private static class DummyNodeMatcher implements NodeMatcher<Object> {
@Override
public <T> boolean matches(final T node, final NodeHandler<T> handler, final Object criterion) {
return true;
}
}
/**
* Creates a new {@code NodeHandler} object for the specified nodes structure.
*
* @param root the root of the nodes structure
* @return the handler object
*/
protected abstract NodeHandler<ImmutableNode> createHandler(ImmutableNode root);
/**
* Tests whether the correct parent for the root node is returned.
*/
@Test
public void testGetParentForRoot() {
final NodeHandler<ImmutableNode> handler = createHandler(ROOT_AUTHORS_TREE);
assertNull("Got a parent", handler.getParent(ROOT_AUTHORS_TREE));
}
/**
* Tries to query the parent node for a node which does not belong to the managed tree.
*/
@Test(expected = IllegalArgumentException.class)
public void testGetParentInvalidNode() {
final NodeHandler<ImmutableNode> handler = createHandler(ROOT_AUTHORS_TREE);
handler.getParent(new ImmutableNode.Builder().name("unknown").create());
}
/**
* Tests whether the correct parent nodes are returned. All nodes in the tree are checked.
*/
@Test
public void testGetParentNode() {
final NodeHandler<ImmutableNode> handler = createHandler(ROOT_AUTHORS_TREE);
for (int authorIdx = 0; authorIdx < NodeStructureHelper.authorsLength(); authorIdx++) {
final ImmutableNode authorNode = nodeForKey(handler.getRootNode(), NodeStructureHelper.author(authorIdx));
assertSame("Wrong parent for " + NodeStructureHelper.author(authorIdx), handler.getRootNode(), handler.getParent(authorNode));
for (int workIdx = 0; workIdx < NodeStructureHelper.worksLength(authorIdx); workIdx++) {
final String workKey = NodeStructureHelper.appendPath(NodeStructureHelper.author(authorIdx), NodeStructureHelper.work(authorIdx, workIdx));
final ImmutableNode workNode = nodeForKey(handler.getRootNode(), workKey);
assertSame("Wrong parent for " + workKey, authorNode, handler.getParent(workNode));
for (int personaIdx = 0; personaIdx < NodeStructureHelper.personaeLength(authorIdx, workIdx); personaIdx++) {
final String personKey = NodeStructureHelper.appendPath(workKey, NodeStructureHelper.persona(authorIdx, workIdx, personaIdx));
final ImmutableNode personNode = nodeForKey(handler.getRootNode(), personKey);
assertSame("Wrong parent for " + personKey, workNode, handler.getParent(personNode));
}
}
}
}
/**
* Tests whether a node's attributes can be queried.
*/
@Test
public void testNodeHandlerGetAttributes() {
final NodeHandler<ImmutableNode> handler = createHandler(ROOT_PERSONAE_TREE);
final ImmutableNode node = nodeForKey(handler, "Puck");
assertEquals("Wrong attributes", node.getAttributes().keySet(), handler.getAttributes(node));
}
/**
* Tests that the keys of attributes cannot be modified.
*/
@Test(expected = UnsupportedOperationException.class)
public void testNodeHandlerGetAttributesImmutable() {
final NodeHandler<ImmutableNode> handler = createHandler(ROOT_PERSONAE_TREE);
final ImmutableNode node = nodeForKey(handler, "Puck");
handler.getAttributes(node).add("test");
}
/**
* Tests whether the value of an attribute can be queried.
*/
@Test
public void testNodeHandlerGetAttributeValue() {
final NodeHandler<ImmutableNode> handler = createHandler(ROOT_PERSONAE_TREE);
final ImmutableNode node = nodeForKey(handler, "Prospero");
assertEquals("Wrong value", "Shakespeare", handler.getAttributeValue(node, NodeStructureHelper.ATTR_AUTHOR));
}
/**
* Tests whether a child at a given index can be accessed.
*/
@Test
public void testNodeHandlerGetChildAtIndex() {
final NodeHandler<ImmutableNode> handler = createHandler(ROOT_AUTHORS_TREE);
final ImmutableNode node = nodeForKey(handler, NodeStructureHelper.author(0));
assertSame("Wrong child", node.getChildren().get(1), handler.getChild(node, 1));
}
/**
* Tests whether the children of a node can be queried.
*/
@Test
public void testNodeHandlerGetChildren() {
final NodeHandler<ImmutableNode> handler = createHandler(ROOT_AUTHORS_TREE);
final ImmutableNode node = nodeForKey(handler, NodeStructureHelper.author(0));
assertSame("Wrong children", node.getChildren(), handler.getChildren(node));
}
/**
* Tests whether all children of a specific name can be queried.
*/
@Test
public void testNodeHandlerGetChildrenByName() {
final NodeHandler<ImmutableNode> handler = createHandler(ROOT_PERSONAE_TREE);
final String name = "Achilles";
final Set<ImmutableNode> children = new HashSet<>(handler.getChildren(ROOT_PERSONAE_TREE, name));
assertEquals("Wrong number of children", 3, children.size());
for (final ImmutableNode c : children) {
assertEquals("Wrong node name", name, c.getNodeName());
}
}
/**
* Tests whether the collection of children cannot be modified.
*/
@Test(expected = UnsupportedOperationException.class)
public void testNodeHandlerGetChildrenByNameImmutable() {
final NodeHandler<ImmutableNode> handler = createHandler(ROOT_PERSONAE_TREE);
final List<ImmutableNode> children = handler.getChildren(ROOT_PERSONAE_TREE, "Ajax");
children.add(null);
}
/**
* Tests whether the number of all children can be queried.
*/
@Test
public void testNodeHandlerGetChildrenCountAll() {
final NodeHandler<ImmutableNode> handler = createHandler(ROOT_AUTHORS_TREE);
final ImmutableNode node = nodeForKey(handler, NodeStructureHelper.author(0));
assertEquals("Wrong number of children", NodeStructureHelper.worksLength(0), handler.getChildrenCount(node, null));
}
/**
* Tests whether the number of all children with a given name can be queried.
*/
@Test
public void testNodeHandlerGetChildrenCountSpecific() {
final NodeHandler<ImmutableNode> handler = createHandler(ROOT_PERSONAE_TREE);
assertEquals("Wrong number of children", 3, handler.getChildrenCount(ROOT_PERSONAE_TREE, "Achilles"));
}
/**
* Tests a filter operation on child nodes.
*/
@Test
public void testNodeHandlerGetMatchingChildren() {
final NodeHandler<ImmutableNode> handler = createHandler(ROOT_AUTHORS_TREE);
final ImmutableNode target = NodeStructureHelper.nodeForKey(ROOT_AUTHORS_TREE, NodeStructureHelper.author(1));
final Set<String> encounteredAuthors = new HashSet<>();
final NodeMatcher<ImmutableNode> matcher = new NodeMatcher<ImmutableNode>() {
@Override
public <T> boolean matches(final T node, final NodeHandler<T> paramHandler, final ImmutableNode criterion) {
encounteredAuthors.add(paramHandler.nodeName(node));
return node == target;
}
};
final List<ImmutableNode> result = handler.getMatchingChildren(handler.getRootNode(), matcher, target);
assertEquals("Wrong number of matched nodes", 1, result.size());
assertSame("Wrong result", target, result.get(0));
assertEquals("Wrong number of encountered nodes", NodeStructureHelper.authorsLength(), encounteredAuthors.size());
for (int i = 0; i < NodeStructureHelper.authorsLength(); i++) {
assertTrue("Author not found: " + NodeStructureHelper.author(i), encounteredAuthors.contains(NodeStructureHelper.author(i)));
}
}
/**
* Tests whether filtered nodes can be counted.
*/
@Test
public void testNodeHandlerGetMatchingChildrenCount() {
final NodeHandler<ImmutableNode> handler = createHandler(ROOT_AUTHORS_TREE);
assertEquals("Wrong result", NodeStructureHelper.authorsLength(),
handler.getMatchingChildrenCount(handler.getRootNode(), new DummyNodeMatcher(), this));
}
/**
* Tests that the list returned by getMatchingChildren() cannot be modified.
*/
@Test(expected = UnsupportedOperationException.class)
public void testNodeHandlerGetMatchingChildrenImmutable() {
final NodeHandler<ImmutableNode> handler = createHandler(ROOT_AUTHORS_TREE);
final List<ImmutableNode> result = handler.getMatchingChildren(handler.getRootNode(), new DummyNodeMatcher(), this);
result.clear();
}
/**
* Tests a negative check whether a node has attributes.
*/
@Test
public void testNodeHandlerHasAttributesFalse() {
final NodeHandler<ImmutableNode> handler = createHandler(ROOT_PERSONAE_TREE);
assertFalse("Got attributes", handler.hasAttributes(ROOT_PERSONAE_TREE));
}
/**
* Tests a positive check whether a node has attributes.
*/
@Test
public void testNodeHandlerHasAttributesTrue() {
final NodeHandler<ImmutableNode> handler = createHandler(ROOT_PERSONAE_TREE);
final ImmutableNode node = nodeForKey(handler, "Puck");
assertTrue("No attributes", handler.hasAttributes(node));
}
/**
* Tests whether the index of a given child can be queried.
*/
@Test
public void testNodeHandlerIndexOfChild() {
final NodeHandler<ImmutableNode> handler = createHandler(ROOT_AUTHORS_TREE);
final String key = "Simmons/Hyperion";
final ImmutableNode parent = nodeForKey(handler, key);
final ImmutableNode child = nodeForKey(handler, key + "/Weintraub");
assertEquals("Wrong child index", 3, handler.indexOfChild(parent, child));
}
/**
* Tests the indexOfChild() method for an unknown child node.
*/
@Test
public void testNodeHandlerIndexOfUnknownChild() {
final NodeHandler<ImmutableNode> handler = createHandler(ROOT_AUTHORS_TREE);
final ImmutableNode parent = nodeForKey(handler, "Homer/Ilias");
final ImmutableNode child = nodeForKey(handler, "Shakespeare/Troilus and Cressida/Achilles");
assertEquals("Wrong child index", -1, handler.indexOfChild(parent, child));
}
/**
* Tests whether a node with attributes is defined.
*/
@Test
public void testNodeHandlerIsDefinedAttributes() {
final NodeHandler<ImmutableNode> handler = createHandler(ROOT_PERSONAE_TREE);
final ImmutableNode node = new ImmutableNode.Builder().addAttribute(NodeStructureHelper.ATTR_AUTHOR, NodeStructureHelper.author(0)).create();
assertTrue("Not defined", handler.isDefined(node));
}
/**
* Tests whether a node with children is defined.
*/
@Test
public void testNodeHandlerIsDefinedChildren() {
final NodeHandler<ImmutableNode> handler = createHandler(ROOT_AUTHORS_TREE);
final ImmutableNode node = nodeForKey(handler, NodeStructureHelper.author(2));
assertTrue("Not defined", handler.isDefined(node));
}
/**
* Tests whether an undefined node is correctly detected.
*/
@Test
public void testNodeHandlerIsDefinedFalse() {
final NodeHandler<ImmutableNode> handler = createHandler(ROOT_PERSONAE_TREE);
final ImmutableNode node = new ImmutableNode.Builder().name(NodeStructureHelper.author(1)).create();
assertFalse("Defined", handler.isDefined(node));
}
/**
* Tests whether a node with a value is defined.
*/
@Test
public void testNodeHandlerIsDefinedValue() {
final NodeHandler<ImmutableNode> handler = createHandler(ROOT_PERSONAE_TREE);
final ImmutableNode node = new ImmutableNode.Builder().value(42).create();
assertTrue("Not defined", handler.isDefined(node));
}
/**
* Tests whether the name of a node can be queried.
*/
@Test
public void testNodeHandlerName() {
final NodeHandler<ImmutableNode> handler = createHandler(ROOT_AUTHORS_TREE);
final ImmutableNode author = nodeForKey(handler, NodeStructureHelper.author(0));
assertEquals("Wrong node name", NodeStructureHelper.author(0), handler.nodeName(author));
}
/**
* Tests whether the value of a node can be queried.
*/
@Test
public void testNodeHandlerValue() {
final NodeHandler<ImmutableNode> handler = createHandler(ROOT_AUTHORS_TREE);
ImmutableNode work = nodeForKey(handler, "Shakespeare/The Tempest");
final int year = 1611;
work = work.setValue(year);
assertEquals("Wrong value", year, handler.getValue(work));
}
}