Exemplo n.º 1
0
    def __init__(self, task_id, task_type, duration, status, name, description,
                 follows_task):
        self.task_id = int(task_id)
        self.task_type = task_type
        self.duration = int(duration)
        self.status = status
        self.name = name
        self.description = description
        self.node = NestedTreeNode(self)

        if follows_task is None:
            self.follows_task = 0
        else:
            self.follows_task = int(follows_task)
Exemplo n.º 2
0
class ProjectTask:
    """ Project Task

		This class holds the definition of the Project Task.
	"""
    def __init__(self, task_id, task_type, duration, status, name, description,
                 follows_task):
        self.task_id = int(task_id)
        self.task_type = task_type
        self.duration = int(duration)
        self.status = status
        self.name = name
        self.description = description
        self.node = NestedTreeNode(self)

        if follows_task is None:
            self.follows_task = 0
        else:
            self.follows_task = int(follows_task)

    def toFileString(self):
        ini_format = "task%d = %s,%d,%s,%s,%s,%d\n"
        return ini_format % (self.task_id, self.task_type, self.duration,
                             self.status, self.name, self.description,
                             self.follows_task)

    def getChildren(self):
        """ Get the child tasks of the current task.

			This function will return the list of children that belong
			to this task.
		"""
        return self.node.getChildren()
Exemplo n.º 3
0
    def test_createNode(self):
        """ Create Node Test

			This is a basic test to make sure that the object can be created.
			This is an exploding test to see if the code works.
		"""
        node = NestedTreeNode(0)
        self.assertTrue(True)
Exemplo n.º 4
0
    def build_simple_tree(self, graph):
        """ Builds a simple tree

			This test will create the following tree:

			[root]
             |
             v
			[1] -> [2] -> [11] -> [17] -> [18]
                    |      |
					|      v
					|     [12] -> [13] -> [14] -> [15] -> [16]
					|
					v
				   [3] -> [4] -> [5] -> [9] -> [10]
                                  |
								  v
                                 [6] -> [7] -> [8]

			This function returns a node that can used to amend the tree.
		"""
        # create the nodes
        nodes = []
        for i in range(19):
            nodes.append(NestedTreeNode(i))

        graph.addChildNode(nodes[1])
        nodes[1].addNodeAfter(nodes[2])
        nodes[2].addNodeAfter(nodes[11])
        nodes[11].addNodeAfter(nodes[17])
        nodes[17].addNodeAfter(nodes[18])

        nodes[2].addChildNode(nodes[3])
        nodes[3].addNodeAfter(nodes[4])
        nodes[4].addNodeAfter(nodes[5])
        nodes[5].addNodeAfter(nodes[9])
        nodes[9].addNodeAfter(nodes[10])

        nodes[5].addChildNode(nodes[6])
        nodes[6].addNodeAfter(nodes[7])
        nodes[7].addNodeAfter(nodes[8])

        nodes[11].addChildNode(nodes[12])
        nodes[12].addNodeAfter(nodes[13])
        nodes[13].addNodeAfter(nodes[14])
        nodes[14].addNodeAfter(nodes[15])
        nodes[15].addNodeAfter(nodes[16])

        return (nodes[14], nodes[16])
Exemplo n.º 5
0
    def test_3NodeWalk(self):
        """ 3 Node Walk.

			This test adds three nodes in a row to see if the graph code works.

			It then will walk the tree to see if the it finds all the nodes.
		"""
        node1 = NestedTreeNode(1)
        node2 = NestedTreeNode(2)
        node3 = NestedTreeNode(3)

        graph = NestedTree()

        graph.addNodeAfter(node1)
        node1.addNodeAfter(node2)
        node2.addNodeAfter(node3)

        # we are only using the next function for this rest.
        count = 0
        count = graph.walkTree(self.count_function)
        self.assertTrue(count == 3)
Exemplo n.º 6
0
    def test_SingleChildNode(self):
        """ Single Child Node with Walk.

			This test will add a single child node.

			It then will walk the tree to see if the it finds all the nodes.
		"""
        node1 = NestedTreeNode(1)
        graph = NestedTree()

        # insert the child node
        graph.addChildNode(node1)

        # we are only using the next function for this rest.
        count = 0
        count = graph.walkTree(self.count_function)
        self.assertTrue(count == 1)
Exemplo n.º 7
0
    def test_OrderedSiblingsListFirst(self):
        graph = NestedTree()
        (leaf_node, end_node) = self.build_simple_tree(graph)
        leaf_node.addChildNode(NestedTreeNode(98))
        leaf_node.addChildNode(NestedTreeNode(99))

        leaf_node.setLeaf(True)

        # paint the tree - now with it's new leafy-ness
        painted_list = graph.walkTree(self.all_nodes_level_function,
                                      NestedTreeNode.TREE_WALK_PARENTS_FIRST)

        # we are only using the next function for this rest.
        for item in painted_list:
            found = graph.findItemWithColour(
                item[2], NestedTreeNode.TREE_WALK_PARENTS_FIRST, True)
            self.assertIsNotNone(found)
            self.assertEqual(found.payload, item[1])
            self.assertEqual(found.colour, item[2])

        next_node = leaf_node.next_node
        next_node.addChildNode(NestedTreeNode(108))
        next_node.addChildNode(NestedTreeNode(109))
        next_node.setLeaf(True)

        end_node.setLeaf(True)
        end_node.addChildNode(NestedTreeNode(209))
        end_node.addChildNode(NestedTreeNode(210))
        end_node.addChildNode(NestedTreeNode(211))

        # paint the tree - now with it's new leafy-ness
        painted_list = graph.walkTree(self.all_nodes_level_function,
                                      NestedTreeNode.TREE_WALK_PARENTS_FIRST)

        # we are only using the next function for this rest.
        for item in painted_list:
            found = graph.findItemWithColour(
                item[2], NestedTreeNode.TREE_WALK_PARENTS_FIRST, True)
            self.assertIsNotNone(found)
            self.assertEqual(found.payload, item[1])
            self.assertEqual(found.colour, item[2])
Exemplo n.º 8
0
    def test_MakeTree(self):
        """ Make Tree

			The test checks that makeSubTree function works.

			So the following tree:

				[1] -> [2] -> [3] -> [7] -> [8] -> [9] -> [10] -> [11] -> [12]
			                   |
							  {4} -> [5] -> [6]

			can be turned into:

				[1] -> [2] -> [3]
				               |
							  {4} -> [5] -> [6]
							   |
							  {7} -> [8] -> [9]
	 						                 |
							                {10}-> [11] -> [12]

			by calling sub-tree on (3), (9) in that order.

			Then add a new subTree:

				[1] -> [2] -> [3]
				               |
							  {4} -> [5] -> [6]
							   |
							  {7} -> [8] -> [9]
	 						   |             |
							   |            {10}-> [11] -> [12]
                               |
		                      {13} -> [14] -> [15]

			By adding a subTree to (3), this will prove it works. Also doing a
			next walk on (3).
		"""
        graph = NestedTree()

        # create the nodes
        nodes = []

        for i in range(16):
            nodes.append(NestedTreeNode(i))

        graph.addChildNode(nodes[1])
        graph.addChildNode(nodes[2])
        graph.addChildNode(nodes[3])
        graph.addChildNode(nodes[7])
        graph.addChildNode(nodes[8])
        graph.addChildNode(nodes[9])
        graph.addChildNode(nodes[10])
        graph.addChildNode(nodes[11])
        graph.addChildNode(nodes[12])

        nodes[3].addChildNode(nodes[4])
        nodes[4].addNodeAfter(nodes[5])
        nodes[5].addNodeAfter(nodes[6])
        self.assertEqual(graph.walkTree(self.collect_function),
                         list(range(1, 13)))
        self.assertEqual(graph.walkTree(self.plain_levels_function),
                         (2, [(1, 1), (1, 2), (1, 3), (2, 4), (2, 5), (2, 6),
                              (1, 7), (1, 8), (1, 9), (1, 10), (1, 11),
                              (1, 12)]))

        # Subtrees don't make sense unless the whole tree are subtrees.

        # ok, let's let makeSubTree do it's thing.
        #		self.assertTrue(graph.makeSubTree(nodes[3]))
        #		self.assertTrue(graph.makeSubTree(nodes[9]))
        #		self.assertEqual(graph.walkTree(self.collect_function), range(1, 13))
        #		self.assertEqual(graph.walkTree(self.plain_levels_function), (5, [(1, 1), (1, 2), (1, 3), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9), (5, 10), (5, 11), (5, 12)]))

        # ok, add the new sub-tree
        nodes[12].addSubTreeNode(nodes[13])
        nodes[13].addNodeAfter(nodes[14])
        nodes[14].addNodeAfter(nodes[15])

        # walk the tree
        value = graph.walkTree(self.collect_function)

        # now check the ordering is correct
        self.assertEqual(value, list(range(1, 16)))

        # check the shape of the tree
        #self.assertFalse(nodes[3].hasSibling())
        self.assertFalse(nodes[6].hasSibling())
        self.assertFalse(nodes[12].hasSibling())

        self.assertTrue(nodes[3].hasChild())
        self.assertTrue(nodes[12].hasChild())
Exemplo n.º 9
0
    def test_OrderedSiblingsListLast(self):
        graph = NestedTree()
        (leaf_node, end_node) = self.build_simple_tree(graph)

        leaf_node.addChildNode(NestedTreeNode(98))
        leaf_node.addChildNode(NestedTreeNode(99))

        # paint the tree.
        painted_list = graph.walkTree(self.all_nodes_level_function,
                                      NestedTreeNode.TREE_WALK_PARENTS_LAST)
        for item in painted_list:
            found = graph.findItemWithColour(
                item[2], NestedTreeNode.TREE_WALK_PARENTS_LAST, True)
            self.assertIsNotNone(found)
            self.assertEqual(found.payload, item[1])
            self.assertEqual(found.colour, item[2])

        # corner case graphs
        nodes = []

        for count in range(1, 6):
            nodes.append(NestedTreeNode(count))

        graph = NestedTree()

        # the empty graph.
        found = graph.findItemWithColour(1, NestedTreeNode.TREE_WALK_NORMAL,
                                         True)
        self.assertIsNone(found)
        found = graph.findItemWithColour(
            1, NestedTreeNode.TREE_WALK_PARENTS_FIRST, True)
        self.assertIsNone(found)
        found = graph.findItemWithColour(1,
                                         NestedTreeNode.TREE_WALK_PARENTS_LAST,
                                         True)
        self.assertIsNone(found)

        # single node
        graph.addNodeAfter(nodes[1])
        # unpainted
        found = graph.findItemWithColour(1, NestedTreeNode.TREE_WALK_NORMAL,
                                         True)
        self.assertIsNone(found)
        found = graph.findItemWithColour(
            1, NestedTreeNode.TREE_WALK_PARENTS_FIRST, True)
        self.assertIsNone(found)
        found = graph.findItemWithColour(1,
                                         NestedTreeNode.TREE_WALK_PARENTS_LAST,
                                         True)
        self.assertIsNone(found)

        # painted
        nodes[1].colour = 1
        found = graph.findItemWithColour(1, NestedTreeNode.TREE_WALK_NORMAL,
                                         True)
        self.assertIsNotNone(found)
        found = graph.findItemWithColour(
            1, NestedTreeNode.TREE_WALK_PARENTS_FIRST, True)
        self.assertIsNotNone(found)
        found = graph.findItemWithColour(1,
                                         NestedTreeNode.TREE_WALK_PARENTS_LAST,
                                         True)
        self.assertIsNotNone(found)

        # One child - only need to test painted.
        graph = NestedTree()
        graph.colour = 99  # colour the route or it won't search down.
        graph.addChildNode(nodes[1])
        found = graph.findItemWithColour(1, NestedTreeNode.TREE_WALK_NORMAL,
                                         True)
        self.assertIsNotNone(found)
        found = graph.findItemWithColour(
            1, NestedTreeNode.TREE_WALK_PARENTS_FIRST, True)
        self.assertIsNotNone(found)
        found = graph.findItemWithColour(1,
                                         NestedTreeNode.TREE_WALK_PARENTS_LAST,
                                         True)
        self.assertIsNotNone(found)

        graph.addChildNode(nodes[2])
        graph.addChildNode(nodes[3])

        painted_list = graph.walkTree(self.all_nodes_level_function,
                                      NestedTreeNode.TREE_WALK_NORMAL)
        for item in range(1, 4):
            found = graph.findItemWithColour(item,
                                             NestedTreeNode.TREE_WALK_NORMAL,
                                             True)
            self.assertIsNotNone(found)

        painted_list = graph.walkTree(self.all_nodes_level_function,
                                      NestedTreeNode.TREE_WALK_PARENTS_FIRST)
        for item in range(1, 4):
            found = graph.findItemWithColour(
                1, NestedTreeNode.TREE_WALK_PARENTS_FIRST, True)
            self.assertIsNotNone(found)

        painted_list = graph.walkTree(self.all_nodes_level_function,
                                      NestedTreeNode.TREE_WALK_PARENTS_LAST)
        for item in range(1, 4):
            found = graph.findItemWithColour(
                1, NestedTreeNode.TREE_WALK_PARENTS_FIRST, True)
            self.assertIsNotNone(found)
Exemplo n.º 10
0
    def build_tree(self, use_id=True, mark_no_walk=False):
        """
			This function will create the following tree:

			{} this indicate sub-tree nodes that have been created.

			[root]
             |
             v
			[1] -> [2] -> [24] -> [40] -> [41] -> [42] -> [43] -> [44] -> [46]
                    |      |                                       |       |
					|      v                                       v       v
					|     {25} -> [26] -> [27] -> [28] -> [29]    [45]    [47] -> [48]
                    |      |
					|      v
					|     {30} -> [31] -> [32] -> [33] -> [34]
                    |      |
					|      v
					|     {35} -> [36] -> [37] -> [38] -> [39]
					|
					v
				   {3} -> [4] -> [5] -> [12] -> [13] -> [14] -> [15] -> [22] -> [23]
                                  |                              |
								  v                              v
                                 {6} -> [7] -> [8]              {16} -> [17] -> [18]
                                  |                              |
								  v                              v
                                 {9} -> [10] -> [11]            {19} -> [20] -> [21]

			It should be a walk this tree and return the nodes in the correct order.

			If no walk is set, then nodes 3,15,34,41 and 46 a marked as no walk, so that
			only the nodes 16-21 and 47,48 will be skipped as they are no walkers.
		"""
        graph = NestedTree()

        # create the nodes
        nodes = []

        if (use_id):
            for i in range(49):
                nodes.append(NestedTreeNode(i))
        else:
            nodes.append(NestedTreeNode(TestPayload(True)))
            for i in range(1, 49):
                nodes.append(NestedTreeNode(TestPayload()))

        #	[1] -> [2] -> [24] -> [40] -> [41] -> [42] -> [43] -> [44] -> [46]
        graph.addChildNode(nodes[1])
        nodes[1].addNodeAfter(nodes[2])
        nodes[2].addNodeAfter(nodes[24])
        nodes[24].addNodeAfter(nodes[40])
        nodes[40].addNodeAfter(nodes[41])
        nodes[41].addNodeAfter(nodes[42])
        nodes[42].addNodeAfter(nodes[43])
        nodes[43].addNodeAfter(nodes[44])
        nodes[44].addNodeAfter(nodes[46])

        # [25] -> [26] -> [27] -> [28] -> [29]
        nodes[24].addSubTreeNode(nodes[25])
        nodes[25].addNodeAfter(nodes[26])
        nodes[26].addNodeAfter(nodes[27])
        nodes[27].addNodeAfter(nodes[28])
        nodes[28].addNodeAfter(nodes[29])

        # subgraph of 24 - added from 24
        # [30] -> [31] -> [32] -> [33] -> [34]
        nodes[24].addSubTreeNode(nodes[30])
        nodes[30].addNodeAfter(nodes[31])
        nodes[31].addNodeAfter(nodes[32])
        nodes[32].addNodeAfter(nodes[33])
        nodes[33].addNodeAfter(nodes[34])

        # subtree of 24 - added from 24
        # [35] -> [36] -> [37] -> [38] -> [39]
        nodes[24].addSubTreeNode(nodes[35])
        nodes[35].addNodeAfter(nodes[36])
        nodes[36].addNodeAfter(nodes[37])
        nodes[37].addNodeAfter(nodes[38])
        nodes[38].addNodeAfter(nodes[39])

        # child of 44 - single
        nodes[44].addChildNode(nodes[45])

        # child of 46 - pair and end tree on an up.
        nodes[46].addChildNode(nodes[47])
        nodes[47].addNodeAfter(nodes[48])

        # subtree of 2
        #  [3] -> [4] -> [5] -> [12] -> [13] -> [14] -> [15] -> [22] -> [23]
        nodes[2].addSubTreeNode(nodes[3])
        nodes[3].addNodeAfter(nodes[4])
        nodes[4].addNodeAfter(nodes[5])
        nodes[5].addNodeAfter(nodes[12])
        nodes[12].addNodeAfter(nodes[13])
        nodes[13].addNodeAfter(nodes[14])
        nodes[14].addNodeAfter(nodes[15])
        nodes[15].addNodeAfter(nodes[22])
        nodes[22].addNodeAfter(nodes[23])

        # subtree of 5
        # [6] -> [7] -> [8]
        nodes[5].addSubTreeNode(nodes[6])
        nodes[6].addNodeAfter(nodes[7])
        nodes[7].addNodeAfter(nodes[8])

        # subtree of 5
        # [9] -> [10] -> [11]
        nodes[5].addSubTreeNode(nodes[9])
        nodes[9].addNodeAfter(nodes[10])
        nodes[10].addNodeAfter(nodes[11])

        # subtree of 15
        # [16] -> [17] -> [18]
        nodes[15].addSubTreeNode(nodes[16])
        nodes[16].addNodeAfter(nodes[17])
        nodes[17].addNodeAfter(nodes[18])

        # subtree of 15
        # [19] -> [20] -> [21]
        nodes[15].addSubTreeNode(nodes[19])
        nodes[19].addNodeAfter(nodes[20])
        nodes[20].addNodeAfter(nodes[21])

        # Ok, need to make a couple of nodes as no-walk nodes to test that the
        # short walk code works.
        # So 3, 15, 34, and 41 as this are all different in the tree and should prove that
        # the code works.
        if not use_id and mark_no_walk:
            nodes[3].payload.no_walk = True
            nodes[15].payload.no_walk = True
            nodes[34].payload.no_walk = True
            nodes[41].payload.no_walk = True
            nodes[46].payload.no_walk = True

        return graph
Exemplo n.º 11
0
    def test_ChildNodeInsertionDecending(self):
        """
			This tests that the child node insertions work as expected.
			It will also check to see if they can be walked as expected.
		"""
        # test descending insertion - empty list
        graph = NestedTree()
        graph.addChildNode(NestedTreeNode(1), NestedTreeNode.INSERT_DESCENDING)
        graph.addChildNode(NestedTreeNode(4), NestedTreeNode.INSERT_DESCENDING)
        graph.addChildNode(NestedTreeNode(5), NestedTreeNode.INSERT_DESCENDING)
        graph.addChildNode(NestedTreeNode(6), NestedTreeNode.INSERT_DESCENDING)
        graph.addChildNode(NestedTreeNode(7), NestedTreeNode.INSERT_DESCENDING)
        graph.addChildNode(NestedTreeNode(3), NestedTreeNode.INSERT_DESCENDING)
        graph.addChildNode(NestedTreeNode(8), NestedTreeNode.INSERT_DESCENDING)
        graph.addChildNode(NestedTreeNode(2), NestedTreeNode.INSERT_DESCENDING)
        graph.addChildNode(NestedTreeNode(5), NestedTreeNode.INSERT_DESCENDING)
        self.assertEqual(graph.walkTree(self.all_nodes_function),
                         [8, 7, 6, 5, 5, 4, 3, 2, 1],
                         "Basic descending insert")

        # test normal insertion - empty list
        nodes = []
        nodes.append(NestedTreeNode(TestPayload(True)))
        for i in range(1, 10):
            nodes.append(NestedTreeNode(TestPayload()))

        graph = NestedTree()
        graph.addChildNode(nodes[1], NestedTreeNode.INSERT_DESCENDING)
        graph.addChildNode(nodes[4], NestedTreeNode.INSERT_DESCENDING)
        graph.addChildNode(nodes[5], NestedTreeNode.INSERT_DESCENDING)
        graph.addChildNode(nodes[6], NestedTreeNode.INSERT_DESCENDING)
        graph.addChildNode(nodes[7], NestedTreeNode.INSERT_DESCENDING)
        graph.addChildNode(nodes[3], NestedTreeNode.INSERT_DESCENDING)
        graph.addChildNode(nodes[8], NestedTreeNode.INSERT_DESCENDING)
        graph.addChildNode(nodes[2], NestedTreeNode.INSERT_DESCENDING)
        graph.addChildNode(nodes[5], NestedTreeNode.INSERT_DESCENDING)

        nodes[7].addChildNode(nodes[9])

        self.assertEqual((1, [(1, 8, 2), (1, 7, 3), (2, 9, 2), (1, 6, 1),
                              (1, 5, 3), (1, 4, 3), (1, 3, 3), (1, 2, 3),
                              (1, 1, 3)]),
                         graph.walkTree(self.levels_function))
Exemplo n.º 12
0
    def test_ChildNodeInsertion(self):
        """
			This tests that the child node insertions work as expected.
			It will also check to see if they can be walked as expected.
		"""
        # test normal insertion - empty list
        graph = NestedTree()
        graph.addChildNode(NestedTreeNode(1))
        self.assertEqual(graph.walkTree(self.all_nodes_function), [1],
                         "Basic insert failed")

        # test normal insertion - empty list - this is the same as above as is the default
        graph = NestedTree()
        graph.addChildNode(NestedTreeNode(1), NestedTreeNode.INSERT_END)
        graph.addChildNode(NestedTreeNode(2), NestedTreeNode.INSERT_END)
        graph.addChildNode(NestedTreeNode(3), NestedTreeNode.INSERT_END)
        self.assertEqual(graph.walkTree(self.all_nodes_function), [1, 2, 3],
                         "Basic append insert")

        # test front insertion - empty list
        graph = NestedTree()
        graph.addChildNode(NestedTreeNode(3), NestedTreeNode.INSERT_FRONT)
        graph.addChildNode(NestedTreeNode(2), NestedTreeNode.INSERT_FRONT)
        graph.addChildNode(NestedTreeNode(1), NestedTreeNode.INSERT_FRONT)
        self.assertEqual(graph.walkTree(self.all_nodes_function), [1, 2, 3],
                         "Basic in front insert")

        # test ascending insertion - empty list
        graph = NestedTree()
        graph.addChildNode(NestedTreeNode(8), NestedTreeNode.INSERT_ASCENDING)
        graph.addChildNode(NestedTreeNode(2), NestedTreeNode.INSERT_ASCENDING)
        graph.addChildNode(NestedTreeNode(3), NestedTreeNode.INSERT_ASCENDING)
        graph.addChildNode(NestedTreeNode(7), NestedTreeNode.INSERT_ASCENDING)
        graph.addChildNode(NestedTreeNode(6), NestedTreeNode.INSERT_ASCENDING)
        graph.addChildNode(NestedTreeNode(5), NestedTreeNode.INSERT_ASCENDING)
        graph.addChildNode(NestedTreeNode(1), NestedTreeNode.INSERT_ASCENDING)
        graph.addChildNode(NestedTreeNode(4), NestedTreeNode.INSERT_ASCENDING)
        graph.addChildNode(NestedTreeNode(5), NestedTreeNode.INSERT_ASCENDING)
        self.assertEqual(graph.walkTree(self.all_nodes_function),
                         [1, 2, 3, 4, 5, 5, 6, 7, 8], "Basic in front insert")
Exemplo n.º 13
0
    def test_5NodeWalk(self):
        """ 5 Node Walk - with insert before.

			This test adds three nodes in a row to see if the graph code works
			it also inserts two more nodes before node 2 and node 3.

			It then will walk the tree to see if the it finds all the nodes.
		"""
        node1 = NestedTreeNode(1)
        node2 = NestedTreeNode(2)
        node3 = NestedTreeNode(3)
        node4 = NestedTreeNode(4)
        node5 = NestedTreeNode(5)

        graph = NestedTree()

        # insert the three nodes
        graph.addNodeAfter(node1)
        node1.addNodeAfter(node2)
        node2.addNodeAfter(node3)

        # now insert the two extra nodes
        node2.addNodeBefore(node4)
        node3.addNodeBefore(node5)

        # we are only using the next function for this rest.
        count = 0
        count = graph.walkTree(self.count_function)
        self.assertTrue(count == 5)
Exemplo n.º 14
0
    def test_addNodes(self):
        """ Add Nodes.

			This test adds three nodes in a row to see if the graph code works.
			This is an exploding test to see if the code works.
		"""
        node1 = NestedTreeNode(1)
        node2 = NestedTreeNode(2)
        node3 = NestedTreeNode(3)

        graph = NestedTree()

        graph.addNodeAfter(node1)
        node1.addNodeAfter(node2)
        node2.addNodeAfter(node3)

        self.assertTrue(graph.hasSibling())
        self.assertTrue(node1.hasSibling())
        self.assertTrue(node2.hasSibling())