From 67f5c5dc274837efbe5dbc57dca0ce26e4e32349 Mon Sep 17 00:00:00 2001 From: buczekp <buczekp> Date: Fri, 20 May 2011 11:27:05 +0000 Subject: [PATCH] [LMS-2104] minor changes to virtual content & basic tests SVN: 21416 --- .../common/io/VirtualHierarchicalContent.java | 26 ++- .../io/VirtualHierarchicalContentTest.java | 216 ++++++++++++++++++ 2 files changed, 231 insertions(+), 11 deletions(-) create mode 100644 common/sourceTest/java/ch/systemsx/cisd/common/io/VirtualHierarchicalContentTest.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 dbc9794e942..d36d8ba98a2 100644 --- a/common/source/java/ch/systemsx/cisd/common/io/VirtualHierarchicalContent.java +++ b/common/source/java/ch/systemsx/cisd/common/io/VirtualHierarchicalContent.java @@ -33,7 +33,7 @@ import ch.systemsx.cisd.base.io.IRandomAccessFile; * * @author Piotr Buczek */ -public class VirtualHierarchicalContent implements IHierarchicalContent +class VirtualHierarchicalContent implements IHierarchicalContent { private final List<IHierarchicalContent> components; @@ -42,6 +42,10 @@ public class VirtualHierarchicalContent implements IHierarchicalContent public VirtualHierarchicalContent(List<IHierarchicalContent> components) { + if (components == null || components.isEmpty()) + { + throw new IllegalArgumentException("Undefined contents"); + } this.components = components; } @@ -72,7 +76,7 @@ public class VirtualHierarchicalContent implements IHierarchicalContent return content.getNode(relativePath); } catch (IllegalArgumentException ex) { - return null; + return null; // ignore (not all components need to contain the node) } } }); @@ -111,7 +115,7 @@ public class VirtualHierarchicalContent implements IHierarchicalContent private IHierarchicalContentNode mergeNodes(INodeProvider provider) { - IVirtualNodesMerger merger = createNodesMerger(); + IVirtualNodeMerger merger = createNodeMerger(); for (IHierarchicalContent component : components) { IHierarchicalContentNode componentNode = provider.tryGetNode(component); @@ -134,9 +138,9 @@ public class VirtualHierarchicalContent implements IHierarchicalContent return listMerger.createMergedNodeList(); } - private static IVirtualNodesMerger createNodesMerger() + private static IVirtualNodeMerger createNodeMerger() { - return new VirtualNodesMerger(); + return new VirtualNodeMerger(); } private static IVirtualNodeListMerger createNodeListMerger() @@ -154,7 +158,7 @@ public class VirtualHierarchicalContent implements IHierarchicalContent List<IHierarchicalContentNode> getNodeList(IHierarchicalContent content); } - interface IVirtualNodesMerger + interface IVirtualNodeMerger { void addNode(IHierarchicalContentNode node); @@ -175,7 +179,7 @@ public class VirtualHierarchicalContent implements IHierarchicalContent * <li>For normal files uses the 'last' node's file. * </ul> */ - static class VirtualNodesMerger implements IVirtualNodesMerger + static class VirtualNodeMerger implements IVirtualNodeMerger { // 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. @@ -199,17 +203,17 @@ public class VirtualHierarchicalContent implements IHierarchicalContent static class VirtualNodeListMerger implements IVirtualNodeListMerger { // relative path -> merger (with preserved order) - Map<String, IVirtualNodesMerger> mergers = new LinkedHashMap<String, IVirtualNodesMerger>(); + Map<String, IVirtualNodeMerger> mergers = new LinkedHashMap<String, IVirtualNodeMerger>(); public void addNodes(List<IHierarchicalContentNode> nodes) { for (IHierarchicalContentNode node : nodes) { String relativePath = node.getRelativePath(); - IVirtualNodesMerger merger = mergers.get(relativePath); + IVirtualNodeMerger merger = mergers.get(relativePath); if (merger == null) { - merger = createNodesMerger(); + merger = createNodeMerger(); mergers.put(relativePath, merger); } merger.addNode(node); @@ -219,7 +223,7 @@ public class VirtualHierarchicalContent implements IHierarchicalContent public List<IHierarchicalContentNode> createMergedNodeList() { List<IHierarchicalContentNode> result = new ArrayList<IHierarchicalContentNode>(); - for (IVirtualNodesMerger merger : mergers.values()) + for (IVirtualNodeMerger merger : mergers.values()) { result.add(merger.createMergedNode()); } diff --git a/common/sourceTest/java/ch/systemsx/cisd/common/io/VirtualHierarchicalContentTest.java b/common/sourceTest/java/ch/systemsx/cisd/common/io/VirtualHierarchicalContentTest.java new file mode 100644 index 00000000000..023c7c44062 --- /dev/null +++ b/common/sourceTest/java/ch/systemsx/cisd/common/io/VirtualHierarchicalContentTest.java @@ -0,0 +1,216 @@ +/* + * 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.Arrays; +import java.util.List; + +import org.jmock.Expectations; +import org.jmock.Mockery; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import ch.systemsx.cisd.base.tests.AbstractFileSystemTestCase; + +/** + * Unit tests for {@link VirtualHierarchicalContent} + * + * @author Piotr Buczek + */ +public class VirtualHierarchicalContentTest extends AbstractFileSystemTestCase +{ + + private IHierarchicalContent[] components; + + // mocks + + private Mockery context; + + private IHierarchicalContent component1; + + private IHierarchicalContent component2; + + private IHierarchicalContent component3; + + @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"); + + components = new IHierarchicalContent[] + { component1, component2, component3 }; + } + + @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(); + } + + private IHierarchicalContent createContent(IHierarchicalContent... contents) + { + return new VirtualHierarchicalContent(Arrays.asList(contents)); + } + + @Test + public void testFailWithNullOrEmptyComponents() + { + try + { + createContent(); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException ex) + { + assertEquals("Undefined contents", ex.getMessage()); + } + + try + { + createContent(new IHierarchicalContent[0]); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException ex) + { + assertEquals("Undefined contents", ex.getMessage()); + } + + context.assertIsSatisfied(); + } + + // TODO public void testEqualsAndHashCode() + + @Test + public void testClose() + { + final IHierarchicalContent virtualContent = createContent(components); + + context.checking(new Expectations() + { + { + for (IHierarchicalContent component : components) + { + one(component).close(); + } + } + }); + virtualContent.close(); + + context.assertIsSatisfied(); + } + + @Test + public void testGetRootNode() + { + final IHierarchicalContent virtualContent = createContent(components); + + context.checking(new Expectations() + { + { + for (IHierarchicalContent component : components) + { + one(component).getRootNode(); + } + } + }); + + 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 + + context.assertIsSatisfied(); + } + + @Test + public void testGetNode() + { + final IHierarchicalContent virtualContent = createContent(components); + final String relativePath = "rel/path"; + + context.checking(new Expectations() + { + { + one(component1).getNode(relativePath); + one(component2).getNode(relativePath); + one(component3).getNode(relativePath); + will(throwException(new IllegalArgumentException(""))); + } + }); + + IHierarchicalContentNode node = virtualContent.getNode(relativePath); + assertNotNull(node); + // TODO merging & handling exceptions not tested + + context.assertIsSatisfied(); + } + + @Test + public void testListMatchingNodesWithRelativePathPattern() + { + final IHierarchicalContent virtualContent = createContent(components); + final String pattern = "rel.*path.?pattern"; + + context.checking(new Expectations() + { + { + for (IHierarchicalContent component : components) + { + one(component).listMatchingNodes(pattern); + } + } + }); + + List<IHierarchicalContentNode> nodeList = virtualContent.listMatchingNodes(pattern); + assertNotNull(nodeList); + // TODO merging & handling exceptions not tested + + context.assertIsSatisfied(); + } + + @Test + public void testListMatchingNodesWithStartingPath() + { + final IHierarchicalContent virtualContent = createContent(components); + final String startingPath = "some/dir"; + final String pattern = "file.*name.?pattern"; + + context.checking(new Expectations() + { + { + for (IHierarchicalContent component : components) + { + one(component).listMatchingNodes(startingPath, pattern); + } + } + }); + + List<IHierarchicalContentNode> nodeList = + virtualContent.listMatchingNodes(startingPath, pattern); + assertNotNull(nodeList); + // TODO merging & handling exceptions not tested + + context.assertIsSatisfied(); + } + +} -- GitLab