import unittest
from htmlnode import HTMLNode, LeafNode, ParentNode

class TestHTMLNode(unittest.TestCase):

    def test_initialization(self):
        node = HTMLNode(tag="div", value="Hello, World!", props={"class": "container"})
        self.assertEqual(node.tag, "div")
        self.assertEqual(node.value, "Hello, World!")
        self.assertEqual(node.children, [])
        self.assertEqual(node.props, {"class": "container"})

    def test_props_to_html(self):
        node = HTMLNode(tag="input", props={"type": "text", "placeholder": "Enter name"})
        props_html = node.props_to_html()
        self.assertEqual(props_html, 'type="text" placeholder="Enter name"')

    def test_repr(self):
        node = HTMLNode(tag="p", value="Sample text", props={"id": "text1"})
        expected_repr = "Tag: p, Val: Sample text, Children: [], Props: {'id': 'text1'}"
        self.assertEqual(repr(node), expected_repr)

class TestParentNode(unittest.TestCase):

    def test_initialization(self):
        node = ParentNode(tag="div", children=[])
        self.assertEqual(node.tag, "div")
        self.assertEqual(node.children, [])
        self.assertEqual(node.props, {})

    def test_to_html_with_one_child(self):
        child = LeafNode(value="Hello, World!", tag="p")
        node = ParentNode(tag="div", children=[child])
        self.assertEqual(node.to_html(), "<div><p>Hello, World!</p></div>")

    def test_to_html_with_multiple_children(self):
        child1 = LeafNode(value="First", tag="span")
        child2 = LeafNode(value="Second", tag="span")
        node = ParentNode(tag="div", children=[child1, child2])
        self.assertEqual(node.to_html(), "<div><span>First</span><span>Second</span></div>")

    def test_to_html_with_nested_parent(self):
        inner_child = LeafNode(value="Nested", tag="b")
        inner_parent = ParentNode(tag="p", children=[inner_child])
        outer_parent = ParentNode(tag="div", children=[inner_parent])

        expected_html = "<div><p><b>Nested</b></p></div>"
        self.assertEqual(outer_parent.to_html(), expected_html)

    def test_to_html_with_props(self):
        child = LeafNode(value="Text", tag="p")
        node = ParentNode(tag="section", children=[child], props={"class": "content"})
        self.assertEqual(node.to_html(), '<section class="content"><p>Text</p></section>')

    def test_to_html_with_empty_children_raises_error(self):
        with self.assertRaises(ValueError):
            ParentNode(tag="div", children=[]).to_html()

    def test_to_html_raises_error_without_tag(self):
        child = LeafNode(value="Test", tag="p")
        with self.assertRaises(ValueError):
            ParentNode(tag=None, children=[child]).to_html()

class TestLeafNode(unittest.TestCase):

    def test_initialization(self):
        node = LeafNode(value="Hello, World!", tag="p")
        self.assertEqual(node.tag, "p")
        self.assertEqual(node.value, "Hello, World!")
        self.assertEqual(node.children, [])
        self.assertEqual(node.props, {})

    def test_to_html_with_tag(self):
        node = LeafNode(value="Hello, World!", tag="p")
        self.assertEqual(node.to_html(), "<p>Hello, World!</p>")

    def test_to_html_without_tag(self):
        node = LeafNode(value="Just text")
        self.assertEqual(node.to_html(), "Just text")

    def test_to_html_with_props(self):
        node = LeafNode(value="Click me", tag="button")
        node.props = {"class": "btn", "id": "submit-btn"}
        self.assertEqual(node.to_html(), '<button class="btn" id="submit-btn">Click me</button>')

    def test_to_html_raises_value_error(self):
        with self.assertRaises(ValueError):
            LeafNode(value=None, tag="p").to_html()

if __name__ == "__main__":
    unittest.main()


