def test_add_right_raises_ValueError_with_nonempty_node(self):
        lt = LinkedBinaryTree()
        lt._root = lt._Node('foo', None, None, None)
        lt._root._right = lt._Node('bar', lt._root, None, None)
        lt._size = 2
        root_position = lt.Position(lt, lt._root)

        self.assertRaises(ValueError, lt._add_right, root_position, 'foo')
    def test_validate_raises_ValueError_with_deprecated_node(self):
        lt = LinkedBinaryTree()
        lt._root = lt._Node('foo')
        lt._root._left = lt._Node('bar', None, None, None)
        lt._root._left._parent = lt._root._left  # deprecate node
        lt._size = 2
        bad_position = lt.Position(lt, lt._root._left)

        self.assertRaises(ValueError, lt._validate, bad_position)
    def test_delete_raises_ValueError_when_called_on_Position_with_two_children(
            self):
        lt = LinkedBinaryTree()
        lt._root = lt._Node('foo', None, None, None)
        lt._root._left = lt._Node('bar', lt._root, None, None)
        lt._root._left._left = lt._Node('baz', lt._root._left, None, None)
        lt._root._left._right = lt._Node('spam', lt._root._left, None, None)
        lt._size = 4
        pos_to_delete = lt.Position(lt, lt._root._left)

        self.assertRaises(ValueError, lt._delete, pos_to_delete)
    def test_add_right_stores_element_as_right_child_returns_Position(self):
        lt = LinkedBinaryTree()
        lt._root = lt._Node('foo', None, None, None)
        lt._size = 1
        root_position = lt.Position(lt, lt._root)
        expected_element = 'bar'

        result_position = lt._add_right(root_position, expected_element)

        self.assertIsInstance(result_position, lt.Position)
        self.assertIs(result_position._node._element, expected_element)
        self.assertIs(root_position._node._right._element, expected_element)
    def test_replace_replaces_element_at_Position_returns_old_element(self):
        lt = LinkedBinaryTree()
        old_element = 'bar'
        new_element = 'baz'
        lt._root = lt._Node('foo', None, None, None)
        lt._root._left = lt._Node(old_element, lt._root, None, None)
        lt._size = 2
        pos_to_replace = lt.Position(lt, lt._root._left)

        result_element = lt._replace(pos_to_replace, new_element)

        self.assertIs(pos_to_replace._node._element, new_element)
        self.assertIs(result_element, old_element)
    def test_delete_deletes_node_on_Position_replaces_with_a_single_child(
            self):
        lt = LinkedBinaryTree()
        element_to_delete = 'bar'
        child_element = 'baz'
        lt._root = lt._Node('foo', None, None, None)
        lt._root._left = lt._Node(element_to_delete, lt._root, None, None)
        lt._root._left._left = lt._Node(child_element, lt._root._left, None,
                                        None)
        lt._size = 3
        pos_to_delete = lt.Position(lt, lt._root._left)

        deleted_element = lt._delete(pos_to_delete)

        self.assertIs(deleted_element, element_to_delete)
        self.assertIs(lt._root._left._element, child_element)
        self.assertIs(lt._root._left._parent, lt._root)
    def test_num_children_returns_number_of_children_nodes_of_position(self):
        lt = LinkedBinaryTree()
        lt._root = lt._Node('foo')
        lt._size = 1
        expected_result = 0
        root_position = lt.Position(lt, lt._root)

        result = lt.num_children(root_position)

        self.assertEqual(result, expected_result)

        lt._root._left = lt._Node('bar', lt._root, None, None)
        lt._root._right = lt._Node('baz', lt._root, None, None)
        lt._size = 3
        expected_result = 2

        result = lt.num_children(root_position)

        self.assertEqual(result, expected_result)
    def test_add_root_raises_ValueError_with_nonempty_tree(self):
        lt = LinkedBinaryTree()
        lt._root = lt._Node('foo', None, None, None)
        lt._size = 1

        self.assertRaises(ValueError, lt._add_root, 'foo')