# region PROBLEM
'''
<> LL: Print List
Implement a method print_list(self) on the LinkedList class that prints the linked list's elements, one per line.

Walk from the head to the tail, printing each node's value on its own line.

Example:
    my_linked_list = LinkedList(4)
    my_linked_list.print_list()

Expected output:
    4
'''

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None


class LinkedList:
    def __init__(self, value):
        new_node = Node(value)
        self.head = new_node
        self.tail = new_node
        self.length = 1

    def make_empty(self):
        self.head = None
        self.tail = None
        self.length = 0

    def append(self, value):
        new_node = Node(value)
        if self.head is None:
            self.head = new_node
            self.tail = new_node
        else:
            self.tail.next = new_node
            self.tail = new_node
        self.length += 1
# endregion


# region SOLUTION

def print_list(self):
    current_node = self.head
    while current_node is not None: 
        print(current_node.value)
        current_node = current_node.next
        
LinkedList.print_list = print_list

# endregion


# region TESTS

def test_print_list_single_node(capsys):
    ll = LinkedList(4)
    ll.print_list()
    assert capsys.readouterr().out == "4\n"


def test_print_list_multiple_nodes(capsys):
    ll = LinkedList(1)
    ll.head.next = Node(2)
    ll.tail = ll.head.next
    ll.tail.next = Node(3)
    ll.tail = ll.tail.next
    ll.print_list()
    assert capsys.readouterr().out == "1\n2\n3\n"


def test_print_list_does_not_mutate():
    ll = LinkedList(7)
    ll.print_list()
    assert ll.head.value == 7
    assert ll.tail is ll.head
    assert ll.length == 1


if __name__ == "__main__":
    import pytest

    raise SystemExit(pytest.main([__file__, "-v"]))

# endregion
