package nodebox.node; import com.google.common.collect.ImmutableList; import org.junit.Before; import org.junit.Test; import java.util.List; import static nodebox.util.Assertions.assertResultsEqual; import static org.junit.Assert.*; public class NodeLibraryControllerTest { private NodeLibraryController controller; @Before public void setUp() throws Exception { controller = NodeLibraryController.create(); } @Test public void testChangeRenderedNode() throws Exception { Node alpha = Node.ROOT.withName("alpha"); Node beta = Node.ROOT.withName("beta"); controller.addNode("/", alpha); controller.addNode("/", beta); assertNull(controller.getRootNode().getRenderedChild()); controller.setRenderedChild("/", "alpha"); assertEquals(alpha, controller.getRootNode().getRenderedChild()); controller.setRenderedChild("/", "beta"); assertEquals(beta, controller.getRootNode().getRenderedChild()); controller.setRenderedChild("/", ""); assertNull(controller.getRootNode().getRenderedChild()); } @Test public void testAddPort() { Node gamma = Node.ROOT.withName("gamma"); controller.addNode("/", gamma); assertFalse(controller.getNodeLibrary().getNodeForPath("/gamma").hasInput("p")); controller.addPort("/gamma", "p", Port.TYPE_INT); assertTrue(controller.getNodeLibrary().getNodeForPath("/gamma").hasInput("p")); } @Test public void testRemovePort() { Node gamma = Node.ROOT.withName("gamma").withInputAdded(Port.intPort("p", 0)); controller.addNode("/", gamma); assertTrue(controller.getNodeLibrary().getNodeForPath("/gamma").hasInput("p")); controller.removePort("/", "gamma", "p"); assertFalse(controller.getNodeLibrary().getNodeForPath("/gamma").hasInput("p")); } @Test public void testRemoveConnectedPort() { Node gamma = Node.ROOT.withName("gamma").withInputAdded(Port.intPort("p", 0)); Node delta = Node.ROOT.withName("delta").withInputAdded(Port.intPort("q", 0)); controller.addNode("/", gamma); controller.addNode("/", delta); controller.connect("/", gamma, delta, delta.getInput("q")); assertTrue(controller.getNodeLibrary().getNodeForPath("/delta").hasInput("q")); assertEquals(1, controller.getRootNode().getConnections().size()); controller.removePort("/", "delta", "q"); assertFalse(controller.getNodeLibrary().getNodeForPath("/delta").hasInput("q")); assertEquals(0, controller.getRootNode().getConnections().size()); } @Test public void testAddNode() { NodeLibrary library; Node parent = Node.NETWORK.withName("parent"); controller.addNode("/", parent); library = controller.getNodeLibrary(); assertTrue(library.getRoot().hasChild("parent")); assertSame(parent, library.getRoot().getChild("parent")); assertSame(parent, library.getNodeForPath("/parent")); Node child = Node.ROOT.withName("child"); controller.addNode("/parent", child); library = controller.getNodeLibrary(); assertTrue(library.getRoot().getChild("parent").hasChild("child")); assertSame(child, library.getNodeForPath("/parent/child")); assertNotSame("No longer the same since the new parent has an extra child.", parent, library.getNodeForPath("/parent")); } /** * Test that adding nodes gives them unique names. * <p/> * addNode() is only used for pasting. */ @Test public void testAddNodeUniqueName() { Node gamma = Node.ROOT.withName("gamma"); controller.addNode("/", gamma); assertTrue(controller.getRootNode().hasChild("gamma")); controller.addNode("/", gamma); assertTrue(controller.getRootNode().hasChild("gamma1")); } /** * Test that copying/pasting nodes with connections works. */ @Test public void testCopyPasteNodes() { createTestNetwork(); // Now paste them controller.pasteNodes("/", controller.getRootNode(), ImmutableList.of(controller.getNode("/alpha"), controller.getNode("/beta"))); Node root = controller.getRootNode(); assertTrue(root.hasChild("alpha1")); assertTrue(root.hasChild("beta1")); assertTrue(root.isConnected("alpha1")); assertTrue(root.isConnected("beta1")); } /** * Test that cutting/pasting nodes with connections works. */ @Test public void testCutPasteNodes() { createTestNetwork(); Node root = controller.getRootNode(); Node alpha = controller.getNode("/alpha"); Node beta = controller.getNode("/beta"); controller.removeNode("/", "alpha"); controller.removeNode("/", "beta"); controller.pasteNodes("/", root, ImmutableList.of(alpha, beta)); assertTrue(root.hasChild("alpha")); assertTrue(root.hasChild("beta")); assertTrue(root.isConnected("alpha")); assertTrue(root.isConnected("beta")); } /** * Test that copying/pasting nodes with connections into subnetworks works. */ @Test public void testPasteIntoSubnetwork() { createTestNetwork(); controller.addNode("/", Node.NETWORK.withName("subnet")); controller.pasteNodes("/subnet", controller.getRootNode(), ImmutableList.of(controller.getNode("/alpha"), controller.getNode("/beta"))); Node subnet = controller.getNode("/subnet"); assertTrue(subnet.hasChild("alpha")); assertTrue(subnet.hasChild("beta")); assertTrue(subnet.isConnected("alpha")); assertTrue(subnet.isConnected("beta")); } /** * Test pasting a node with its output connected. * The output should not be replaced. */ @Test public void testPasteOutputNode() { createTestNetwork(); // Now paste them controller.pasteNodes("/", controller.getRootNode(), ImmutableList.of(controller.getNode("/alpha"))); Node root = controller.getRootNode(); assertTrue(root.hasChild("alpha1")); assertTrue(root.isConnected("alpha")); assertTrue(root.isConnected("beta")); assertFalse(root.isConnected("alpha1")); } /** * Test pasting a node with its output connected. * A new connection is made. */ @Test public void testPasteInputNode() { createTestNetwork(); // Now paste them controller.pasteNodes("/", controller.getRootNode(), ImmutableList.of(controller.getNode("/beta"))); Node root = controller.getRootNode(); assertTrue(root.hasChild("beta1")); assertTrue(root.isConnected("alpha")); assertTrue(root.isConnected("beta")); assertTrue(root.isConnected("beta1")); } /** * Test pasting a node with its output connected but with the input removed between copying/pasting. * No new connection is made. */ @Test public void testPasteInputNodePartial() { createTestNetwork(); Node root = controller.getRootNode(); controller.removeNode("/", "alpha"); // Now paste them controller.pasteNodes("/", root, ImmutableList.of(controller.getNode("/beta"))); root = controller.getRootNode(); assertTrue(root.hasChild("beta1")); assertFalse(root.hasChild("alpha")); assertFalse(root.isConnected("beta")); assertFalse(root.isConnected("beta1")); } private void createTestNetwork() { Node alpha = Node.ROOT.withName("alpha"); Node beta = Node.ROOT.withName("beta").withInputAdded(Port.floatPort("number", 0.0)); controller.addNode("/", alpha); controller.addNode("/", beta); controller.connect("/", alpha, beta, beta.getInput("number")); Node root = controller.getRootNode(); assertTrue(root.isConnected("alpha")); assertTrue(root.isConnected("beta")); } @Test public void testCreateNode() { Node proto = Node.ROOT.withName("protoNode"); controller.createNode("/", proto); assertTrue(controller.getRootNode().hasChild("protoNode1")); assertSame(proto, controller.getNodeLibrary().getNodeForPath("/protoNode1").getPrototype()); } @Test public void testRemoveNode() { Node child = Node.ROOT.withName("child"); controller.addNode("/", child); assertTrue(controller.getRootNode().hasChild("child")); controller.removeNode("/", "child"); assertFalse(controller.getRootNode().hasChild("child")); assertNull(controller.getNodeLibrary().getNodeForPath("/child")); } @Test public void testSetPortValue() { Node numberNode = Node.ROOT.withName("number").withInputAdded(Port.intPort("value", 10)); controller.addNode("/", numberNode); assertEquals(10, controller.getNode("/number").getInput("value").intValue()); controller.setPortValue("/number", "value", 42); assertEquals(42, controller.getNode("/number").getInput("value").intValue()); } @Test public void testSetPortValueInSubNet() { Node numberNode = Node.ROOT.withName("number").withFunction("math/number").withInputAdded(Port.floatPort("value", 10.0)); Node subNet = Node.NETWORK.withName("subNet").withChildAdded(numberNode).withRenderedChildName("number"); controller.addNode("/", subNet); assertResultsEqual(controller.getRootNode(), controller.getNode("/subNet"), 10.0); controller.setPortValue("/subNet/number", "value", 42.0); assertResultsEqual(controller.getRootNode(), controller.getNode("/subNet"), 42.0); } @Test public void testUniqueNodeName() { Node proto = Node.ROOT.withName("protoNode"); controller.createNode("/", proto); controller.createNode("/", proto); controller.createNode("/", proto); Node rootNode = controller.getRootNode(); assertFalse(rootNode.hasChild("protoNode")); assertTrue(rootNode.hasChild("protoNode1")); assertTrue(rootNode.hasChild("protoNode2")); assertTrue(rootNode.hasChild("protoNode3")); controller.removeNode("/", "protoNode2"); rootNode = controller.getRootNode(); assertFalse(rootNode.hasChild("protoNode2")); controller.createNode("/", proto); rootNode = controller.getRootNode(); assertTrue(rootNode.hasChild("protoNode2")); assertFalse(rootNode.hasChild("protoNode4")); } @Test public void testSimpleRename() { Node child = Node.ROOT.withName("child"); controller.addNode("/", child); controller.renameNode("/", "child", "n"); assertFalse(controller.getRootNode().hasChild("child")); assertTrue(controller.getRootNode().hasChild("n")); } @Test public void testCommentNode() { Node child = Node.ROOT.withName("child"); controller.addNode("/", child); controller.commentNode("/", "child", "test"); assertTrue(controller.getRootNode().hasChild("child")); assertTrue(controller.getNode("/child").getComment().equals("test")); } @Test public void testRenderedNodeRenaming() { Node child = Node.ROOT.withName("child"); controller.addNode("/", child); controller.setRenderedChild("/", "child"); assertTrue(controller.getRootNode().getRenderedChildName().equals("child")); controller.renameNode("/", "child", "n"); assertTrue(controller.getRootNode().getRenderedChildName().equals("n")); } @Test public void testSimpleConnection() { assertEquals(0, controller.getRootNode().getConnections().size()); createSimpleConnection(); assertEquals(1, controller.getRootNode().getConnections().size()); Connection c = controller.getRootNode().getConnections().get(0); assertEquals("negate", c.getInputNode()); assertEquals("value", c.getInputPort()); assertEquals("number", c.getOutputNode()); assertResultsEqual(controller.getRootNode(), controller.getNode("/negate"), -20.0); } @Test public void testSimpleDisconnect() { createSimpleConnection(); Connection c = controller.getRootNode().getConnections().get(0); controller.disconnect("/", c); assertEquals(0, controller.getRootNode().getConnections().size()); } @Test public void testRemoveNodeWithConnections() { createSimpleConnection(); Node invert2Node = Node.ROOT.withName("invert2").withFunction("math/negate").withInputAdded(Port.floatPort("value", 0)); controller.addNode("/", invert2Node); controller.connect("/", controller.getNode("/number"), invert2Node, invert2Node.getInput("value")); assertEquals(2, controller.getRootNode().getConnections().size()); controller.removeNode("/", "number"); assertEquals(0, controller.getRootNode().getConnections().size()); } @Test public void testConnectedNodeRenaming() { createSimpleConnection(); controller.renameNode("/", "negate", "invert"); assertEquals(1, controller.getRootNode().getConnections().size()); Connection c = controller.getRootNode().getConnections().get(0); assertEquals("invert", c.getInputNode()); assertEquals("value", c.getInputPort()); assertEquals("number", c.getOutputNode()); } @Test public void testRemoveNodeWithRendered() { Node alpha = Node.ROOT.withName("alpha"); controller.addNode("/", alpha); controller.setRenderedChild("/", "alpha"); Node beta = Node.ROOT.withName("beta"); controller.addNode("/", beta); assertEquals("alpha", controller.getRootNode().getRenderedChildName()); controller.removeNode("/", "beta"); assertEquals("alpha", controller.getRootNode().getRenderedChildName()); controller.removeNode("/", "alpha"); assertEquals("", controller.getRootNode().getRenderedChildName()); assertNull(controller.getRootNode().getRenderedChild()); } @Test public void testPublish() { Node invertNode = Node.ROOT.withName("negate").withFunction("math/negate").withInputAdded(Port.floatPort("value", 0)); controller.addNode("/", Node.NETWORK.withName("subnet")); controller.addNode("/subnet", invertNode); controller.setRenderedChild("/subnet", "negate"); controller.publish("/subnet", "negate", "value", "n"); assertTrue(controller.getNode("/subnet").hasPublishedInput("n")); controller.setPortValue("/subnet", "n", 42.0); assertEquals(42, controller.getNode("/subnet").getPublishedPort("n").intValue()); assertEquals(42, controller.getNode("/subnet/negate").getInput("value").intValue()); Node numberNode = Node.ROOT.withName("number").withFunction("math/number").withInputAdded(Port.floatPort("value", 20)); controller.addNode("/", numberNode); controller.connect("/", "number", "subnet", "n"); assertResultsEqual(controller.getRootNode(), controller.getNode("/subnet"), -20.0); controller.setPortValue("/number", "value", 55.0); assertResultsEqual(controller.getRootNode(), controller.getNode("/subnet"), -55.0); } @Test public void testSimpleUnpublish() { Node invertNode = Node.ROOT.withName("negate").withFunction("math/negate").withInputAdded(Port.floatPort("value", 0)); controller.addNode("/", Node.NETWORK.withName("subnet")); controller.addNode("/subnet", invertNode); controller.publish("/subnet", "negate", "value", "n"); controller.unpublish("/subnet", "n"); assertFalse(controller.getNode("/subnet").hasPublishedInput("n")); } @Test public void testGroupIntoNetwork() { Node numberNode = Node.ROOT.withName("number").withFunction("math/number").withInputAdded(Port.floatPort("value", 15)); controller.addNode("/", numberNode); Node invertNode = Node.ROOT.withName("negate").withFunction("math/negate").withInputAdded(Port.floatPort("value", 0)); controller.addNode("/", invertNode); controller.setRenderedChild("/", "negate"); controller.connect("/", controller.getNode("/number"), invertNode, invertNode.getInput("value")); Node subnet = controller.groupIntoNetwork("/", ImmutableList.of(numberNode, invertNode)); assertTrue(subnet.hasChild("number")); assertTrue(subnet.hasChild("negate")); assertEquals(1, subnet.getConnections().size()); assertEquals(1, controller.getRootNode().getChildren().size()); assertSame(subnet, controller.getRootNode().getChild("network1")); assertResultsEqual(controller.getRootNode(), controller.getNode("/network1"), -15.0); } @Test public void testGroupAndPublish() { Node piNode = Node.ROOT.withName("pi").withFunction("math/number").withInputAdded(Port.floatPort("value", 3.1415)); controller.addNode("/", piNode); Node multiply1Node = Node.ROOT.withName("multiply1").withFunction("math/multiply") .withInputAdded(Port.floatPort("value1", 0)) .withInputAdded(Port.floatPort("value2", 2)); controller.addNode("/", multiply1Node); Node multiply2Node = Node.ROOT.withName("multiply2").withFunction("math/multiply") .withInputAdded(Port.floatPort("value1", 0)) .withInputAdded(Port.floatPort("value2", 0)); controller.addNode("/", multiply2Node); Node radiusNode = Node.ROOT.withName("radius").withFunction("math/number").withInputAdded(Port.floatPort("value", 2)); controller.addNode("/", radiusNode); controller.connect("/", "pi", "multiply1", "value1"); controller.connect("/", "radius", "multiply2", "value1"); controller.connect("/", "multiply1", "multiply2", "value2"); controller.setRenderedChild("/", "multiply2"); Node subnet1 = controller.groupIntoNetwork("/", ImmutableList.of(piNode, multiply1Node, multiply2Node)); Node root = controller.getRootNode(); assertEquals(2, root.getChildren().size()); assertTrue(root.hasChild(radiusNode)); assertTrue(root.hasChild(subnet1)); assertEquals(1, subnet1.getInputs().size()); assertEquals("value1", subnet1.getInputs().get(0).getName()); assertEquals(1, root.getConnections().size()); assertEquals("radius", root.getConnection("network1", "value1").getOutputNode()); } @Test public void testGroupingAndPortNaming() { Node number1Node = Node.ROOT.withName("number1").withFunction("math/number").withInputAdded(Port.floatPort("value", 2)); controller.addNode("/", number1Node); Node multiply1Node = Node.ROOT.withName("multiply1").withFunction("math/multiply") .withInputAdded(Port.floatPort("value1", 0)) .withInputAdded(Port.floatPort("value2", 3)); controller.addNode("/", multiply1Node); Node add1Node = Node.ROOT.withName("add1").withFunction("math/add") .withInputAdded(Port.floatPort("value1", 0)) .withInputAdded(Port.floatPort("value2", 3)); controller.addNode("/", add1Node); Node divide1Node = Node.ROOT.withName("divide1").withFunction("math/divide") .withInputAdded(Port.floatPort("value1", 0)) .withInputAdded(Port.floatPort("value2", 1)); controller.addNode("/", divide1Node); controller.connect("/", "number1", "multiply1", "value1"); controller.connect("/", "number1", "add1", "value1"); controller.connect("/", "multiply1", "divide1", "value1"); controller.connect("/", "add1", "divide1", "value2"); controller.setRenderedChild("/", "divide1"); assertResultsEqual(controller.getRootNode(), controller.getNode("/divide1"), 1.2); Node subnet1 = controller.groupIntoNetwork("/", ImmutableList.of(multiply1Node, add1Node, divide1Node)); Node root = controller.getRootNode(); assertEquals(2, root.getChildren().size()); assertTrue(root.hasChild(number1Node)); assertTrue(root.hasChild(subnet1)); assertEquals(2, subnet1.getInputs().size()); List<Port> inputs = subnet1.getInputs(); assertEquals("value1_1", inputs.get(0).getName()); assertEquals("value1_2", inputs.get(1).getName()); assertEquals(2, root.getConnections().size()); assertEquals("number1", root.getConnection("network1", "value1_1").getOutputNode()); assertEquals("number1", root.getConnection("network1", "value1_2").getOutputNode()); assertResultsEqual(controller.getRootNode(), controller.getNode("/network1"), 1.2); } /** * Test if a valid subnetwork can be formed where the rendered node is not an * end point in the network. */ @Test public void testGroupingRenderedBeforeEnd() { Node numberNode = Node.ROOT.withName("number").withFunction("math/number").withInputAdded(Port.floatPort("value", 20)); Node invert1Node = Node.ROOT.withName("negate1").withFunction("math/negate").withInputAdded(Port.floatPort("value", 0)); Node invert2Node = Node.ROOT.withName("negate2").withFunction("math/negate").withInputAdded(Port.floatPort("value", 0)); controller.addNode("/", numberNode); controller.addNode("/", invert1Node); controller.addNode("/", invert2Node); controller.connect("/", numberNode, invert1Node, invert1Node.getInput("value")); controller.connect("/", numberNode, invert2Node, invert2Node.getInput("value")); controller.setRenderedChild("/", "number"); controller.groupIntoNetwork("/", ImmutableList.of(numberNode, invert1Node, invert2Node)); assertResultsEqual(controller.getRootNode(), controller.getNode("/network1"), 20.0); } private void createSimpleConnection() { Node numberNode = Node.ROOT.withName("number").withFunction("math/number").withInputAdded(Port.floatPort("value", 20)); Node invertNode = Node.ROOT.withName("negate").withFunction("math/negate").withInputAdded(Port.floatPort("value", 0)); controller.addNode("/", numberNode); controller.addNode("/", invertNode); controller.connect("/", numberNode, invertNode, invertNode.getInput("value")); } }