package compiler

import (
	"esperframework/compiler/appshell"
	"esperframework/compiler/parser"
	"testing"

	"github.com/matryer/is"
)

func TestInitList(t *testing.T) {
	tests := []struct {
		input  *parser.MarkupItem
		output appshell.SlotHTML
	}{
		// Base cases
		{
			input: &parser.MarkupItem{
				Typ: parser.MarkupItemType[parser.MUFragment],
				Children: []parser.MarkupItem{
					{
						Typ:         parser.MarkupItemType[parser.MUText],
						Data:        "\n\n\n\n",
						SelfClosing: true,
					},
				},
			},
			output: appshell.SlotHTML{
				Open: "\n",
			},
		},
		{
			input: &parser.MarkupItem{
				Typ: parser.MarkupItemType[parser.MUFragment],
				Children: []parser.MarkupItem{
					{
						Typ:         parser.MarkupItemType[parser.MUComment],
						Data:        "in comment",
						Start:       0,
						End:         19,
						Line:        1,
						SelfClosing: true,
					},
				},
			},
			output: appshell.SlotHTML{
				Open: "",
			},
		},
		{
			input: &parser.MarkupItem{
				Typ: parser.MarkupItemType[parser.MUFragment],
				Children: []parser.MarkupItem{
					{
						Typ:         parser.MarkupItemType[parser.MUComment],
						Data:        "multi\n\tline\n\tcomment",
						Start:       0,
						End:         30,
						Line:        1,
						SelfClosing: true,
					},
				},
			},
			output: appshell.SlotHTML{
				Open: "",
			},
		},
		{
			input: &parser.MarkupItem{
				Typ: parser.MarkupItemType[parser.MUFragment],
				Children: []parser.MarkupItem{
					{
						Typ:         parser.MarkupItemType[parser.MUElement],
						Name:        "h1",
						Start:       0,
						End:         20,
						Line:        1,
						SelfClosing: false,
						Children: []parser.MarkupItem{
							{
								Typ:         parser.MarkupItemType[parser.MUText],
								Data:        "One element",
								Start:       4,
								End:         15,
								Line:        1,
								SelfClosing: true,
							},
						},
					},
				},
			},
			output: appshell.SlotHTML{
				Open: "<h1>One element</h1>",
			},
		},
		{
			input: &parser.MarkupItem{
				Typ: parser.MarkupItemType[parser.MUFragment],
				Children: []parser.MarkupItem{
					{
						Typ:         parser.MarkupItemType[parser.MUComment],
						Data:        "Test comment",
						Start:       0,
						End:         21,
						Line:        1,
						SelfClosing: true,
					},
					{
						Typ:         parser.MarkupItemType[parser.MUText],
						Data:        "\n\n",
						Start:       21,
						End:         23,
						Line:        1,
						SelfClosing: true,
					},
					{
						Typ:         parser.MarkupItemType[parser.MUElement],
						Name:        "h1",
						Start:       23,
						End:         40,
						Line:        3,
						SelfClosing: false,
						Children: []parser.MarkupItem{
							{
								Typ:         parser.MarkupItemType[parser.MUText],
								Data:        "Welcome!",
								Start:       27,
								End:         35,
								Line:        3,
								SelfClosing: true,
							},
						},
					},
				},
			},
			output: appshell.SlotHTML{
				Open: "\n<h1>Welcome!</h1>",
			},
		},
		{
			input: &parser.MarkupItem{
				Typ: parser.MarkupItemType[parser.MUFragment],
				Children: []parser.MarkupItem{
					{
						Typ:         parser.MarkupItemType[parser.MUElement],
						Name:        "h1",
						Start:       0,
						End:         26,
						Line:        1,
						SelfClosing: false,
						Children: []parser.MarkupItem{
							{
								Typ:         parser.MarkupItemType[parser.MUText],
								Data:        "\n\t\t1 elm newlines\n",
								Start:       4,
								End:         21,
								Line:        1,
								SelfClosing: true,
							},
						},
					},
				},
			},
			output: appshell.SlotHTML{
				Open: "<h1>\n1 elm newlines\n</h1>",
			},
		},
		{
			input: &parser.MarkupItem{
				Typ: parser.MarkupItemType[parser.MUFragment],
				Children: []parser.MarkupItem{
					{
						Typ:         parser.MarkupItemType[parser.MUText],
						Data:        "\n",
						Start:       0,
						End:         1,
						Line:        1,
						SelfClosing: true,
					},
					{
						Typ:         parser.MarkupItemType[parser.MUElement],
						Name:        "h1",
						Start:       1,
						End:         24,
						Line:        2,
						SelfClosing: false,
						Children: []parser.MarkupItem{
							{
								Typ:         parser.MarkupItemType[parser.MUText],
								Data:        "padded element",
								Start:       5,
								End:         19,
								Line:        2,
								SelfClosing: true,
							},
						},
					},
				},
			},
			output: appshell.SlotHTML{
				Open: "\n<h1>padded element</h1>",
			},
		},
		{
			input: &parser.MarkupItem{
				Typ: parser.MarkupItemType[parser.MUFragment],
				Children: []parser.MarkupItem{
					{
						Typ:         parser.MarkupItemType[parser.MUElement],
						Name:        "p",
						Start:       0,
						End:         26,
						Line:        1,
						SelfClosing: false,
						Children: []parser.MarkupItem{
							{
								Typ:         parser.MarkupItemType[parser.MUElement],
								Name:        "span",
								Start:       3,
								End:         22,
								Line:        1,
								SelfClosing: false,
								Children: []parser.MarkupItem{
									{
										Typ:         parser.MarkupItemType[parser.MUText],
										Data:        "Nested",
										Start:       9,
										End:         15,
										Line:        1,
										SelfClosing: true,
									},
								},
							},
						},
					},
				},
			},
			output: appshell.SlotHTML{
				Open: "<p><span>Nested</span></p>",
			},
		},
		{
			input: &parser.MarkupItem{
				Typ: parser.MarkupItemType[parser.MUFragment],
				Children: []parser.MarkupItem{
					{
						Typ:         parser.MarkupItemType[parser.MUElement],
						Name:        "div",
						Start:       0,
						End:         37,
						Line:        1,
						SelfClosing: false,
						Children: []parser.MarkupItem{
							{
								Typ:         parser.MarkupItemType[parser.MUElement],
								Name:        "p",
								Start:       5,
								End:         31,
								Line:        1,
								SelfClosing: false,
								Children: []parser.MarkupItem{
									{
										Typ:         parser.MarkupItemType[parser.MUElement],
										Name:        "span",
										Start:       8,
										End:         27,
										Line:        1,
										SelfClosing: false,
										Children: []parser.MarkupItem{
											{
												Typ:         parser.MarkupItemType[parser.MUText],
												Data:        "Nested",
												Start:       14,
												End:         20,
												Line:        1,
												SelfClosing: true,
											},
										},
									},
								},
							},
						},
					},
				},
			},
			output: appshell.SlotHTML{
				Open: "<div><p><span>Nested</span></p></div>",
			},
		},
		{
			input: &parser.MarkupItem{
				Typ: parser.MarkupItemType[parser.MUFragment],
				Children: []parser.MarkupItem{
					{
						Typ:         parser.MarkupItemType[parser.MUElement],
						Name:        "h1",
						Start:       0,
						End:         14,
						Line:        1,
						SelfClosing: false,
						Children: []parser.MarkupItem{
							{
								Typ:         parser.MarkupItemType[parser.MUText],
								Data:        "Width",
								Start:       4,
								End:         9,
								Line:        1,
								SelfClosing: true,
							},
						},
					},
					{
						Typ:         parser.MarkupItemType[parser.MUElement],
						Name:        "p",
						Start:       14,
						End:         26,
						Line:        1,
						SelfClosing: false,
						Children: []parser.MarkupItem{
							{
								Typ:         parser.MarkupItemType[parser.MUText],
								Data:        "tests",
								Start:       17,
								End:         22,
								Line:        1,
								SelfClosing: true,
							},
						},
					},
				},
			},
			output: appshell.SlotHTML{
				Open: "<h1>Width</h1><p>tests</p>",
			},
		},
		{
			input: &parser.MarkupItem{
				Typ: parser.MarkupItemType[parser.MUFragment],
				Children: []parser.MarkupItem{
					{
						Typ:         parser.MarkupItemType[parser.MUElement],
						Name:        "div",
						Start:       0,
						End:         54,
						Line:        1,
						SelfClosing: false,
						Children: []parser.MarkupItem{
							{
								Typ:         parser.MarkupItemType[parser.MUElement],
								Name:        "p",
								Start:       5,
								End:         48,
								Line:        1,
								SelfClosing: false,
								Children: []parser.MarkupItem{
									{
										Typ:         parser.MarkupItemType[parser.MUElement],
										Name:        "span",
										Start:       8,
										End:         26,
										Line:        1,
										SelfClosing: false,
										Children: []parser.MarkupItem{
											{
												Typ:         parser.MarkupItemType[parser.MUText],
												Data:        "Depth",
												Start:       14,
												End:         19,
												Line:        1,
												SelfClosing: true,
											},
										},
									},
									{
										Typ:         parser.MarkupItemType[parser.MUElement],
										Name:        "a",
										Start:       26,
										End:         44,
										Line:        1,
										SelfClosing: false,
										Children: []parser.MarkupItem{
											{
												Typ:         parser.MarkupItemType[parser.MUText],
												Data:        "width",
												Start:       32,
												End:         37,
												Line:        1,
												SelfClosing: true,
											},
										},
									},
								},
							},
						},
					},
				},
			},
			output: appshell.SlotHTML{Open: "<div><p><span>Depth</span><a>width</a></p></div>"},
		},
		{
			input: &parser.MarkupItem{
				Typ: parser.MarkupItemType[parser.MUFragment],
				Children: []parser.MarkupItem{
					{
						Typ:         parser.MarkupItemType[parser.MUElement],
						Name:        "div",
						Start:       0,
						End:         54,
						Line:        1,
						SelfClosing: false,
						Children: []parser.MarkupItem{
							{
								Typ:         parser.MarkupItemType[parser.MUElement],
								Name:        "p",
								Start:       5,
								End:         30,
								Line:        1,
								SelfClosing: false,
								Children: []parser.MarkupItem{
									{
										Typ:         parser.MarkupItemType[parser.MUElement],
										Name:        "span",
										Start:       8,
										End:         26,
										Line:        1,
										SelfClosing: false,
										Children: []parser.MarkupItem{
											{
												Typ:         parser.MarkupItemType[parser.MUText],
												Data:        "Three",
												Start:       14,
												End:         19,
												Line:        1,
												SelfClosing: true,
												Children:    []parser.MarkupItem{},
											},
										},
									},
								},
							},
							{
								Typ:         parser.MarkupItemType[parser.MUElement],
								Name:        "p",
								Start:       30,
								End:         48,
								Line:        1,
								SelfClosing: false,
								Children: []parser.MarkupItem{
									{
										Typ:         parser.MarkupItemType[parser.MUElement],
										Name:        "a",
										Start:       33,
										End:         4,
										Line:        1,
										SelfClosing: false,
										Children: []parser.MarkupItem{
											{
												Typ:         parser.MarkupItemType[parser.MUText],
												Data:        "deep",
												Start:       36,
												End:         40,
												Line:        1,
												SelfClosing: true,
												Children:    []parser.MarkupItem{},
											},
										},
									},
								},
							},
						},
					},
				},
			},
			output: appshell.SlotHTML{
				Open: "<div><p><span>Three</span></p><p><a>deep</a></p></div>",
			},
		},
		{
			input: &parser.MarkupItem{
				Typ: parser.MarkupItemType[parser.MUFragment],
				Children: []parser.MarkupItem{
					{
						Typ:         parser.MarkupItemType[parser.MUElement],
						Name:        "div",
						Start:       0,
						End:         54,
						Line:        1,
						SelfClosing: false,
						Children: []parser.MarkupItem{
							{
								Typ:         parser.MarkupItemType[parser.MUElement],
								Name:        "p",
								Start:       5,
								End:         55,
								Line:        1,
								SelfClosing: false,
								Children: []parser.MarkupItem{
									{
										Typ:         parser.MarkupItemType[parser.MUElement],
										Name:        "span",
										Start:       8,
										End:         29,
										Line:        1,
										SelfClosing: false,
										Children: []parser.MarkupItem{
											{
												Typ:         parser.MarkupItemType[parser.MUText],
												Data:        "Adjacent",
												Start:       14,
												End:         22,
												Line:        1,
												SelfClosing: true,
												Children:    []parser.MarkupItem{},
											},
										},
									},
									{
										Typ:         parser.MarkupItemType[parser.MUElement],
										Name:        "strong",
										Start:       29,
										End:         52,
										Line:        1,
										SelfClosing: false,
										Children: []parser.MarkupItem{
											{
												Typ:         parser.MarkupItemType[parser.MUText],
												Data:        "double",
												Start:       37,
												End:         43,
												Line:        1,
												SelfClosing: true,
												Children:    []parser.MarkupItem{},
											},
										},
									},
								},
							},
							{
								Typ:         parser.MarkupItemType[parser.MUElement],
								Name:        "p",
								Start:       56,
								End:         87,
								Line:        1,
								SelfClosing: false,
								Children: []parser.MarkupItem{
									{
										Typ:         parser.MarkupItemType[parser.MUElement],
										Name:        "a",
										Start:       59,
										End:         72,
										Line:        1,
										SelfClosing: false,
										Children: []parser.MarkupItem{
											{
												Typ:         parser.MarkupItemType[parser.MUText],
												Data:        "nested",
												Start:       62,
												End:         68,
												Line:        1,
												SelfClosing: true,
												Children:    []parser.MarkupItem{},
											},
										},
									},
									{
										Typ:         parser.MarkupItemType[parser.MUElement],
										Name:        "b",
										Start:       72,
										End:         83,
										Line:        1,
										SelfClosing: false,
										Children: []parser.MarkupItem{
											{
												Typ:         parser.MarkupItemType[parser.MUText],
												Data:        "test",
												Start:       75,
												End:         79,
												Line:        1,
												SelfClosing: true,
												Children:    []parser.MarkupItem{},
											},
										},
									},
								},
							},
						},
					},
				},
			},
			output: appshell.SlotHTML{
				Open: "<div><p><span>Adjacent</span><strong>double</strong></p><p><a>nested</a><b>test</b></p></div>",
			},
		},
		{
			input: &parser.MarkupItem{
				Typ: parser.MarkupItemType[parser.MUFragment],
				Children: []parser.MarkupItem{
					{
						Typ:         parser.MarkupItemType[parser.MUElement],
						Name:        "div",
						Start:       0,
						End:         128,
						Line:        1,
						SelfClosing: false,
						Children: []parser.MarkupItem{
							{
								Typ:         parser.MarkupItemType[parser.MUElement],
								Name:        "p",
								Start:       5,
								End:         63,
								Line:        1,
								SelfClosing: false,
								Children: []parser.MarkupItem{
									{
										Typ:         parser.MarkupItemType[parser.MUElement],
										Name:        "span",
										Start:       8,
										End:         26,
										Line:        1,
										SelfClosing: false,
										Children: []parser.MarkupItem{
											{
												Typ:         parser.MarkupItemType[parser.MUText],
												Data:        "Final",
												Start:       14,
												End:         19,
												Line:        1,
												SelfClosing: true,
											},
										},
									},
									{
										Typ:         parser.MarkupItemType[parser.MUElement],
										Name:        "span",
										Start:       26,
										End:         43,
										Line:        1,
										SelfClosing: false,
										Children: []parser.MarkupItem{
											{
												Typ:         parser.MarkupItemType[parser.MUText],
												Data:        "test",
												Start:       32,
												End:         36,
												Line:        1,
												SelfClosing: true,
											},
										},
									},
									{
										Typ:         parser.MarkupItemType[parser.MUElement],
										Name:        "span",
										Start:       43,
										End:         59,
										Line:        1,
										SelfClosing: false,
										Children: []parser.MarkupItem{
											{
												Typ:         parser.MarkupItemType[parser.MUText],
												Data:        "for",
												Start:       49,
												End:         52,
												Line:        1,
												SelfClosing: true,
											},
										},
									},
								},
							},
							{
								Typ:         parser.MarkupItemType[parser.MUElement],
								Name:        "p",
								Start:       63,
								End:         122,
								Line:        1,
								SelfClosing: false,
								Children: []parser.MarkupItem{
									{
										Typ:         parser.MarkupItemType[parser.MUElement],
										Name:        "span",
										Start:       66,
										End:         82,
										Line:        1,
										SelfClosing: false,
										Children: []parser.MarkupItem{
											{
												Typ:         parser.MarkupItemType[parser.MUText],
												Data:        "all",
												Start:       72,
												End:         75,
												Line:        1,
												SelfClosing: true,
											},
										},
									},
									{
										Typ:         parser.MarkupItemType[parser.MUElement],
										Name:        "span",
										Start:       82,
										End:         100,
										Line:        1,
										SelfClosing: false,
										Children: []parser.MarkupItem{
											{
												Typ:         parser.MarkupItemType[parser.MUText],
												Data:        "known",
												Start:       88,
												End:         93,
												Line:        1,
												SelfClosing: true,
											},
										},
									},
									{
										Typ:         parser.MarkupItemType[parser.MUElement],
										Name:        "span",
										Start:       100,
										End:         118,
										Line:        1,
										SelfClosing: false,
										Children: []parser.MarkupItem{
											{
												Typ:         parser.MarkupItemType[parser.MUText],
												Data:        "cases",
												Start:       106,
												End:         111,
												Line:        1,
												SelfClosing: true,
											},
										},
									},
								},
							},
						},
					},
				},
			},
			output: appshell.SlotHTML{
				Open: "<div><p><span>Final</span><span>test</span><span>for</span></p><p><span>all</span><span>known</span><span>cases</span></p></div>",
			},
		},
		{
			input: &parser.MarkupItem{
				Typ: parser.MarkupItemType[parser.MUFragment],
				Children: []parser.MarkupItem{
					{
						Typ:         parser.MarkupItemType[parser.MUElement],
						Name:        "div",
						Start:       0,
						End:         65,
						Line:        1,
						SelfClosing: false,
						Children: []parser.MarkupItem{
							{
								Typ:         parser.MarkupItemType[parser.MUElement],
								Name:        "p",
								Start:       5,
								End:         33,
								Line:        1,
								SelfClosing: false,
								Children: []parser.MarkupItem{
									{
										Typ:         parser.MarkupItemType[parser.MUText],
										Data:        "Text",
										Start:       8,
										End:         12,
										Line:        1,
										SelfClosing: false,
										Children:    []parser.MarkupItem{},
									},
									{
										Typ:         parser.MarkupItemType[parser.MUElement],
										Name:        "span",
										Start:       12,
										End:         29,
										Line:        1,
										SelfClosing: false,
										Children: []parser.MarkupItem{
											{
												Typ:         parser.MarkupItemType[parser.MUText],
												Data:        "with",
												Start:       8,
												End:         12,
												Line:        1,
												SelfClosing: true,
												Children:    []parser.MarkupItem{},
											},
										},
									},
								},
							},
							{
								Typ:         parser.MarkupItemType[parser.MUElement],
								Name:        "p",
								Start:       33,
								End:         59,
								Line:        1,
								SelfClosing: false,
								Children: []parser.MarkupItem{
									{
										Typ:         parser.MarkupItemType[parser.MUElement],
										Name:        "a",
										Start:       36,
										End:         51,
										Line:        1,
										SelfClosing: false,
										Children: []parser.MarkupItem{
											{
												Typ:         parser.MarkupItemType[parser.MUText],
												Data:        "adjacent",
												Start:       39,
												End:         47,
												Line:        1,
												SelfClosing: true,
												Children:    []parser.MarkupItem{},
											},
										},
									},
									{
										Typ:         parser.MarkupItemType[parser.MUText],
										Data:        "test",
										Start:       51,
										End:         55,
										Line:        1,
										SelfClosing: true,
										Children:    []parser.MarkupItem{},
									},
								},
							},
						},
					},
				},
			},
			output: appshell.SlotHTML{
				Open: "<div><p>Text<span>with</span></p><p><a>adjacent</a>test</p></div>",
			},
		},
		{
			input: &parser.MarkupItem{
				Typ: parser.MarkupItemType[parser.MUFragment],
				Children: []parser.MarkupItem{
					{
						Typ:         parser.MarkupItemType[parser.MUElement],
						Name:        "div",
						Start:       0,
						End:         91,
						Line:        1,
						SelfClosing: false,
						Children: []parser.MarkupItem{
							{
								Typ:         parser.MarkupItemType[parser.MUElement],
								Name:        "p",
								Start:       5,
								End:         43,
								Line:        1,
								SelfClosing: false,
								Children: []parser.MarkupItem{
									{
										Typ:         parser.MarkupItemType[parser.MUElement],
										Name:        "span",
										Start:       8,
										End:         26,
										Line:        1,
										SelfClosing: false,
										Children: []parser.MarkupItem{
											{
												Typ:         parser.MarkupItemType[parser.MUText],
												Data:        "Nodes",
												Start:       14,
												End:         19,
												Line:        1,
												SelfClosing: true,
												Children:    []parser.MarkupItem{},
											},
										},
									},
									{
										Typ:         parser.MarkupItemType[parser.MUText],
										Data:        "of",
										Start:       26,
										End:         28,
										Line:        1,
										SelfClosing: true,
										Children:    []parser.MarkupItem{},
									},
									{
										Typ:         parser.MarkupItemType[parser.MUElement],
										Name:        "a",
										Start:       26,
										End:         28,
										Line:        1,
										SelfClosing: false,
										Children: []parser.MarkupItem{
											{
												Typ:         parser.MarkupItemType[parser.MUText],
												Data:        "text",
												Start:       31,
												End:         35,
												Line:        1,
												SelfClosing: true,
												Children:    []parser.MarkupItem{},
											},
										},
									},
								},
							},
							{
								Typ:         parser.MarkupItemType[parser.MUElement],
								Name:        "p",
								Start:       43,
								End:         85,
								Line:        1,
								SelfClosing: false,
								Children: []parser.MarkupItem{
									{
										Typ:         parser.MarkupItemType[parser.MUElement],
										Name:        "strong",
										Start:       46,
										End:         65,
										Line:        1,
										SelfClosing: false,
										Children: []parser.MarkupItem{
											{
												Typ:         parser.MarkupItemType[parser.MUText],
												Data:        "in",
												Start:       54,
												End:         56,
												Line:        1,
												SelfClosing: true,
												Children:    []parser.MarkupItem{},
											},
										},
									},
									{
										Typ:         parser.MarkupItemType[parser.MUText],
										Data:        "adjacent",
										Start:       65,
										End:         73,
										Line:        1,
										SelfClosing: true,
										Children:    []parser.MarkupItem{},
									},
									{
										Typ:         parser.MarkupItemType[parser.MUElement],
										Name:        "em",
										Start:       73,
										End:         87,
										Line:        1,
										SelfClosing: false,
										Children: []parser.MarkupItem{
											{
												Typ:         parser.MarkupItemType[parser.MUText],
												Data:        "nodes",
												Start:       77,
												End:         82,
												Line:        1,
												SelfClosing: true,
												Children:    []parser.MarkupItem{},
											},
										},
									},
								},
							},
						},
					},
				},
			},
			output: appshell.SlotHTML{
				Open: "<div><p><span>Nodes</span>of<a>text</a></p><p><strong>in</strong>adjacent<em>nodes</em></p></div>",
			},
		},
		{
			input: &parser.MarkupItem{
				Typ: parser.MarkupItemType[parser.MUFragment],
				Children: []parser.MarkupItem{
					{
						Typ:         parser.MarkupItemType[parser.MUElement],
						Name:        "div",
						Start:       0,
						End:         95,
						Line:        1,
						SelfClosing: false,
						Children: []parser.MarkupItem{
							{
								Typ:         parser.MarkupItemType[parser.MUElement],
								Name:        "p",
								Start:       5,
								End:         48,
								Line:        1,
								SelfClosing: false,
								Children: []parser.MarkupItem{
									{
										Typ:         parser.MarkupItemType[parser.MUText],
										Data:        "Text Nodes",
										Start:       8,
										End:         18,
										Line:        1,
										SelfClosing: true,
										Children:    []parser.MarkupItem{},
									},
									{
										Typ:         parser.MarkupItemType[parser.MUElement],
										Name:        "span",
										Start:       18,
										End:         37,
										Line:        1,
										SelfClosing: false,
										Children: []parser.MarkupItem{
											{
												Typ:         parser.MarkupItemType[parser.MUText],
												Data:        "around",
												Start:       24,
												End:         30,
												Line:        1,
												SelfClosing: true,
												Children:    []parser.MarkupItem{},
											},
										},
									},
									{
										Typ:         parser.MarkupItemType[parser.MUText],
										Data:        "element",
										Start:       37,
										End:         44,
										Line:        1,
										SelfClosing: true,
										Children:    []parser.MarkupItem{},
									},
								},
							},
							{
								Typ:         parser.MarkupItemType[parser.MUElement],
								Name:        "p",
								Start:       48,
								End:         89,
								Line:        1,
								SelfClosing: false,
								Children: []parser.MarkupItem{
									{
										Typ:         parser.MarkupItemType[parser.MUText],
										Data:        "nodes",
										Start:       51,
										End:         56,
										Line:        1,
										SelfClosing: true,
										Children:    []parser.MarkupItem{},
									},
									{
										Typ:         parser.MarkupItemType[parser.MUElement],
										Name:        "a",
										Start:       56,
										End:         69,
										Line:        1,
										SelfClosing: false,
										Children: []parser.MarkupItem{
											{
												Typ:         parser.MarkupItemType[parser.MUText],
												Data:        "nested",
												Start:       59,
												End:         65,
												Line:        1,
												SelfClosing: true,
												Children:    []parser.MarkupItem{},
											},
										},
									},
									{
										Typ:         parser.MarkupItemType[parser.MUText],
										Data:        "in element nodes",
										Start:       69,
										End:         85,
										Line:        1,
										SelfClosing: true,
										Children:    []parser.MarkupItem{},
									},
								},
							},
						},
					},
				},
			},
			output: appshell.SlotHTML{
				Open: "<div><p>Text Nodes<span>around</span>element</p><p>nodes<a>nested</a>in element nodes</p></div>",
			},
		},

		// Failing code
		{
			input: &parser.MarkupItem{
				Typ: parser.MarkupItemType[parser.MUFragment],
				Children: []parser.MarkupItem{
					{
						Typ:         parser.MarkupItemType[parser.MUText],
						Data:        "\n",
						Start:       0,
						End:         1,
						Line:        1,
						SelfClosing: true,
					},
					{
						Typ:         parser.MarkupItemType[parser.MUElement],
						Name:        "a",
						Start:       1,
						End:         39,
						Line:        2,
						SelfClosing: false,
						Attributes: []parser.MarkupItem{
							{
								Typ:         parser.MarkupItemType[parser.MUAttribute],
								Name:        "href",
								Start:       4,
								End:         19,
								Line:        2,
								SelfClosing: false,
								Value: []parser.MarkupItem{
									{
										Typ:   parser.MarkupItemType[parser.MUText],
										Data:  "#content",
										Start: 10,
										End:   18,
										Line:  2,
									},
								},
							},
						},
						Children: []parser.MarkupItem{
							{
								Typ:   parser.MarkupItemType[parser.MUText],
								Data:  "Skip to content",
								Start: 20,
								End:   35,
								Line:  2,
							},
						},
					},
					{
						Typ:         parser.MarkupItemType[parser.MUText],
						Data:        "\n\n",
						Start:       39,
						End:         41,
						Line:        2,
						SelfClosing: true,
					},
					{
						Typ:         parser.MarkupItemType[parser.MUSlot],
						Name:        "slot",
						Start:       41,
						End:         63,
						Line:        4,
						SelfClosing: false,
						Attributes: []parser.MarkupItem{
							{
								Typ:         parser.MarkupItemType[parser.MUAttribute],
								Name:        "type",
								Start:       47,
								End:         60,
								Line:        4,
								SelfClosing: false,
								Value: []parser.MarkupItem{
									{
										Typ:         parser.MarkupItemType[parser.MUText],
										Data:        "static",
										Start:       53,
										End:         59,
										Line:        4,
										SelfClosing: true,
									},
								},
							},
						},
					},
				},
			},
			output: appshell.SlotHTML{
				Open: "\n<a href=\"#content\">Skip to content</a>\n",
			},
		},
		{
			input: &parser.MarkupItem{
				Typ: parser.MarkupItemType[parser.MUFragment],
				Children: []parser.MarkupItem{
					{
						Typ:         parser.MarkupItemType[parser.MUComment],
						Data:        "Test Comment",
						Start:       0,
						End:         21,
						Line:        1,
						SelfClosing: true,
					},
					{
						Typ:         parser.MarkupItemType[parser.MUText],
						Data:        "\n\n\n\n\n\n\n\n\n",
						Start:       21,
						End:         30,
						Line:        1,
						SelfClosing: true,
					},
					{
						Typ:         parser.MarkupItemType[parser.MUInlineComponent],
						Name:        "HeaderComp",
						Start:       30,
						End:         44,
						Line:        10,
						SelfClosing: true,
					},
					{
						Typ:         parser.MarkupItemType[parser.MUText],
						Data:        "\n\n",
						Start:       44,
						End:         46,
						Line:        10,
						SelfClosing: true,
					},
					{
						Typ:         parser.MarkupItemType[parser.MUElement],
						Name:        "h1",
						Start:       46,
						End:         63,
						Line:        12,
						SelfClosing: false,
						Children: []parser.MarkupItem{
							{
								Typ:         parser.MarkupItemType[parser.MUText],
								Data:        "Welcome!",
								Start:       50,
								End:         58,
								Line:        12,
								SelfClosing: true,
							},
						},
					},
					{
						Typ:         parser.MarkupItemType[parser.MUText],
						Data:        "\n\n",
						Start:       63,
						End:         65,
						Line:        12,
						SelfClosing: true,
					},
					{
						Typ:         parser.MarkupItemType[parser.MUInlineComponent],
						Name:        "Links",
						Start:       65,
						End:         80,
						Line:        14,
						SelfClosing: false,
					},
					{
						Typ:         parser.MarkupItemType[parser.MUText],
						Data:        "\n\n",
						Start:       80,
						End:         82,
						Line:        14,
						SelfClosing: true,
					},
					{
						Typ:         parser.MarkupItemType[parser.MUElement],
						Name:        "main",
						Start:       82,
						End:         120,
						Line:        16,
						SelfClosing: false,
						Children: []parser.MarkupItem{
							{
								Typ:         parser.MarkupItemType[parser.MUText],
								Data:        "\n\t",
								Start:       88,
								End:         90,
								Line:        16,
								SelfClosing: true,
							},
							{
								Typ:         parser.MarkupItemType[parser.MUSlot],
								Name:        "slot",
								Start:       90,
								End:         112,
								Line:        17,
								SelfClosing: true,
								Attributes: []parser.MarkupItem{
									{
										Typ:   parser.MarkupItemType[parser.MUAttribute],
										Name:  "type",
										Start: 96,
										End:   109,
										Line:  17,
										Value: []parser.MarkupItem{
											{
												Typ:   parser.MarkupItemType[parser.MUText],
												Data:  "static",
												Start: 102,
												End:   108,
												Line:  17,
											},
										},
									},
								},
							},
							{
								Typ:         parser.MarkupItemType[parser.MUText],
								Data:        "\n",
								Start:       112,
								End:         113,
								Line:        17,
								SelfClosing: true,
							},
						},
					},
					{
						Typ:         parser.MarkupItemType[parser.MUText],
						Data:        "\n\n",
						Start:       120,
						End:         122,
						Line:        18,
						SelfClosing: true,
					},
					{
						Typ:         parser.MarkupItemType[parser.MUInlineComponent],
						Name:        "FooterComp",
						Start:       122,
						End:         136,
						Line:        20,
						SelfClosing: true,
					},
				},
			},
			output: appshell.SlotHTML{
				Open:  "\n${HeaderComp}\n<h1>Welcome!</h1>\n${Links}\n<main>\n",
				Close: "\n</main>\n${FooterComp}",
			},
		},
		{
			input: &parser.MarkupItem{
				Typ: parser.MarkupItemType[parser.MUFragment],
				Children: []parser.MarkupItem{
					{
						Typ:         parser.MarkupItemType[parser.MUElement],
						Name:        "footer",
						Start:       0,
						End:         41,
						Line:        1,
						SelfClosing: false,
						Children: []parser.MarkupItem{
							{
								Typ:         parser.MarkupItemType[parser.MUText],
								Data:        "\n\t",
								Start:       8,
								End:         10,
								Line:        1,
								SelfClosing: true,
							},
							{
								Typ:         parser.MarkupItemType[parser.MUInlineComponent],
								Name:        "Links",
								Start:       10,
								End:         19,
								Line:        2,
								SelfClosing: true,
							},
							{
								Typ:         parser.MarkupItemType[parser.MUText],
								Data:        "\n\t",
								Start:       19,
								End:         21,
								Line:        2,
								SelfClosing: true,
							},
							{
								Typ:         parser.MarkupItemType[parser.MUInlineComponent],
								Name:        "Socket",
								Start:       21,
								End:         31,
								Line:        3,
								SelfClosing: true,
							},
							{
								Typ:         parser.MarkupItemType[parser.MUText],
								Data:        "\n",
								Start:       31,
								End:         32,
								Line:        3,
								SelfClosing: true,
							},
						},
					},
				},
			},
			output: appshell.SlotHTML{
				Open:  "<footer>\n${Links}\n${Socket}\n</footer>",
				Close: "",
			},
		},
		{
			input: &parser.MarkupItem{
				Typ: parser.MarkupItemType[parser.MUFragment],
				Children: []parser.MarkupItem{
					{
						Typ:         parser.MarkupItemType[parser.MUElement],
						Name:        "h1",
						Start:       0,
						End:         65,
						Line:        1,
						SelfClosing: false,
						Children: []parser.MarkupItem{
							{
								Typ:         parser.MarkupItemType[parser.MUText],
								Data:        "\n\t",
								Start:       4,
								End:         6,
								Line:        1,
								SelfClosing: true,
							},
							{
								Typ:         parser.MarkupItemType[parser.MUElement],
								Name:        "span",
								Start:       6,
								End:         22,
								Line:        2,
								SelfClosing: false,
								Children: []parser.MarkupItem{
									{
										Typ:         parser.MarkupItemType[parser.MUText],
										Data:        "404",
										Start:       12,
										End:         15,
										Line:        2,
										SelfClosing: true,
									},
								},
							},
							{
								Typ:         parser.MarkupItemType[parser.MUText],
								Data:        "\n\t",
								Start:       22,
								End:         24,
								Line:        2,
								SelfClosing: true,
							},
							{
								Typ:         parser.MarkupItemType[parser.MUElement],
								Name:        "div",
								Start:       24,
								End:         35,
								Line:        3,
								SelfClosing: false,
							},
							{
								Typ:         parser.MarkupItemType[parser.MUText],
								Data:        "\n\t",
								Start:       35,
								End:         37,
								Line:        3,
								SelfClosing: true,
							},
							{
								Typ:         parser.MarkupItemType[parser.MUElement],
								Name:        "span",
								Start:       37,
								End:         59,
								Line:        4,
								SelfClosing: false,
								Children: []parser.MarkupItem{
									{
										Typ:         parser.MarkupItemType[parser.MUText],
										Data:        "not found",
										Start:       43,
										End:         52,
										Line:        2,
										SelfClosing: true,
									},
								},
							},
							{
								Typ:         parser.MarkupItemType[parser.MUText],
								Data:        "\n",
								Start:       35,
								End:         37,
								Line:        5,
								SelfClosing: true,
							},
						},
					},
				},
			},
			output: appshell.SlotHTML{
				Open:  "<h1>\n<span>404</span>\n<div></div>\n<span>not found</span>\n</h1>",
				Close: "",
			},
		},
	}

	is := is.New(t)

	for _, tt := range tests {
		ml := MarkupList{}

		ml.init(tt.input)

		// cl, _ := diff.Diff(tt.output, ml.printList())
		// fmt.Printf("\n%+v\n\n", cl)

		// fmt.Printf("\n\n\nEXP: %+v\n\nRES: %+v\n\n\n\n", tt.output, ml.printList())

		is.Equal(tt.output, ml.printList())
	}
}
