/*
* Grapht, an open source dependency injector.
* Copyright 2014-2015 various contributors (see CONTRIBUTORS.txt)
* Copyright 2010-2014 Regents of the University of Minnesota
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.grouplens.grapht.graph;
import com.google.common.collect.Lists;
import org.hamcrest.Matcher;
import org.junit.Before;
import org.junit.Test;
import java.util.List;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertThat;
public class MergePoolTest {
MergePool<String,String> pool;
@Before
public void createPool() {
pool = MergePool.create();
}
@Test
public void testSingletonNode() {
DAGNode<String,String> node = DAGNode.singleton("foo");
DAGNode<String,String> merged = pool.merge(node);
// merging a singleton node should just return the node
assertThat(merged, sameInstance(node));
}
@Test
public void testReuseSingleton() {
DAGNode<String,String> node = DAGNode.singleton("foo");
DAGNode<String,String> node2 = DAGNode.singleton("foo");
// simplify first so it's in the pool
pool.merge(node);
// and merge the second
DAGNode<String,String> merged = pool.merge(node2);
// the first node should have been reused
assertThat(merged, sameInstance(node));
}
@Test
public void testMergeDescendants() {
DAGNode<String,String> node = DAGNode.singleton("foo");
DAGNode<String,String> node2 = DAGNode.singleton("foo");
DAGNode<String,String> root =
DAGNode.<String,String>newBuilder("root")
.addEdge(node, "hello")
.addEdge(node2, "goodbye")
.build();
DAGNode<String,String> merged = pool.merge(root);
// now, node and node2 should be merged
// new graph (since they're merged)
assertThat(merged, not(sameInstance(root)));
// only 2 nodes (root has 2 edges to same node)
assertThat(merged.getReachableNodes(), hasSize(2));
// two edges have same target
List<DAGEdge<String,String>> nbrs =
Lists.newArrayList(merged.getOutgoingEdges());
// both edges have the same instance
assertThat(nbrs.get(1).getTail(),
sameInstance(nbrs.get(0).getTail()));
// it's one of the nodes we gave it
assertThat(nbrs.get(0).getTail(),
anyOf(sameInstance(node),
sameInstance(node2)));
// and a new singleton should be merged
assertThat(pool.merge(DAGNode.<String, String>singleton("foo")),
anyOf(sameInstance(node),
sameInstance(node2)));
// re-merging our old root should give us the same node
assertThat(pool.merge(root), sameInstance(merged));
}
@Test
public void testMergeWithChildren() {
DAGNode<String,String> node = DAGNode.singleton("foo");
DAGNode<String,String> p1 =
DAGNode.<String,String>newBuilder("child")
.addEdge(node, "k1")
.build();
DAGNode<String,String> node2 = DAGNode.singleton("foo");
// second parent node. it will have different label to test that labels are ignored
DAGNode<String,String> p2 =
DAGNode.<String,String>newBuilder("child")
.addEdge(node, "k2")
.build();
DAGNode<String,String> root =
DAGNode.<String,String>newBuilder("root")
.addEdge(p1, "hello")
.addEdge(p2, "fish")
.build();
DAGNode<String,String> merged = pool.merge(root);
// now, p1 and p2 should be merged
// new graph (since they're merged)
assertThat(merged, not(sameInstance(root)));
// only 3 nodes (root has 2 edges to now-merged nodes)
assertThat(merged.getReachableNodes(), hasSize(3));
// it has one of the leaves
assertThat(merged.getReachableNodes(),
(Matcher) anyOf(hasItem(sameInstance(node)),
hasItem(sameInstance(node2))));
// two edges have same target
List<DAGEdge<String,String>> nbrs =
Lists.newArrayList(merged.getOutgoingEdges());
// both edges have the same instance
assertThat(nbrs.get(1).getTail(),
sameInstance(nbrs.get(0).getTail()));
// and a new singleton should be merged
assertThat(pool.merge(DAGNode.<String, String>singleton("foo")),
anyOf(sameInstance(node),
sameInstance(node2)));
// re-merging a child should give us a previously-merged node
assertThat(pool.merge(p2), isIn(merged.getReachableNodes()));
assertThat(pool.merge(p1), isIn(merged.getReachableNodes()));
}
}