Skip to content
Snippets Groups Projects
Commit 1bfbc942 authored by buczekp's avatar buczekp
Browse files

[LMS-2104] refactored VirtualHierarchicalContent to write more reliable tests

SVN: 21454
parent 9c109bbd
No related branches found
No related tags found
No related merge requests found
...@@ -26,6 +26,7 @@ import java.util.Map; ...@@ -26,6 +26,7 @@ import java.util.Map;
import ch.systemsx.cisd.base.exceptions.IOExceptionUnchecked; import ch.systemsx.cisd.base.exceptions.IOExceptionUnchecked;
import ch.systemsx.cisd.base.io.IRandomAccessFile; 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 * Simple {@link IHierarchicalContent} implementation for virtual data sets with dynamic behavior
...@@ -36,17 +37,40 @@ import ch.systemsx.cisd.base.io.IRandomAccessFile; ...@@ -36,17 +37,40 @@ import ch.systemsx.cisd.base.io.IRandomAccessFile;
class VirtualHierarchicalContent implements IHierarchicalContent 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 final List<IHierarchicalContent> components;
private IHierarchicalContentNode rootNode; // cached private IHierarchicalContentNode rootNode; // cached
public VirtualHierarchicalContent(List<IHierarchicalContent> components) // for tests
VirtualHierarchicalContent(IVirtualNodeMergerFactory mergerFactory,
List<IHierarchicalContent> components)
{ {
if (components == null || components.isEmpty()) if (components == null || components.isEmpty())
{ {
throw new IllegalArgumentException("Undefined contents"); throw new IllegalArgumentException("Undefined contents");
} }
this.components = components; this.components = components;
this.mergerFactory = mergerFactory;
}
public VirtualHierarchicalContent(List<IHierarchicalContent> components)
{
this(DEFAULT_MERGER_FACTORY, components);
} }
public IHierarchicalContentNode getRootNode() public IHierarchicalContentNode getRootNode()
...@@ -113,9 +137,51 @@ class VirtualHierarchicalContent implements IHierarchicalContent ...@@ -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) private IHierarchicalContentNode mergeNodes(INodeProvider provider)
{ {
IVirtualNodeMerger merger = createNodeMerger(); IVirtualNodeMerger merger = mergerFactory.createNodeMerger();
for (IHierarchicalContent component : components) for (IHierarchicalContent component : components)
{ {
IHierarchicalContentNode componentNode = provider.tryGetNode(component); IHierarchicalContentNode componentNode = provider.tryGetNode(component);
...@@ -129,7 +195,7 @@ class VirtualHierarchicalContent implements IHierarchicalContent ...@@ -129,7 +195,7 @@ class VirtualHierarchicalContent implements IHierarchicalContent
private List<IHierarchicalContentNode> mergeNodeLists(INodeListProvider listProvider) private List<IHierarchicalContentNode> mergeNodeLists(INodeListProvider listProvider)
{ {
IVirtualNodeListMerger listMerger = createNodeListMerger(); IVirtualNodeListMerger listMerger = mergerFactory.createNodeListMerger();
for (IHierarchicalContent component : components) for (IHierarchicalContent component : components)
{ {
List<IHierarchicalContentNode> componentNodes = listProvider.getNodeList(component); List<IHierarchicalContentNode> componentNodes = listProvider.getNodeList(component);
...@@ -138,24 +204,25 @@ class VirtualHierarchicalContent implements IHierarchicalContent ...@@ -138,24 +204,25 @@ class VirtualHierarchicalContent implements IHierarchicalContent
return listMerger.createMergedNodeList(); 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 //
{ // NOTE: following interfaces and classes are exposed (package protected) only for testing
IHierarchicalContentNode tryGetNode(IHierarchicalContent content); //
}
interface INodeListProvider interface IVirtualNodeMergerFactory
{ {
List<IHierarchicalContentNode> getNodeList(IHierarchicalContent content); IVirtualNodeMerger createNodeMerger();
IVirtualNodeListMerger createNodeListMerger();
} }
interface IVirtualNodeMerger interface IVirtualNodeMerger
...@@ -181,11 +248,18 @@ class VirtualHierarchicalContent implements IHierarchicalContent ...@@ -181,11 +248,18 @@ class VirtualHierarchicalContent implements IHierarchicalContent
*/ */
static class VirtualNodeMerger implements IVirtualNodeMerger static class VirtualNodeMerger implements IVirtualNodeMerger
{ {
private final IVirtualNodeMergerFactory factory;
// For convenience in iteration the order of these nodes is reversed. // 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. // 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>(); new LinkedList<IHierarchicalContentNode>();
public VirtualNodeMerger(IVirtualNodeMergerFactory factory)
{
this.factory = factory;
}
public void addNode(IHierarchicalContentNode node) public void addNode(IHierarchicalContentNode node)
{ {
nodes.addFirst(node); nodes.addFirst(node);
...@@ -193,7 +267,7 @@ class VirtualHierarchicalContent implements IHierarchicalContent ...@@ -193,7 +267,7 @@ class VirtualHierarchicalContent implements IHierarchicalContent
public IHierarchicalContentNode createMergedNode() public IHierarchicalContentNode createMergedNode()
{ {
return new VirtualNode(nodes); return new VirtualNode(factory, nodes);
} }
} }
...@@ -202,8 +276,16 @@ class VirtualHierarchicalContent implements IHierarchicalContent ...@@ -202,8 +276,16 @@ class VirtualHierarchicalContent implements IHierarchicalContent
*/ */
static class VirtualNodeListMerger implements IVirtualNodeListMerger static class VirtualNodeListMerger implements IVirtualNodeListMerger
{ {
private final IVirtualNodeMergerFactory nodeMergerFactory;
// relative path -> merger (with preserved order) // 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) public void addNodes(List<IHierarchicalContentNode> nodes)
{ {
...@@ -213,7 +295,7 @@ class VirtualHierarchicalContent implements IHierarchicalContent ...@@ -213,7 +295,7 @@ class VirtualHierarchicalContent implements IHierarchicalContent
IVirtualNodeMerger merger = mergers.get(relativePath); IVirtualNodeMerger merger = mergers.get(relativePath);
if (merger == null) if (merger == null)
{ {
merger = createNodeMerger(); merger = nodeMergerFactory.createNodeMerger();
mergers.put(relativePath, merger); mergers.put(relativePath, merger);
} }
merger.addNode(node); merger.addNode(node);
...@@ -231,6 +313,7 @@ class VirtualHierarchicalContent implements IHierarchicalContent ...@@ -231,6 +313,7 @@ class VirtualHierarchicalContent implements IHierarchicalContent
} }
} }
// NOTE: exposed for tests
/** /**
* {@link IHierarchicalContentNode} implementation merging nodes with the same relative paths: * {@link IHierarchicalContentNode} implementation merging nodes with the same relative paths:
* <ul> * <ul>
...@@ -241,14 +324,18 @@ class VirtualHierarchicalContent implements IHierarchicalContent ...@@ -241,14 +324,18 @@ class VirtualHierarchicalContent implements IHierarchicalContent
static class VirtualNode implements IHierarchicalContentNode static class VirtualNode implements IHierarchicalContentNode
{ {
private final IVirtualNodeMergerFactory nodeMergerFactory;
private final List<IHierarchicalContentNode> nodes; 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()) if (nodes.isEmpty())
{ {
throw new IllegalArgumentException("Resource doesn't exist."); throw new IllegalArgumentException("Resource doesn't exist.");
} }
this.nodeMergerFactory = factory;
this.nodes = nodes; this.nodes = nodes;
} }
...@@ -305,7 +392,7 @@ class VirtualHierarchicalContent implements IHierarchicalContent ...@@ -305,7 +392,7 @@ class VirtualHierarchicalContent implements IHierarchicalContent
public List<IHierarchicalContentNode> getChildNodes() throws UnsupportedOperationException public List<IHierarchicalContentNode> getChildNodes() throws UnsupportedOperationException
{ {
IVirtualNodeListMerger listMerger = createNodeListMerger(); IVirtualNodeListMerger listMerger = nodeMergerFactory.createNodeListMerger();
for (IHierarchicalContentNode node : nodes) for (IHierarchicalContentNode node : nodes)
{ {
listMerger.addNodes(node.getChildNodes()); listMerger.addNodes(node.getChildNodes());
......
...@@ -16,45 +16,72 @@ ...@@ -16,45 +16,72 @@
package ch.systemsx.cisd.common.io; package ch.systemsx.cisd.common.io;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import org.jmock.Expectations; import org.jmock.Expectations;
import org.jmock.Mockery; import org.jmock.Mockery;
import org.testng.AssertJUnit;
import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod; import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test; 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} * Unit tests for {@link VirtualHierarchicalContent}
* *
* @author Piotr Buczek * @author Piotr Buczek
*/ */
public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase public class VirtualHierarchicalContentTest extends AssertJUnit
{ {
private IHierarchicalContent[] components; private IHierarchicalContent[] components; // real contents
// mocks // mocks
private Mockery context; private Mockery context;
private IVirtualNodeMergerFactory mergerFactory;
private IVirtualNodeMerger nodeMerger;
private IVirtualNodeListMerger nodeListMerger;
private IHierarchicalContent component1; private IHierarchicalContent component1;
private IHierarchicalContent component2; private IHierarchicalContent component2;
private IHierarchicalContent component3; private IHierarchicalContent component3;
private IHierarchicalContentNode node1;
private IHierarchicalContentNode node2;
private IHierarchicalContentNode node3;
private IHierarchicalContentNode mergedNode;
@BeforeMethod @BeforeMethod
public void beforeMethod() throws Exception public void beforeMethod() throws Exception
{ {
context = new Mockery(); context = new Mockery();
component1 = context.mock(IHierarchicalContent.class, "component 1"); mergerFactory = context.mock(IVirtualNodeMergerFactory.class);
component2 = context.mock(IHierarchicalContent.class, "component 2"); nodeMerger = context.mock(IVirtualNodeMerger.class);
component3 = context.mock(IHierarchicalContent.class, "component 3"); 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[] components = new IHierarchicalContent[]
{ component1, component2, component3 }; { component1, component2, component3 };
...@@ -68,9 +95,13 @@ public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase ...@@ -68,9 +95,13 @@ public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase
context.assertIsSatisfied(); context.assertIsSatisfied();
} }
//
// tests mocking IVirtualNodeMergerFactory
//
private IHierarchicalContent createContent(IHierarchicalContent... contents) private IHierarchicalContent createContent(IHierarchicalContent... contents)
{ {
return new VirtualHierarchicalContent(Arrays.asList(contents)); return new VirtualHierarchicalContent(mergerFactory, Arrays.asList(contents));
} }
@Test @Test
...@@ -78,7 +109,7 @@ public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase ...@@ -78,7 +109,7 @@ public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase
{ {
try try
{ {
createContent(); new VirtualHierarchicalContent(mergerFactory, null);
fail("Expected IllegalArgumentException"); fail("Expected IllegalArgumentException");
} catch (IllegalArgumentException ex) } catch (IllegalArgumentException ex)
{ {
...@@ -87,7 +118,7 @@ public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase ...@@ -87,7 +118,7 @@ public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase
try try
{ {
createContent(new IHierarchicalContent[0]); new VirtualHierarchicalContent(mergerFactory, new ArrayList<IHierarchicalContent>());
fail("Expected IllegalArgumentException"); fail("Expected IllegalArgumentException");
} catch (IllegalArgumentException ex) } catch (IllegalArgumentException ex)
{ {
...@@ -97,7 +128,28 @@ public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase ...@@ -97,7 +128,28 @@ public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase
context.assertIsSatisfied(); 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 @Test
public void testClose() public void testClose()
...@@ -126,18 +178,29 @@ public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase ...@@ -126,18 +178,29 @@ public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase
context.checking(new Expectations() context.checking(new Expectations()
{ {
{ {
for (IHierarchicalContent component : components) one(mergerFactory).createNodeMerger();
{ will(returnValue(nodeMerger));
one(component).getRootNode();
} 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(); IHierarchicalContentNode virtualRoot = virtualContent.getRootNode();
// 2nd call uses cache (doesn't invoke getRootNode() on components) // 2nd call uses cache (no method in expectation should be invoked twice)
IHierarchicalContentNode root2 = virtualContent.getRootNode(); IHierarchicalContentNode virtualRoot2 = virtualContent.getRootNode();
assertSame(root1, root2); assertSame(virtualRoot, virtualRoot2);
// TODO merging & handling exceptions not tested assertSame(mergedNode, virtualRoot);
context.assertIsSatisfied(); context.assertIsSatisfied();
} }
...@@ -151,16 +214,26 @@ public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase ...@@ -151,16 +214,26 @@ public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase
context.checking(new Expectations() context.checking(new Expectations()
{ {
{ {
one(mergerFactory).createNodeMerger();
will(returnValue(nodeMerger));
one(component1).getNode(relativePath); one(component1).getNode(relativePath);
will(returnValue(node1));
one(component2).getNode(relativePath); one(component2).getNode(relativePath);
will(returnValue(node2));
// component3 will not be added to merged nodes
one(component3).getNode(relativePath); one(component3).getNode(relativePath);
will(throwException(new IllegalArgumentException(""))); will(throwException(new IllegalArgumentException("")));
one(nodeMerger).addNode(node1);
one(nodeMerger).addNode(node2);
one(nodeMerger).createMergedNode();
will(returnValue(mergedNode));
} }
}); });
IHierarchicalContentNode node = virtualContent.getNode(relativePath); IHierarchicalContentNode node = virtualContent.getNode(relativePath);
assertNotNull(node); assertSame(mergedNode, node);
// TODO merging & handling exceptions not tested
context.assertIsSatisfied(); context.assertIsSatisfied();
} }
...@@ -171,19 +244,35 @@ public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase ...@@ -171,19 +244,35 @@ public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase
final IHierarchicalContent virtualContent = createContent(components); final IHierarchicalContent virtualContent = createContent(components);
final String pattern = "rel.*path.?pattern"; 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() context.checking(new Expectations()
{ {
{ {
for (IHierarchicalContent component : components) one(mergerFactory).createNodeListMerger();
{ will(returnValue(nodeListMerger));
one(component).listMatchingNodes(pattern);
} 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); List<IHierarchicalContentNode> nodeList = virtualContent.listMatchingNodes(pattern);
assertNotNull(nodeList); assertSame(mergedNodeList, nodeList);
// TODO merging & handling exceptions not tested
context.assertIsSatisfied(); context.assertIsSatisfied();
} }
...@@ -195,20 +284,36 @@ public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase ...@@ -195,20 +284,36 @@ public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase
final String startingPath = "some/dir"; final String startingPath = "some/dir";
final String pattern = "file.*name.?pattern"; 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() context.checking(new Expectations()
{ {
{ {
for (IHierarchicalContent component : components) one(mergerFactory).createNodeListMerger();
{ will(returnValue(nodeListMerger));
one(component).listMatchingNodes(startingPath, pattern);
} 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 = List<IHierarchicalContentNode> nodeList =
virtualContent.listMatchingNodes(startingPath, pattern); virtualContent.listMatchingNodes(startingPath, pattern);
assertNotNull(nodeList); assertSame(mergedNodeList, nodeList);
// TODO merging & handling exceptions not tested
context.assertIsSatisfied(); context.assertIsSatisfied();
} }
......
/*
* 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
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment