def test_insert_last(self, values_to_add, all_values_from_head, all_values_from_tail):
        instance = MyDoubleLinkedList()
        for value in values_to_add:
            instance.insert_last(value)

        assert all_values_from_head == instance.all_values_from_head
        assert all_values_from_tail == instance.all_values_from_tail
 def test_first(self, values_to_add, expected_value, all_values_from_head, all_values_from_tail):
     instance = MyDoubleLinkedList()
     for value in values_to_add:
         instance.insert_first(value)
     actual_result = instance.first
     assert actual_result == expected_value
     assert all_values_from_head == instance.all_values_from_head
     assert all_values_from_tail == instance.all_values_from_tail
    def test_delete_last(self, values_to_add, expected_deleted_value, all_values_from_head, all_values_from_tail):
        instance = MyDoubleLinkedList()
        for value in values_to_add:
            instance.insert_first(value)

        deleted_value = instance.delete_last()
        assert deleted_value == expected_deleted_value
        assert all_values_from_head == instance.all_values_from_head
        assert all_values_from_tail == instance.all_values_from_tail
 def test_concatenate(
         self,
         list_a: MyDoubleLinkedList,
         list_b: MyDoubleLinkedList,
         expected_all_values_from_head,
         expected_all_values_from_tail,
         expected_size,
 ):
     updated_list = list_a.concatenate(list_b)
     actual_all_values_from_head = updated_list.all_values_from_head
     actual_all_values_from_tail = updated_list.all_values_from_tail
     actual_size = updated_list._size
     assert actual_all_values_from_head == expected_all_values_from_head
     assert actual_all_values_from_tail == expected_all_values_from_tail
     assert actual_size == expected_size
 def test_is_empty(self, new_size, expected_result):
     instance = MyDoubleLinkedList()
     instance._size = new_size
     actual_result = instance.is_empty()
     assert actual_result == expected_result
class TestMyDoubleLinkedList:
    @pytest.mark.parametrize(
        'new_size, expected_result',
        [
            (0, True),
            (1, False),
        ]
    )
    def test_is_empty(self, new_size, expected_result):
        instance = MyDoubleLinkedList()
        instance._size = new_size
        actual_result = instance.is_empty()
        assert actual_result == expected_result

    @pytest.mark.parametrize(
        'instance',
        [
            MyDoubleLinkedList()
        ]
    )
    def test_first__negative_scenario_empty_collection(
            self, instance,
    ):
        with pytest.raises(EmptyCollection):
            first_element = instance.first

    @pytest.mark.parametrize(
        'values_to_add, expected_value, all_values_from_head, all_values_from_tail',
        [
            (
                    [1],
                    1,
                    [1],
                    [1],
            ),
        ]
    )
    def test_first(self, values_to_add, expected_value, all_values_from_head, all_values_from_tail):
        instance = MyDoubleLinkedList()
        for value in values_to_add:
            instance.insert_first(value)
        actual_result = instance.first
        assert actual_result == expected_value
        assert all_values_from_head == instance.all_values_from_head
        assert all_values_from_tail == instance.all_values_from_tail

    @pytest.mark.parametrize(
        'instance',
        [
            MyDoubleLinkedList()
        ]
    )
    def test_last__negative_scenario_empty_collection(
            self, instance,
    ):
        with pytest.raises(EmptyCollection):
            first_element = instance.last

    @pytest.mark.parametrize(
        'values_to_add, expected_value, all_values_from_head, all_values_from_tail',
        [
            (
                    [1],
                    1,
                    [1],
                    [1],
            ),
        ]
    )
    def test_last(self, values_to_add, expected_value, all_values_from_head, all_values_from_tail):
        instance = MyDoubleLinkedList()
        for value in values_to_add:
            instance.insert_first(value)

        actual_result = instance.last
        assert actual_result == expected_value
        assert all_values_from_head == instance.all_values_from_head
        assert all_values_from_tail == instance.all_values_from_tail

    @pytest.mark.parametrize(
        'values_to_add, all_values_from_head, all_values_from_tail',
        [
            (
                    [1],
                    [1],
                    [1],
            ),
            (
                    [1, 2],
                    [2, 1],
                    [1, 2]
            ),
            (
                    [1, 2, 3],
                    [3, 2, 1],
                    [1, 2, 3],
            ),


            #

        ]
    )
    def test_insert_fist(self, values_to_add, all_values_from_head, all_values_from_tail):
        instance = MyDoubleLinkedList()
        for value in values_to_add:
            instance.insert_first(value)

        assert all_values_from_head == instance.all_values_from_head
        assert all_values_from_tail == instance.all_values_from_tail

    @pytest.mark.parametrize(
        'values_to_add, all_values_from_head, all_values_from_tail',
        [
            (
                    [1],
                    [1],
                    [1],
            ),
            (
                    [1, 2],
                    [1, 2],
                    [2, 1]
            ),
            (
                    [1, 2, 3],
                    [1, 2, 3],
                    [3, 2, 1],
            ),
        ]
    )
    def test_insert_last(self, values_to_add, all_values_from_head, all_values_from_tail):
        instance = MyDoubleLinkedList()
        for value in values_to_add:
            instance.insert_last(value)

        assert all_values_from_head == instance.all_values_from_head
        assert all_values_from_tail == instance.all_values_from_tail

    @pytest.mark.parametrize(
        'instance',
        [
            MyDoubleLinkedList()
        ]
    )
    def test_delete_first__negative_scenario_empty_collection(
            self, instance,
    ):
        with pytest.raises(EmptyCollection):
            first_element = instance.delete_fist()

    @pytest.mark.parametrize(
        'values_to_add, expected_deleted_value, all_values_from_head, all_values_from_tail',
        [
            (
                    [1],
                    1,
                    [],
                    [],
            ),
            (
                    [1, 2],
                    2,
                    [1],
                    [1]
            ),
            (
                    [1, 2, 3],
                    3,
                    [2, 1],
                    [1, 2
                     ],
            ),
        ]
    )
    def test_delete_first(self, values_to_add, expected_deleted_value, all_values_from_head, all_values_from_tail):
        instance = MyDoubleLinkedList()
        for value in values_to_add:
            instance.insert_first(value)

        deleted_value = instance.delete_fist()
        assert deleted_value == expected_deleted_value
        assert all_values_from_head == instance.all_values_from_head
        assert all_values_from_tail == instance.all_values_from_tail

    @pytest.mark.parametrize(
        'instance',
        [
            MyDoubleLinkedList()
        ]
    )
    def test_delete_last__negative_scenario_empty_collection(
            self, instance,
    ):
        with pytest.raises(EmptyCollection):
            first_element = instance.delete_last()

    @pytest.mark.parametrize(
        'values_to_add, expected_deleted_value, all_values_from_head, all_values_from_tail',
        [
            (
                    [1],
                    1,
                    [],
                    [],
            ),
            (
                    [1, 2],
                    1,
                    [2],
                    [2]
            ),
            (
                    [1, 2, 3],
                    1,
                    [3, 2],
                    [2, 3],
            ),
        ]
    )
    def test_delete_last(self, values_to_add, expected_deleted_value, all_values_from_head, all_values_from_tail):
        instance = MyDoubleLinkedList()
        for value in values_to_add:
            instance.insert_first(value)

        deleted_value = instance.delete_last()
        assert deleted_value == expected_deleted_value
        assert all_values_from_head == instance.all_values_from_head
        assert all_values_from_tail == instance.all_values_from_tail

    @pytest.mark.parametrize(
        'list_a, list_b, expected_all_values_from_head, expected_all_values_from_tail, expected_size',
        [
            (MyDoubleLinkedList.from_iterable(list()), None, list(), list(), 0),
            (MyDoubleLinkedList.from_iterable(list()), MyDoubleLinkedList.from_iterable(list()), list(), list(), 0),
            (MyDoubleLinkedList.from_iterable([1]), MyDoubleLinkedList.from_iterable(list()), [1], [1], 1),
            (MyDoubleLinkedList.from_iterable(list()), MyDoubleLinkedList.from_iterable([1]), [1], [1], 1),
            (MyDoubleLinkedList.from_iterable([2]), MyDoubleLinkedList.from_iterable([1]), [2, 1], [1, 2], 2),
        ]
    )
    def test_concatenate(
            self,
            list_a: MyDoubleLinkedList,
            list_b: MyDoubleLinkedList,
            expected_all_values_from_head,
            expected_all_values_from_tail,
            expected_size,
    ):
        updated_list = list_a.concatenate(list_b)
        actual_all_values_from_head = updated_list.all_values_from_head
        actual_all_values_from_tail = updated_list.all_values_from_tail
        actual_size = updated_list._size
        assert actual_all_values_from_head == expected_all_values_from_head
        assert actual_all_values_from_tail == expected_all_values_from_tail
        assert actual_size == expected_size