From 1bfbc942eb2d6670937f021c9703eab6c1d46b33 Mon Sep 17 00:00:00 2001 From: buczekp <buczekp> Date: Tue, 24 May 2011 07:57:04 +0000 Subject: [PATCH] [LMS-2104] refactored VirtualHierarchicalContent to write more reliable tests SVN: 21454 --- .../common/io/VirtualHierarchicalContent.java | 125 ++++++-- .../io/VirtualHierarchicalContentTest.java | 171 ++++++++--- .../cisd/common/io/VirtualNodeTest.java | 269 ++++++++++++++++++ 3 files changed, 513 insertions(+), 52 deletions(-) create mode 100644 common/sourceTest/java/ch/systemsx/cisd/common/io/VirtualNodeTest.java diff --git a/common/source/java/ch/systemsx/cisd/common/io/VirtualHierarchicalContent.java b/common/source/java/ch/systemsx/cisd/common/io/VirtualHierarchicalContent.java index d36d8ba98a2..6cc44962d4e 100644 --- a/common/source/java/ch/systemsx/cisd/common/io/VirtualHierarchicalContent.java +++ b/common/source/java/ch/systemsx/cisd/common/io/VirtualHierarchicalContent.java @@ -26,6 +26,7 @@ import java.util.Map; import ch.systemsx.cisd.base.exceptions.IOExceptionUnchecked; import ch.systemsx.cisd.base.io.IRandomAccessFile; +import ch.systemsx.cisd.common.collections.CollectionUtils; /** * Simple {@link IHierarchicalContent} implementation for virtual data sets with dynamic behavior @@ -36,17 +37,40 @@ import ch.systemsx.cisd.base.io.IRandomAccessFile; class VirtualHierarchicalContent implements IHierarchicalContent { + final static IVirtualNodeMergerFactory DEFAULT_MERGER_FACTORY = new IVirtualNodeMergerFactory() + { + public IVirtualNodeMerger createNodeMerger() + { + return new VirtualNodeMerger(this); + } + + public IVirtualNodeListMerger createNodeListMerger() + { + return new VirtualNodeListMerger(this); + } + }; + + private final IVirtualNodeMergerFactory mergerFactory; + private final List<IHierarchicalContent> components; private IHierarchicalContentNode rootNode; // cached - public VirtualHierarchicalContent(List<IHierarchicalContent> components) + // for tests + VirtualHierarchicalContent(IVirtualNodeMergerFactory mergerFactory, + List<IHierarchicalContent> components) { if (components == null || components.isEmpty()) { throw new IllegalArgumentException("Undefined contents"); } this.components = components; + this.mergerFactory = mergerFactory; + } + + public VirtualHierarchicalContent(List<IHierarchicalContent> components) + { + this(DEFAULT_MERGER_FACTORY, components); } public IHierarchicalContentNode getRootNode() @@ -113,9 +137,51 @@ class VirtualHierarchicalContent implements IHierarchicalContent } } + // + // Object + // + + @Override + public String toString() + { + return "VirtualHierarchicalContent [components=" + + CollectionUtils.abbreviate(components, 10) + "]"; + } + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + for (IHierarchicalContent component : components) + { + result = prime * result + component.hashCode(); + } + return result; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (!(obj instanceof VirtualHierarchicalContent)) + { + return false; + } + VirtualHierarchicalContent other = (VirtualHierarchicalContent) obj; + return components.equals(other.components); + } + private IHierarchicalContentNode mergeNodes(INodeProvider provider) { - IVirtualNodeMerger merger = createNodeMerger(); + IVirtualNodeMerger merger = mergerFactory.createNodeMerger(); for (IHierarchicalContent component : components) { IHierarchicalContentNode componentNode = provider.tryGetNode(component); @@ -129,7 +195,7 @@ class VirtualHierarchicalContent implements IHierarchicalContent private List<IHierarchicalContentNode> mergeNodeLists(INodeListProvider listProvider) { - IVirtualNodeListMerger listMerger = createNodeListMerger(); + IVirtualNodeListMerger listMerger = mergerFactory.createNodeListMerger(); for (IHierarchicalContent component : components) { List<IHierarchicalContentNode> componentNodes = listProvider.getNodeList(component); @@ -138,24 +204,25 @@ class VirtualHierarchicalContent implements IHierarchicalContent return listMerger.createMergedNodeList(); } - private static IVirtualNodeMerger createNodeMerger() + private interface INodeProvider { - return new VirtualNodeMerger(); + IHierarchicalContentNode tryGetNode(IHierarchicalContent content); } - private static IVirtualNodeListMerger createNodeListMerger() + private interface INodeListProvider { - return new VirtualNodeListMerger(); + List<IHierarchicalContentNode> getNodeList(IHierarchicalContent content); } - interface INodeProvider - { - IHierarchicalContentNode tryGetNode(IHierarchicalContent content); - } + // + // NOTE: following interfaces and classes are exposed (package protected) only for testing + // - interface INodeListProvider + interface IVirtualNodeMergerFactory { - List<IHierarchicalContentNode> getNodeList(IHierarchicalContent content); + IVirtualNodeMerger createNodeMerger(); + + IVirtualNodeListMerger createNodeListMerger(); } interface IVirtualNodeMerger @@ -181,11 +248,18 @@ class VirtualHierarchicalContent implements IHierarchicalContent */ static class VirtualNodeMerger implements IVirtualNodeMerger { + private final IVirtualNodeMergerFactory factory; + // For convenience in iteration the order of these nodes is reversed. // It is the first node, not the last one, which is overriding all files of other nodes. - private LinkedList<IHierarchicalContentNode> nodes = + private final LinkedList<IHierarchicalContentNode> nodes = new LinkedList<IHierarchicalContentNode>(); + public VirtualNodeMerger(IVirtualNodeMergerFactory factory) + { + this.factory = factory; + } + public void addNode(IHierarchicalContentNode node) { nodes.addFirst(node); @@ -193,7 +267,7 @@ class VirtualHierarchicalContent implements IHierarchicalContent public IHierarchicalContentNode createMergedNode() { - return new VirtualNode(nodes); + return new VirtualNode(factory, nodes); } } @@ -202,8 +276,16 @@ class VirtualHierarchicalContent implements IHierarchicalContent */ static class VirtualNodeListMerger implements IVirtualNodeListMerger { + private final IVirtualNodeMergerFactory nodeMergerFactory; + // relative path -> merger (with preserved order) - Map<String, IVirtualNodeMerger> mergers = new LinkedHashMap<String, IVirtualNodeMerger>(); + private final Map<String, IVirtualNodeMerger> mergers = + new LinkedHashMap<String, IVirtualNodeMerger>(); + + public VirtualNodeListMerger(IVirtualNodeMergerFactory nodeMergerFactory) + { + this.nodeMergerFactory = nodeMergerFactory; + } public void addNodes(List<IHierarchicalContentNode> nodes) { @@ -213,7 +295,7 @@ class VirtualHierarchicalContent implements IHierarchicalContent IVirtualNodeMerger merger = mergers.get(relativePath); if (merger == null) { - merger = createNodeMerger(); + merger = nodeMergerFactory.createNodeMerger(); mergers.put(relativePath, merger); } merger.addNode(node); @@ -231,6 +313,7 @@ class VirtualHierarchicalContent implements IHierarchicalContent } } + // NOTE: exposed for tests /** * {@link IHierarchicalContentNode} implementation merging nodes with the same relative paths: * <ul> @@ -241,14 +324,18 @@ class VirtualHierarchicalContent implements IHierarchicalContent static class VirtualNode implements IHierarchicalContentNode { + private final IVirtualNodeMergerFactory nodeMergerFactory; + private final List<IHierarchicalContentNode> nodes; - public VirtualNode(List<IHierarchicalContentNode> nodes) + public VirtualNode(IVirtualNodeMergerFactory factory, List<IHierarchicalContentNode> nodes) { + assert nodes != null : "Undefined nodes."; if (nodes.isEmpty()) { throw new IllegalArgumentException("Resource doesn't exist."); } + this.nodeMergerFactory = factory; this.nodes = nodes; } @@ -305,7 +392,7 @@ class VirtualHierarchicalContent implements IHierarchicalContent public List<IHierarchicalContentNode> getChildNodes() throws UnsupportedOperationException { - IVirtualNodeListMerger listMerger = createNodeListMerger(); + IVirtualNodeListMerger listMerger = nodeMergerFactory.createNodeListMerger(); for (IHierarchicalContentNode node : nodes) { listMerger.addNodes(node.getChildNodes()); diff --git a/common/sourceTest/java/ch/systemsx/cisd/common/io/VirtualHierarchicalContentTest.java b/common/sourceTest/java/ch/systemsx/cisd/common/io/VirtualHierarchicalContentTest.java index 023c7c44062..8ad4711581f 100644 --- a/common/sourceTest/java/ch/systemsx/cisd/common/io/VirtualHierarchicalContentTest.java +++ b/common/sourceTest/java/ch/systemsx/cisd/common/io/VirtualHierarchicalContentTest.java @@ -16,45 +16,72 @@ package ch.systemsx.cisd.common.io; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.jmock.Expectations; import org.jmock.Mockery; +import org.testng.AssertJUnit; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; -import ch.systemsx.cisd.base.tests.AbstractFileSystemTestCase; +import ch.systemsx.cisd.common.io.VirtualHierarchicalContent.IVirtualNodeListMerger; +import ch.systemsx.cisd.common.io.VirtualHierarchicalContent.IVirtualNodeMerger; +import ch.systemsx.cisd.common.io.VirtualHierarchicalContent.IVirtualNodeMergerFactory; /** * Unit tests for {@link VirtualHierarchicalContent} * * @author Piotr Buczek */ -public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase +public class VirtualHierarchicalContentTest extends AssertJUnit { - private IHierarchicalContent[] components; + private IHierarchicalContent[] components; // real contents // mocks private Mockery context; + private IVirtualNodeMergerFactory mergerFactory; + + private IVirtualNodeMerger nodeMerger; + + private IVirtualNodeListMerger nodeListMerger; + private IHierarchicalContent component1; private IHierarchicalContent component2; private IHierarchicalContent component3; + private IHierarchicalContentNode node1; + + private IHierarchicalContentNode node2; + + private IHierarchicalContentNode node3; + + private IHierarchicalContentNode mergedNode; + @BeforeMethod public void beforeMethod() throws Exception { context = new Mockery(); - component1 = context.mock(IHierarchicalContent.class, "component 1"); - component2 = context.mock(IHierarchicalContent.class, "component 2"); - component3 = context.mock(IHierarchicalContent.class, "component 3"); + mergerFactory = context.mock(IVirtualNodeMergerFactory.class); + nodeMerger = context.mock(IVirtualNodeMerger.class); + nodeListMerger = context.mock(IVirtualNodeListMerger.class); + + component1 = context.mock(IHierarchicalContent.class, "component1"); + component2 = context.mock(IHierarchicalContent.class, "component2"); + component3 = context.mock(IHierarchicalContent.class, "component3"); + + node1 = context.mock(IHierarchicalContentNode.class, "node1"); + node2 = context.mock(IHierarchicalContentNode.class, "node2"); + node3 = context.mock(IHierarchicalContentNode.class, "node3"); + mergedNode = context.mock(IHierarchicalContentNode.class, "mergedNode"); components = new IHierarchicalContent[] { component1, component2, component3 }; @@ -68,9 +95,13 @@ public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase context.assertIsSatisfied(); } + // + // tests mocking IVirtualNodeMergerFactory + // + private IHierarchicalContent createContent(IHierarchicalContent... contents) { - return new VirtualHierarchicalContent(Arrays.asList(contents)); + return new VirtualHierarchicalContent(mergerFactory, Arrays.asList(contents)); } @Test @@ -78,7 +109,7 @@ public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase { try { - createContent(); + new VirtualHierarchicalContent(mergerFactory, null); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException ex) { @@ -87,7 +118,7 @@ public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase try { - createContent(new IHierarchicalContent[0]); + new VirtualHierarchicalContent(mergerFactory, new ArrayList<IHierarchicalContent>()); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException ex) { @@ -97,7 +128,28 @@ public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase context.assertIsSatisfied(); } - // TODO public void testEqualsAndHashCode() + @Test + public void testEqualsAndHashCode() + { + IHierarchicalContent virtualContent = createContent(components); + IHierarchicalContent virtualContentSameComponents = createContent(components.clone()); + assertEquals(virtualContent, virtualContentSameComponents); + assertEquals(virtualContent.hashCode(), virtualContentSameComponents.hashCode()); + + IHierarchicalContent[] subComponents = + { component1, component2 }; + IHierarchicalContent virtualContentSubComponents = createContent(subComponents); + assertFalse(virtualContent.equals(virtualContentSubComponents)); + assertFalse(virtualContent.hashCode() == virtualContentSubComponents.hashCode()); + + IHierarchicalContent[] reorderedComponents = new IHierarchicalContent[] + { component1, component3, component2 }; + IHierarchicalContent virtualContentReorderedComponents = createContent(reorderedComponents); + assertFalse(virtualContent.equals(virtualContentReorderedComponents)); + assertFalse(virtualContent.hashCode() == virtualContentReorderedComponents.hashCode()); + + context.assertIsSatisfied(); + } @Test public void testClose() @@ -126,18 +178,29 @@ public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase context.checking(new Expectations() { { - for (IHierarchicalContent component : components) - { - one(component).getRootNode(); - } + one(mergerFactory).createNodeMerger(); + will(returnValue(nodeMerger)); + + one(component1).getRootNode(); + will(returnValue(node1)); + one(component2).getRootNode(); + will(returnValue(node2)); + // component3 will not be added to merged nodes + one(component3).getRootNode(); + will(returnValue(null)); // no exception expected + + one(nodeMerger).addNode(node1); + one(nodeMerger).addNode(node2); + one(nodeMerger).createMergedNode(); + will(returnValue(mergedNode)); } }); - IHierarchicalContentNode root1 = virtualContent.getRootNode(); - // 2nd call uses cache (doesn't invoke getRootNode() on components) - IHierarchicalContentNode root2 = virtualContent.getRootNode(); - assertSame(root1, root2); - // TODO merging & handling exceptions not tested + IHierarchicalContentNode virtualRoot = virtualContent.getRootNode(); + // 2nd call uses cache (no method in expectation should be invoked twice) + IHierarchicalContentNode virtualRoot2 = virtualContent.getRootNode(); + assertSame(virtualRoot, virtualRoot2); + assertSame(mergedNode, virtualRoot); context.assertIsSatisfied(); } @@ -151,16 +214,26 @@ public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase context.checking(new Expectations() { { + one(mergerFactory).createNodeMerger(); + will(returnValue(nodeMerger)); + one(component1).getNode(relativePath); + will(returnValue(node1)); one(component2).getNode(relativePath); + will(returnValue(node2)); + // component3 will not be added to merged nodes one(component3).getNode(relativePath); will(throwException(new IllegalArgumentException(""))); + + one(nodeMerger).addNode(node1); + one(nodeMerger).addNode(node2); + one(nodeMerger).createMergedNode(); + will(returnValue(mergedNode)); } }); IHierarchicalContentNode node = virtualContent.getNode(relativePath); - assertNotNull(node); - // TODO merging & handling exceptions not tested + assertSame(mergedNode, node); context.assertIsSatisfied(); } @@ -171,19 +244,35 @@ public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase final IHierarchicalContent virtualContent = createContent(components); final String pattern = "rel.*path.?pattern"; + // contents of these lists is not significang in the test + final List<IHierarchicalContentNode> list1 = Arrays.asList(node1, node2); + final List<IHierarchicalContentNode> list2 = Arrays.asList(node3); + final List<IHierarchicalContentNode> list3 = Arrays.asList(); + final List<IHierarchicalContentNode> mergedNodeList = Arrays.asList(mergedNode); + context.checking(new Expectations() { { - for (IHierarchicalContent component : components) - { - one(component).listMatchingNodes(pattern); - } + one(mergerFactory).createNodeListMerger(); + will(returnValue(nodeListMerger)); + + one(component1).listMatchingNodes(pattern); + will(returnValue(list1)); + one(component2).listMatchingNodes(pattern); + will(returnValue(list2)); + one(component3).listMatchingNodes(pattern); + will(returnValue(list3)); + + one(nodeListMerger).addNodes(list1); + one(nodeListMerger).addNodes(list2); + one(nodeListMerger).addNodes(list3); + one(nodeListMerger).createMergedNodeList(); + will(returnValue(mergedNodeList)); } }); List<IHierarchicalContentNode> nodeList = virtualContent.listMatchingNodes(pattern); - assertNotNull(nodeList); - // TODO merging & handling exceptions not tested + assertSame(mergedNodeList, nodeList); context.assertIsSatisfied(); } @@ -195,20 +284,36 @@ public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase final String startingPath = "some/dir"; final String pattern = "file.*name.?pattern"; + // contents of these lists is not important in the test + final List<IHierarchicalContentNode> list1 = Arrays.asList(node1, node2); + final List<IHierarchicalContentNode> list2 = Arrays.asList(node3); + final List<IHierarchicalContentNode> list3 = Arrays.asList(); + final List<IHierarchicalContentNode> mergedNodeList = Arrays.asList(mergedNode); + context.checking(new Expectations() { { - for (IHierarchicalContent component : components) - { - one(component).listMatchingNodes(startingPath, pattern); - } + one(mergerFactory).createNodeListMerger(); + will(returnValue(nodeListMerger)); + + one(component1).listMatchingNodes(startingPath, pattern); + will(returnValue(list1)); + one(component2).listMatchingNodes(startingPath, pattern); + will(returnValue(list2)); + one(component3).listMatchingNodes(startingPath, pattern); + will(returnValue(list3)); + + one(nodeListMerger).addNodes(list1); + one(nodeListMerger).addNodes(list2); + one(nodeListMerger).addNodes(list3); + one(nodeListMerger).createMergedNodeList(); + will(returnValue(mergedNodeList)); } }); List<IHierarchicalContentNode> nodeList = virtualContent.listMatchingNodes(startingPath, pattern); - assertNotNull(nodeList); - // TODO merging & handling exceptions not tested + assertSame(mergedNodeList, nodeList); context.assertIsSatisfied(); } diff --git a/common/sourceTest/java/ch/systemsx/cisd/common/io/VirtualNodeTest.java b/common/sourceTest/java/ch/systemsx/cisd/common/io/VirtualNodeTest.java new file mode 100644 index 00000000000..6f6be3fac76 --- /dev/null +++ b/common/sourceTest/java/ch/systemsx/cisd/common/io/VirtualNodeTest.java @@ -0,0 +1,269 @@ +/* + * Copyright 2010 ETH Zuerich, CISD + * + * 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 ch.systemsx.cisd.common.io; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.jmock.Expectations; +import org.jmock.Mockery; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import ch.systemsx.cisd.common.io.VirtualHierarchicalContent.IVirtualNodeListMerger; +import ch.systemsx.cisd.common.io.VirtualHierarchicalContent.IVirtualNodeMergerFactory; +import ch.systemsx.cisd.common.io.VirtualHierarchicalContent.VirtualNode; + +/** + * Unit tests for {@link VirtualNode} + * + * @author Piotr Buczek + */ +public class VirtualNodeTest extends AssertJUnit +{ + + private List<IHierarchicalContentNode> nodes; // real nodes + + // mocks + + private Mockery context; + + private IVirtualNodeMergerFactory mergerFactory; + + @SuppressWarnings("unused") + private IVirtualNodeListMerger nodeListMerger; + + private IHierarchicalContentNode node1; + + private IHierarchicalContentNode node2; + + private IHierarchicalContentNode node3; + + @SuppressWarnings("unused") + private IHierarchicalContentNode mergedNode; + + @BeforeMethod + public void beforeMethod() throws Exception + { + context = new Mockery(); + + mergerFactory = context.mock(IVirtualNodeMergerFactory.class); + nodeListMerger = context.mock(IVirtualNodeListMerger.class); + + node1 = context.mock(IHierarchicalContentNode.class, "node1"); + node2 = context.mock(IHierarchicalContentNode.class, "node2"); + node3 = context.mock(IHierarchicalContentNode.class, "node3"); + mergedNode = context.mock(IHierarchicalContentNode.class, "mergedNode"); + + nodes = Arrays.asList(node1, node2, node3); + } + + @AfterMethod + public void tearDown() + { + // To following line of code should also be called at the end of each test method. + // Otherwise one do not known which test failed. + context.assertIsSatisfied(); + } + + // + // tests mocking IVirtualNodeMergerFactory + // + + private IHierarchicalContentNode createVirtualNode() + { + return new VirtualNode(mergerFactory, nodes); + } + + @Test + public void testFailWithNullOrEmptyNodes() + { + try + { + new VirtualNode(mergerFactory, null); + fail("Expected AssertionError"); + } catch (AssertionError ex) + { + assertEquals("Undefined nodes.", ex.getMessage()); + } + + try + { + new VirtualNode(mergerFactory, new ArrayList<IHierarchicalContentNode>()); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException ex) + { + assertEquals("Resource doesn't exist.", ex.getMessage()); + } + + context.assertIsSatisfied(); + } + + // @Test + // public void testEqualsAndHashCode() + // { + // IHierarchicalContent virtualContent = createContent(components); + // IHierarchicalContent virtualContentSameComponents = createContent(components.clone()); + // assertEquals(virtualContent, virtualContentSameComponents); + // assertEquals(virtualContent.hashCode(), virtualContentSameComponents.hashCode()); + // + // IHierarchicalContent[] subComponents = + // { component1, component2 }; + // IHierarchicalContent virtualContentSubComponents = createContent(subComponents); + // assertFalse(virtualContent.equals(virtualContentSubComponents)); + // assertFalse(virtualContent.hashCode() == virtualContentSubComponents.hashCode()); + // + // IHierarchicalContent[] reorderedComponents = new IHierarchicalContent[] + // { component1, component3, component2 }; + // IHierarchicalContent virtualContentReorderedComponents = createContent(reorderedComponents); + // assertFalse(virtualContent.equals(virtualContentReorderedComponents)); + // assertFalse(virtualContent.hashCode() == virtualContentReorderedComponents.hashCode()); + // + // context.assertIsSatisfied(); + // } + + @Test + public void testGetName() + { + final IHierarchicalContentNode virtualNode = createVirtualNode(); + + final String nodeName = "some name"; + + context.checking(new Expectations() + { + { + // first nodes name is taken + one(node1).getName(); + will(returnValue(nodeName)); + } + }); + + String virtualName = virtualNode.getName(); + assertEquals(nodeName, virtualName); + + context.assertIsSatisfied(); + } + + @Test + public void testGetRelativePath() + { + final IHierarchicalContentNode virtualNode = createVirtualNode(); + + final String relativePath = "relative/path"; + + context.checking(new Expectations() + { + { + // first nodes path is taken + one(node1).getRelativePath(); + will(returnValue(relativePath)); + } + }); + + String virtualRelativePath = virtualNode.getRelativePath(); + assertEquals(relativePath, virtualRelativePath); + + context.assertIsSatisfied(); + } + + @Test + public void testGetParentRelativePath() + { + final IHierarchicalContentNode virtualNode = createVirtualNode(); + + final String parentRelativePath = "parent/relative/path"; + + context.checking(new Expectations() + { + { + // first nodes path is taken + one(node1).getParentRelativePath(); + will(returnValue(parentRelativePath)); + } + }); + + String virtualParentRelativePath = virtualNode.getParentRelativePath(); + assertEquals(parentRelativePath, virtualParentRelativePath); + + context.assertIsSatisfied(); + } + + @Test + public void testExists() + { + final IHierarchicalContentNode virtualNode = createVirtualNode(); + + // contract: at least one node needs to exist for virtual node to exist + + // 1st case: 2nd out of 3 nodes exist, 3rd node is not asked at all + context.checking(new Expectations() + { + { + one(node1).exists(); + will(returnValue(false)); + + one(node2).exists(); + will(returnValue(true)); + } + }); + assertTrue(virtualNode.exists()); + + // 2st case: all nodes don't exist + context.checking(new Expectations() + { + { + for (IHierarchicalContentNode node : nodes) + { + one(node).exists(); + will(returnValue(false)); + } + } + }); + assertFalse(virtualNode.exists()); + + context.assertIsSatisfied(); + } + + @Test + public void testIsDirectory() + { + final IHierarchicalContentNode virtualNode = createVirtualNode(); + + context.checking(new Expectations() + { + { + // first node is asked twice giving different answer + one(node1).isDirectory(); + will(returnValue(true)); + + one(node1).isDirectory(); + will(returnValue(false)); + } + }); + + // check twice with different answer from mocked node + assertTrue(virtualNode.isDirectory()); + assertFalse(virtualNode.isDirectory()); + + context.assertIsSatisfied(); + } + + // TODO 2011-05-24, Piotr Buczek: write remaining tests +} -- GitLab