package parser

import (
	"bytes"
	"esperframework/options"
	"path/filepath"
	"testing"

	"github.com/matryer/is"
)

type parseInput struct {
	lexer *TBLexer
}

func TestParser(t *testing.T) {
	tests := []struct {
		input  *TBLexer
		output OutputMarkupTree
	}{
		{
			input: &TBLexer{
				options: &options.Options{
					CachePath: filepath.Join("../../../", "bin", "delete"),
				},
				templateDataBuf: TemplateDataBuffer{
					markupBlock: *bytes.NewBuffer([]byte("Any string")),
				},
			},
			output: OutputMarkupTree{
				HTML: MarkupItem{
					Typ: MarkupItemType[MUFragment],
					Children: []MarkupItem{
						{
							Typ:         MarkupItemType[MUText],
							Data:        "Any string",
							Start:       0,
							End:         10,
							Line:        1,
							SelfClosing: true,
						},
					},
				},
			},
		},
		{
			input: &TBLexer{
				options: &options.Options{
					CachePath: filepath.Join("../../../", "bin", "delete"),
				},
				templateDataBuf: TemplateDataBuffer{
					markupBlock: *bytes.NewBuffer([]byte("<!-- in comment -->")),
				},
			},
			output: OutputMarkupTree{
				HTML: MarkupItem{
					Typ: MarkupItemType[MUFragment],
					Children: []MarkupItem{
						{
							Typ:         MarkupItemType[MUComment],
							Data:        "in comment",
							Start:       0,
							End:         19,
							Line:        1,
							SelfClosing: true,
						},
					},
				},
			},
		},
		{
			input: &TBLexer{
				options: &options.Options{
					CachePath: filepath.Join("../../../", "bin", "delete"),
				},
				templateDataBuf: TemplateDataBuffer{
					markupBlock: *bytes.NewBuffer([]byte("<!-- comment one -->\n<!-- comment two -->")),
				},
			},
			output: OutputMarkupTree{
				HTML: MarkupItem{
					Typ: MarkupItemType[MUFragment],
					Children: []MarkupItem{
						{
							Typ:         MarkupItemType[MUComment],
							Data:        "comment one",
							Start:       0,
							End:         20,
							Line:        1,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUText],
							Data:        "\n",
							Start:       20,
							End:         21,
							Line:        1,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUComment],
							Data:        "comment two",
							Start:       21,
							End:         41,
							Line:        2,
							SelfClosing: true,
						},
					},
				},
			},
		},
		{
			input: &TBLexer{
				options: &options.Options{
					CachePath: filepath.Join("../../../", "bin", "delete"),
				},
				templateDataBuf: TemplateDataBuffer{
					markupBlock: *bytes.NewBuffer([]byte("<!--\n\tmulti\n\tline\n\tcomment\n-->")),
				},
			},
			output: OutputMarkupTree{
				HTML: MarkupItem{
					Typ: MarkupItemType[MUFragment],
					Children: []MarkupItem{
						{
							Typ:         MarkupItemType[MUComment],
							Data:        "multi\n\tline\n\tcomment",
							Start:       0,
							End:         30,
							Line:        1,
							SelfClosing: true,
						},
					},
				},
			},
		},
		{
			input: &TBLexer{
				options: &options.Options{
					CachePath: filepath.Join("../../../", "bin", "delete"),
				},
				templateDataBuf: TemplateDataBuffer{
					markupBlock: *bytes.NewBuffer([]byte("<h1>One element</h1>")),
				},
			},
			output: OutputMarkupTree{
				HTML: MarkupItem{
					Typ: MarkupItemType[MUFragment],
					Children: []MarkupItem{
						{
							Typ:         MarkupItemType[MUElement],
							Name:        "h1",
							Start:       0,
							End:         20,
							Line:        1,
							SelfClosing: false,
							Children: []MarkupItem{
								{
									Typ:         MarkupItemType[MUText],
									Data:        "One element",
									Start:       4,
									End:         15,
									Line:        1,
									SelfClosing: true,
								},
							},
						},
					},
				},
			},
		},
		{
			input: &TBLexer{
				options: &options.Options{
					CachePath: filepath.Join("../../../", "bin", "delete"),
				},
				templateDataBuf: TemplateDataBuffer{
					markupBlock: *bytes.NewBuffer([]byte("<!-- Test comment -->\n\n<h1>Welcome!</h1>")),
				},
			},
			output: OutputMarkupTree{
				HTML: MarkupItem{
					Typ: MarkupItemType[MUFragment],
					Children: []MarkupItem{
						{
							Typ:         MarkupItemType[MUComment],
							Data:        "Test comment",
							Start:       0,
							End:         21,
							Line:        1,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUText],
							Data:        "\n\n",
							Start:       21,
							End:         23,
							Line:        1,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUElement],
							Name:        "h1",
							Start:       23,
							End:         40,
							Line:        3,
							SelfClosing: false,
							Children: []MarkupItem{
								{
									Typ:         MarkupItemType[MUText],
									Data:        "Welcome!",
									Start:       27,
									End:         35,
									Line:        3,
									SelfClosing: true,
								},
							},
						},
					},
				},
			},
		},
		{
			input: &TBLexer{
				options: &options.Options{
					CachePath: filepath.Join("../../../", "bin", "delete"),
				},
				templateDataBuf: TemplateDataBuffer{
					markupBlock: *bytes.NewBuffer([]byte("<h1>\n\t1 elm newlines\n</h1>\n")),
				},
			},
			output: OutputMarkupTree{
				HTML: MarkupItem{
					Typ: MarkupItemType[MUFragment],
					Children: []MarkupItem{
						{
							Typ:         MarkupItemType[MUElement],
							Name:        "h1",
							Start:       0,
							End:         26,
							Line:        1,
							SelfClosing: false,
							Children: []MarkupItem{
								{
									Typ:         MarkupItemType[MUText],
									Data:        "\n\t1 elm newlines\n",
									Start:       4,
									End:         21,
									Line:        1,
									SelfClosing: true,
								},
							},
						},
					},
				},
			},
		},
		{
			input: &TBLexer{
				options: &options.Options{
					CachePath: filepath.Join("../../../", "bin", "delete"),
				},
				templateDataBuf: TemplateDataBuffer{
					markupBlock: *bytes.NewBuffer([]byte("\n<h1>padded element</h1>\n")),
				},
			},
			output: OutputMarkupTree{
				HTML: MarkupItem{
					Typ: MarkupItemType[MUFragment],
					Children: []MarkupItem{
						{
							Typ:         MarkupItemType[MUText],
							Data:        "\n",
							Start:       0,
							End:         1,
							Line:        1,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUElement],
							Name:        "h1",
							Start:       1,
							End:         24,
							Line:        2,
							SelfClosing: false,
							Children: []MarkupItem{
								{
									Typ:         MarkupItemType[MUText],
									Data:        "padded element",
									Start:       5,
									End:         19,
									Line:        2,
									SelfClosing: true,
								},
							},
						},
					},
				},
			},
		},
		{
			input: &TBLexer{
				options: &options.Options{
					CachePath: filepath.Join("../../../", "bin", "delete"),
				},
				templateDataBuf: TemplateDataBuffer{
					markupBlock: *bytes.NewBuffer([]byte("<p><span>Nested</span></p>")),
				},
			},
			output: OutputMarkupTree{
				HTML: MarkupItem{
					Typ: MarkupItemType[MUFragment],
					Children: []MarkupItem{
						{
							Typ:   MarkupItemType[MUElement],
							Name:  "p",
							Start: 0,
							End:   26,
							Line:  1,
							Children: []MarkupItem{
								{
									Typ:         MarkupItemType[MUElement],
									Name:        "span",
									Start:       3,
									End:         22,
									Line:        1,
									SelfClosing: false,
									Children: []MarkupItem{
										{
											Typ:         MarkupItemType[MUText],
											Data:        "Nested",
											Start:       9,
											End:         15,
											Line:        1,
											SelfClosing: true,
										},
									},
								},
							},
						},
					},
				},
			},
		},
		{
			input: &TBLexer{
				options: &options.Options{
					CachePath: filepath.Join("../../../", "bin", "delete"),
				},
				templateDataBuf: TemplateDataBuffer{
					markupBlock: *bytes.NewBuffer([]byte("<div><p><span>Nested</span></p></div>")),
				},
			},
			output: OutputMarkupTree{
				HTML: MarkupItem{
					Typ: MarkupItemType[MUFragment],
					Children: []MarkupItem{
						{
							Typ:   MarkupItemType[MUElement],
							Name:  "div",
							Start: 0,
							End:   37,
							Line:  1,
							Children: []MarkupItem{
								{
									Typ:   MarkupItemType[MUElement],
									Name:  "p",
									Start: 5,
									End:   31,
									Line:  1,
									Children: []MarkupItem{
										{
											Typ:         MarkupItemType[MUElement],
											Name:        "span",
											Start:       8,
											End:         27,
											Line:        1,
											SelfClosing: false,
											Children: []MarkupItem{
												{
													Typ:         MarkupItemType[MUText],
													Data:        "Nested",
													Start:       14,
													End:         20,
													Line:        1,
													SelfClosing: true,
												},
											},
										},
									},
								},
							},
						},
					},
				},
			},
		},
		{
			input: &TBLexer{
				options: &options.Options{
					CachePath: filepath.Join("../../../", "bin", "delete"),
				},
				templateDataBuf: TemplateDataBuffer{
					markupBlock: *bytes.NewBuffer([]byte("<h1>Width</h1><p>tests</p>")),
				},
			},
			output: OutputMarkupTree{
				HTML: MarkupItem{
					Typ: MarkupItemType[MUFragment],
					Children: []MarkupItem{
						{
							Typ:   MarkupItemType[MUElement],
							Name:  "h1",
							Start: 0,
							End:   14,
							Line:  1,
							Children: []MarkupItem{
								{
									Typ:         MarkupItemType[MUText],
									Data:        "Width",
									Start:       4,
									End:         9,
									Line:        1,
									SelfClosing: true,
								},
							},
						},
						{
							Typ:   MarkupItemType[MUElement],
							Name:  "p",
							Start: 14,
							End:   26,
							Line:  1,
							Children: []MarkupItem{
								{
									Typ:         MarkupItemType[MUText],
									Data:        "tests",
									Start:       17,
									End:         22,
									Line:        1,
									SelfClosing: true,
								},
							},
						},
					},
				},
			},
		},
		{
			input: &TBLexer{
				options: &options.Options{
					CachePath: filepath.Join("../../../", "bin", "delete"),
				},
				templateDataBuf: TemplateDataBuffer{
					markupBlock: *bytes.NewBuffer([]byte("<div><p><span>Depth</span><span>width</span></p></div>")),
				},
			},
			output: OutputMarkupTree{
				HTML: MarkupItem{
					Typ: MarkupItemType[MUFragment],
					Children: []MarkupItem{
						{
							Typ:   MarkupItemType[MUElement],
							Name:  "div",
							Start: 0,
							End:   54,
							Line:  1,
							Children: []MarkupItem{
								{
									Typ:   MarkupItemType[MUElement],
									Name:  "p",
									Start: 5,
									End:   48,
									Line:  1,
									Children: []MarkupItem{
										{
											Typ:   MarkupItemType[MUElement],
											Name:  "span",
											Start: 8,
											End:   26,
											Line:  1,
											Children: []MarkupItem{
												{
													Typ:         MarkupItemType[MUText],
													Data:        "Depth",
													Start:       14,
													End:         19,
													Line:        1,
													SelfClosing: true,
												},
											},
										},
										{
											Typ:   MarkupItemType[MUElement],
											Name:  "span",
											Start: 26,
											End:   44,
											Line:  1,
											Children: []MarkupItem{
												{
													Typ:         MarkupItemType[MUText],
													Data:        "width",
													Start:       32,
													End:         37,
													Line:        1,
													SelfClosing: true,
												},
											},
										},
									},
								},
							},
						},
					},
				},
			},
		},
		{
			input: &TBLexer{
				options: &options.Options{
					CachePath: filepath.Join("../../../", "bin", "delete"),
				},
				templateDataBuf: TemplateDataBuffer{
					markupBlock: *bytes.NewBuffer([]byte("<div><p><span>Final</span><span>test</span><span>for</span></p><p><span>all</span><span>known</span><span>cases</span></p></div>")),
				},
			},
			output: OutputMarkupTree{
				HTML: MarkupItem{
					Typ: MarkupItemType[MUFragment],
					Children: []MarkupItem{
						{
							Typ:   MarkupItemType[MUElement],
							Name:  "div",
							Start: 0,
							End:   128,
							Line:  1,
							Children: []MarkupItem{
								{
									Typ:   MarkupItemType[MUElement],
									Name:  "p",
									Start: 5,
									End:   63,
									Line:  1,
									Children: []MarkupItem{
										{
											Typ:   MarkupItemType[MUElement],
											Name:  "span",
											Start: 8,
											End:   26,
											Line:  1,
											Children: []MarkupItem{
												{
													Typ:         MarkupItemType[MUText],
													Data:        "Final",
													Start:       14,
													End:         19,
													Line:        1,
													SelfClosing: true,
												},
											},
										},
										{
											Typ:   MarkupItemType[MUElement],
											Name:  "span",
											Start: 26,
											End:   43,
											Line:  1,
											Children: []MarkupItem{
												{
													Typ:         MarkupItemType[MUText],
													Data:        "test",
													Start:       32,
													End:         36,
													Line:        1,
													SelfClosing: true,
												},
											},
										},
										{
											Typ:   MarkupItemType[MUElement],
											Name:  "span",
											Start: 43,
											End:   59,
											Line:  1,
											Children: []MarkupItem{
												{
													Typ:         MarkupItemType[MUText],
													Data:        "for",
													Start:       49,
													End:         52,
													Line:        1,
													SelfClosing: true,
												},
											},
										},
									},
								},
								{
									Typ:   MarkupItemType[MUElement],
									Name:  "p",
									Start: 63,
									End:   122,
									Line:  1,
									Children: []MarkupItem{
										{
											Typ:   MarkupItemType[MUElement],
											Name:  "span",
											Start: 66,
											End:   82,
											Line:  1,
											Children: []MarkupItem{
												{
													Typ:         MarkupItemType[MUText],
													Data:        "all",
													Start:       72,
													End:         75,
													Line:        1,
													SelfClosing: true,
												},
											},
										},
										{
											Typ:   MarkupItemType[MUElement],
											Name:  "span",
											Start: 82,
											End:   100,
											Line:  1,
											Children: []MarkupItem{
												{
													Typ:         MarkupItemType[MUText],
													Data:        "known",
													Start:       88,
													End:         93,
													Line:        1,
													SelfClosing: true,
												},
											},
										},
										{
											Typ:   MarkupItemType[MUElement],
											Name:  "span",
											Start: 100,
											End:   118,
											Line:  1,
											Children: []MarkupItem{
												{
													Typ:         MarkupItemType[MUText],
													Data:        "cases",
													Start:       106,
													End:         111,
													Line:        1,
													SelfClosing: true,
												},
											},
										},
									},
								},
							},
						},
					},
				},
			},
		},
		{
			input: &TBLexer{
				options: &options.Options{
					CachePath: filepath.Join("../../../", "bin", "delete"),
				},
				templateDataBuf: TemplateDataBuffer{
					markupBlock: *bytes.NewBuffer([]byte("<h1>\n\t<span>Hello</span></h1>")),
				},
			},
			output: OutputMarkupTree{
				HTML: MarkupItem{
					Typ: "Fragment",
					Children: []MarkupItem{
						{
							Typ:         MarkupItemType[MUElement],
							Name:        "h1",
							Start:       0,
							End:         29,
							Line:        1,
							SelfClosing: false,
							Children: []MarkupItem{
								{
									Typ:         MarkupItemType[MUText],
									Data:        "\n\t",
									Start:       4,
									End:         6,
									Line:        1,
									SelfClosing: true,
								},
								{
									Typ:   MarkupItemType[MUElement],
									Name:  "span",
									Start: 6,
									End:   24,
									Line:  2,
									Children: []MarkupItem{
										{
											Typ:         MarkupItemType[MUText],
											Data:        "Hello",
											Start:       12,
											End:         17,
											Line:        2,
											SelfClosing: true,
										},
									},
								},
							},
						},
					},
				},
			},
		},
		{
			input: &TBLexer{
				options: &options.Options{
					CachePath: filepath.Join("../../../", "bin", "delete"),
				},
				templateDataBuf: TemplateDataBuffer{
					markupBlock: *bytes.NewBuffer([]byte("<h1>\n\t<span>\n\t\tHello</span></h1>")),
				},
			},
			output: OutputMarkupTree{
				HTML: MarkupItem{
					Typ: "Fragment",
					Children: []MarkupItem{
						{
							Typ:         MarkupItemType[MUElement],
							Name:        "h1",
							Start:       0,
							End:         32,
							Line:        1,
							SelfClosing: false,
							Children: []MarkupItem{
								{
									Typ:         MarkupItemType[MUText],
									Data:        "\n\t",
									Start:       4,
									End:         6,
									Line:        1,
									SelfClosing: true,
								},
								{
									Typ:   MarkupItemType[MUElement],
									Name:  "span",
									Start: 6,
									End:   27,
									Line:  2,
									Children: []MarkupItem{
										{
											Typ:         MarkupItemType[MUText],
											Data:        "\n\t\tHello",
											Start:       12,
											End:         20,
											Line:        2,
											SelfClosing: true,
										},
									},
								},
							},
						},
					},
				},
			},
		},
		{
			input: &TBLexer{
				options: &options.Options{
					CachePath: filepath.Join("../../../", "bin", "delete"),
				},
				templateDataBuf: TemplateDataBuffer{
					markupBlock: *bytes.NewBuffer([]byte("<h1>\n\t<span>\n\t\tHello\n\t</span></h1>")),
				},
			},
			output: OutputMarkupTree{
				HTML: MarkupItem{
					Typ: "Fragment",
					Children: []MarkupItem{
						{
							Typ:         MarkupItemType[MUElement],
							Name:        "h1",
							Start:       0,
							End:         34,
							Line:        1,
							SelfClosing: false,
							Children: []MarkupItem{
								{
									Typ:         MarkupItemType[MUText],
									Data:        "\n\t",
									Start:       4,
									End:         6,
									Line:        1,
									SelfClosing: true,
								},
								{
									Typ:   MarkupItemType[MUElement],
									Name:  "span",
									Start: 6,
									End:   29,
									Line:  2,
									Children: []MarkupItem{
										{
											Typ:         MarkupItemType[MUText],
											Data:        "\n\t\tHello\n\t",
											Start:       12,
											End:         22,
											Line:        2,
											SelfClosing: true,
										},
									},
								},
							},
						},
					},
				},
			},
		},
		{
			input: &TBLexer{
				options: &options.Options{
					CachePath: filepath.Join("../../../", "bin", "delete"),
				},
				templateDataBuf: TemplateDataBuffer{
					markupBlock: *bytes.NewBuffer([]byte("<h1>\n\t<span>\n\t\tHello\n\t</span>\n</h1>")),
				},
			},
			output: OutputMarkupTree{
				HTML: MarkupItem{
					Typ: "Fragment",
					Children: []MarkupItem{
						{
							Typ:         MarkupItemType[MUElement],
							Name:        "h1",
							Start:       0,
							End:         35,
							Line:        1,
							SelfClosing: false,
							Children: []MarkupItem{
								{
									Typ:         MarkupItemType[MUText],
									Data:        "\n\t",
									Start:       4,
									End:         6,
									Line:        1,
									SelfClosing: true,
								},
								{
									Typ:   MarkupItemType[MUElement],
									Name:  "span",
									Start: 6,
									End:   29,
									Line:  2,
									Children: []MarkupItem{
										{
											Typ:         MarkupItemType[MUText],
											Data:        "\n\t\tHello\n\t",
											Start:       12,
											End:         22,
											Line:        2,
											SelfClosing: true,
										},
									},
								},
								{
									Typ:         MarkupItemType[MUText],
									Data:        "\n",
									Start:       29,
									End:         30,
									Line:        4,
									SelfClosing: true,
								},
							},
						},
					},
				},
			},
		},
		{
			input: &TBLexer{
				options: &options.Options{
					CachePath: filepath.Join("../../../", "bin", "delete"),
				},
				templateDataBuf: TemplateDataBuffer{
					markupBlock: *bytes.NewBuffer([]byte("<HeaderComp />\n\n<h1>\n\tWelcome!\n</h1>")),
					headBlock: []HeadBlockItem{
						{
							Kind: Kind{
								Name:    "link",
								RelType: "rel",
								Value:   "import",
							},
							Attrs: map[string]string{
								"name": "HeaderComp",
							},
							Path: Path{
								PathType: "href",
								RelPath:  "./header.html",
							},
						},
					},
				},
			},
			output: OutputMarkupTree{
				HTML: MarkupItem{
					Typ: "Fragment",
					Children: []MarkupItem{
						{
							Typ:         MarkupItemType[MUInlineComponent],
							Name:        "HeaderComp",
							Start:       0,
							End:         14,
							Line:        1,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUText],
							Data:        "\n\n",
							Start:       14,
							End:         16,
							Line:        1,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUElement],
							Name:        "h1",
							Start:       16,
							End:         36,
							Line:        3,
							SelfClosing: false,
							Children: []MarkupItem{
								{
									Typ:         MarkupItemType[MUText],
									Data:        "\n\tWelcome!\n",
									Start:       20,
									End:         31,
									Line:        3,
									SelfClosing: true,
								},
							},
						},
					},
				},
			},
		},
		{
			input: &TBLexer{
				options: &options.Options{
					CachePath: filepath.Join("../../../", "bin", "delete"),
				},
				templateDataBuf: TemplateDataBuffer{
					markupBlock: *bytes.NewBuffer([]byte("<HeaderComp />\n\n<h1>\n\tWelcome!\n</h1>\n\n<Links></Links>")),
					headBlock: []HeadBlockItem{
						{
							Kind: Kind{
								Name:    "link",
								RelType: "rel",
								Value:   "import",
							},
							Attrs: map[string]string{
								"name": "HeaderComp",
							},
							Path: Path{
								PathType: "href",
								RelPath:  "./header.html",
							},
						},
						{
							Kind: Kind{
								Name:    "link",
								RelType: "rel",
								Value:   "import",
							},
							Attrs: map[string]string{
								"name": "Links",
							},
							Path: Path{
								PathType: "href",
								RelPath:  "./links.html",
							},
						},
					},
				},
			},
			output: OutputMarkupTree{
				HTML: MarkupItem{
					Typ: "Fragment",
					Children: []MarkupItem{
						{
							Typ:         MarkupItemType[MUInlineComponent],
							Name:        "HeaderComp",
							Start:       0,
							End:         14,
							Line:        1,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUText],
							Data:        "\n\n",
							Start:       14,
							End:         16,
							Line:        1,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUElement],
							Name:        "h1",
							Start:       16,
							End:         36,
							Line:        3,
							SelfClosing: false,
							Children: []MarkupItem{
								{
									Typ:         MarkupItemType[MUText],
									Data:        "\n\tWelcome!\n",
									Start:       20,
									End:         31,
									Line:        3,
									SelfClosing: true,
								},
							},
						},
						{
							Typ:         MarkupItemType[MUText],
							Data:        "\n\n",
							Start:       36,
							End:         38,
							Line:        5,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUInlineComponent],
							Name:        "Links",
							Start:       38,
							End:         53,
							Line:        7,
							SelfClosing: true,
						},
					},
				},
			},
		},
		{
			input: &TBLexer{
				options: &options.Options{
					CachePath: filepath.Join("../../../", "bin", "delete"),
				},
				templateDataBuf: TemplateDataBuffer{
					markupBlock: *bytes.NewBuffer([]byte("<HeaderComp />\n\n<h1>\n\tWelcome!\n</h1>\n\n<Links></Links>\n\n<main>\n\t<slot type=\"static\" />\n</main>")),
					headBlock: []HeadBlockItem{
						{
							Kind: Kind{
								Name:    "link",
								RelType: "rel",
								Value:   "import",
							},
							Attrs: map[string]string{
								"name": "HeaderComp",
							},
							Path: Path{
								PathType: "href",
								RelPath:  "./header.html",
							},
						},
						{
							Kind: Kind{
								Name:    "link",
								RelType: "rel",
								Value:   "import",
							},
							Attrs: map[string]string{
								"name": "Links",
							},
							Path: Path{
								PathType: "href",
								RelPath:  "./links.html",
							},
						},
					},
				},
			},
			output: OutputMarkupTree{
				HTML: MarkupItem{
					Typ: "Fragment",
					Children: []MarkupItem{
						{
							Typ:         MarkupItemType[MUInlineComponent],
							Name:        "HeaderComp",
							Start:       0,
							End:         14,
							Line:        1,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUText],
							Data:        "\n\n",
							Start:       14,
							End:         16,
							Line:        1,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUElement],
							Name:        "h1",
							Start:       16,
							End:         36,
							Line:        3,
							SelfClosing: false,
							Children: []MarkupItem{
								{
									Typ:         MarkupItemType[MUText],
									Data:        "\n\tWelcome!\n",
									Start:       20,
									End:         31,
									Line:        3,
									SelfClosing: true,
								},
							},
						},
						{
							Typ:         MarkupItemType[MUText],
							Data:        "\n\n",
							Start:       36,
							End:         38,
							Line:        5,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUInlineComponent],
							Name:        "Links",
							Start:       38,
							End:         53,
							Line:        7,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUText],
							Data:        "\n\n",
							Start:       53,
							End:         55,
							Line:        7,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUElement],
							Name:        "main",
							Start:       55,
							End:         93,
							Line:        9,
							SelfClosing: false,
							Children: []MarkupItem{
								{
									Typ:         MarkupItemType[MUText],
									Data:        "\n\t",
									Start:       61,
									End:         63,
									Line:        9,
									SelfClosing: true,
								},
								{
									Typ:         MarkupItemType[MUSlot],
									Name:        "slot",
									Start:       63,
									End:         85,
									Line:        10,
									SelfClosing: true,
									Attributes: []MarkupItem{
										{
											Typ:   MarkupItemType[MUAttribute],
											Name:  "type",
											Start: 69,
											End:   82,
											Line:  10,
											Value: []MarkupItem{
												{
													Typ:   MarkupItemType[MUText],
													Data:  "static",
													Start: 75,
													End:   81,
													Line:  10,
												},
											},
										},
									},
								},
								{
									Typ:         MarkupItemType[MUText],
									Data:        "\n",
									Start:       85,
									End:         86,
									Line:        10,
									SelfClosing: true,
								},
							},
						},
					},
				},
			},
		},
		{
			input: &TBLexer{
				options: &options.Options{
					CachePath: filepath.Join("../../../", "bin", "delete"),
				},
				templateDataBuf: TemplateDataBuffer{
					markupBlock: *bytes.NewBuffer([]byte("<HeaderComp />\n\n<h1>\n\tWelcome!\n</h1>\n\n<Links></Links>\n\n<main>\n\t<slot type=\"static\" />\n</main>\n\n<FooterComp />")),
					headBlock: []HeadBlockItem{
						{
							Kind: Kind{
								Name:    "link",
								RelType: "rel",
								Value:   "import",
							},
							Attrs: map[string]string{
								"name": "HeaderComp",
							},
							Path: Path{
								PathType: "href",
								RelPath:  "./header.html",
							},
						},
						{
							Kind: Kind{
								Name:    "link",
								RelType: "rel",
								Value:   "import",
							},
							Attrs: map[string]string{
								"name": "Links",
							},
							Path: Path{
								PathType: "href",
								RelPath:  "./links.html",
							},
						},
						{
							Kind: Kind{
								Name:    "link",
								RelType: "rel",
								Value:   "import",
							},
							Attrs: map[string]string{
								"name": "FooterComp",
							},
							Path: Path{
								PathType: "href",
								RelPath:  "./footer.html",
							},
						},
					},
				},
			},
			output: OutputMarkupTree{
				HTML: MarkupItem{
					Typ: "Fragment",
					Children: []MarkupItem{
						{
							Typ:         MarkupItemType[MUInlineComponent],
							Name:        "HeaderComp",
							Start:       0,
							End:         14,
							Line:        1,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUText],
							Data:        "\n\n",
							Start:       14,
							End:         16,
							Line:        1,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUElement],
							Name:        "h1",
							Start:       16,
							End:         36,
							Line:        3,
							SelfClosing: false,
							Children: []MarkupItem{
								{
									Typ:         MarkupItemType[MUText],
									Data:        "\n\tWelcome!\n",
									Start:       20,
									End:         31,
									Line:        3,
									SelfClosing: true,
								},
							},
						},
						{
							Typ:         MarkupItemType[MUText],
							Data:        "\n\n",
							Start:       36,
							End:         38,
							Line:        5,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUInlineComponent],
							Name:        "Links",
							Start:       38,
							End:         53,
							Line:        7,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUText],
							Data:        "\n\n",
							Start:       53,
							End:         55,
							Line:        7,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUElement],
							Name:        "main",
							Start:       55,
							End:         93,
							Line:        9,
							SelfClosing: false,
							Children: []MarkupItem{
								{
									Typ:         MarkupItemType[MUText],
									Data:        "\n\t",
									Start:       61,
									End:         63,
									Line:        9,
									SelfClosing: true,
								},
								{
									Typ:         MarkupItemType[MUSlot],
									Name:        "slot",
									Start:       63,
									End:         85,
									Line:        10,
									SelfClosing: true,
									Attributes: []MarkupItem{
										{
											Typ:   MarkupItemType[MUAttribute],
											Name:  "type",
											Start: 69,
											End:   82,
											Line:  10,
											Value: []MarkupItem{
												{
													Typ:   MarkupItemType[MUText],
													Data:  "static",
													Start: 75,
													End:   81,
													Line:  10,
												},
											},
										},
									},
								},
								{
									Typ:         MarkupItemType[MUText],
									Data:        "\n",
									Start:       85,
									End:         86,
									Line:        10,
									SelfClosing: true,
								},
							},
						},
						{
							Typ:         MarkupItemType[MUText],
							Data:        "\n\n",
							Start:       93,
							End:         95,
							Line:        11,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUInlineComponent],
							Name:        "FooterComp",
							Start:       95,
							End:         109,
							Line:        13,
							SelfClosing: true,
						},
					},
				},
			},
		},
		{
			input: &TBLexer{
				options: &options.Options{
					CachePath: filepath.Join("../../../", "bin", "delete"),
				},
				templateDataBuf: TemplateDataBuffer{
					markupBlock: *bytes.NewBuffer([]byte("<!-- Test Comment -->\n\n<HeaderComp />\n\n<h1>\n\tWelcome!\n</h1>\n\n<Links></Links>\n\n<main>\n\t<slot type=\"static\" />\n</main>\n\n<FooterComp />")),
					headBlock: []HeadBlockItem{
						{
							Kind: Kind{
								Name:    "link",
								RelType: "rel",
								Value:   "import",
							},
							Attrs: map[string]string{
								"name": "HeaderComp",
							},
							Path: Path{
								PathType: "href",
								RelPath:  "./header.html",
							},
						},
						{
							Kind: Kind{
								Name:    "link",
								RelType: "rel",
								Value:   "import",
							},
							Attrs: map[string]string{
								"name": "Links",
							},
							Path: Path{
								PathType: "href",
								RelPath:  "./links.html",
							},
						},
						{
							Kind: Kind{
								Name:    "link",
								RelType: "rel",
								Value:   "import",
							},
							Attrs: map[string]string{
								"name": "FooterComp",
							},
							Path: Path{
								PathType: "href",
								RelPath:  "./footer.html",
							},
						},
					},
				},
			},
			output: OutputMarkupTree{
				HTML: MarkupItem{
					Typ: "Fragment",
					Children: []MarkupItem{
						{
							Typ:         MarkupItemType[MUComment],
							Data:        "Test Comment",
							Start:       0,
							End:         21,
							Line:        1,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUText],
							Data:        "\n\n",
							Start:       21,
							End:         23,
							Line:        1,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUInlineComponent],
							Name:        "HeaderComp",
							Start:       23,
							End:         37,
							Line:        3,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUText],
							Data:        "\n\n",
							Start:       37,
							End:         39,
							Line:        3,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUElement],
							Name:        "h1",
							Start:       39,
							End:         59,
							Line:        5,
							SelfClosing: false,
							Children: []MarkupItem{
								{
									Typ:         MarkupItemType[MUText],
									Data:        "\n\tWelcome!\n",
									Start:       43,
									End:         54,
									Line:        5,
									SelfClosing: true,
								},
							},
						},
						{
							Typ:         MarkupItemType[MUText],
							Data:        "\n\n",
							Start:       59,
							End:         61,
							Line:        7,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUInlineComponent],
							Name:        "Links",
							Start:       61,
							End:         76,
							Line:        9,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUText],
							Data:        "\n\n",
							Start:       76,
							End:         78,
							Line:        9,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUElement],
							Name:        "main",
							Start:       78,
							End:         116,
							Line:        11,
							SelfClosing: false,
							Children: []MarkupItem{
								{
									Typ:         MarkupItemType[MUText],
									Data:        "\n\t",
									Start:       84,
									End:         86,
									Line:        11,
									SelfClosing: true,
								},
								{
									Typ:         MarkupItemType[MUSlot],
									Name:        "slot",
									Start:       86,
									End:         108,
									Line:        12,
									SelfClosing: true,
									Attributes: []MarkupItem{
										{
											Typ:   MarkupItemType[MUAttribute],
											Name:  "type",
											Start: 92,
											End:   105,
											Line:  12,
											Value: []MarkupItem{
												{
													Typ:   MarkupItemType[MUText],
													Data:  "static",
													Start: 98,
													End:   104,
													Line:  12,
												},
											},
										},
									},
								},
								{
									Typ:         MarkupItemType[MUText],
									Data:        "\n",
									Start:       108,
									End:         109,
									Line:        12,
									SelfClosing: true,
								},
							},
						},
						{
							Typ:         MarkupItemType[MUText],
							Data:        "\n\n",
							Start:       116,
							End:         118,
							Line:        13,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUInlineComponent],
							Name:        "FooterComp",
							Start:       118,
							End:         132,
							Line:        15,
							SelfClosing: true,
						},
					},
				},
			},
		},
		{
			input: &TBLexer{
				options: &options.Options{
					CachePath: filepath.Join("../../../", "bin", "delete"),
				},
				templateDataBuf: TemplateDataBuffer{
					markupBlock: *bytes.NewBuffer([]byte("<main>\n\t<h1>Test Page</h1>\n\n\t<Links></Links>\n\n\t<SlotComponent>\n\t\t<a href=\"/\">Go To Home Page</a>\n\t</SlotComponent>\n</main>\n\n<FooterComp />")),
					headBlock: []HeadBlockItem{
						{
							Kind: Kind{
								Name:    "link",
								RelType: "rel",
								Value:   "import",
							},
							Attrs: map[string]string{
								"name": "Links",
							},
							Path: Path{
								PathType: "href",
								RelPath:  "./links.html",
							},
						},
						{
							Kind: Kind{
								Name:    "link",
								RelType: "rel",
								Value:   "import",
							},
							Attrs: map[string]string{
								"name": "SlotComponent",
							},
							Path: Path{
								PathType: "href",
								RelPath:  "./slot-component.html",
							},
						},
						{
							Kind: Kind{
								Name:    "link",
								RelType: "rel",
								Value:   "import",
							},
							Attrs: map[string]string{
								"name": "FooterComp",
							},
							Path: Path{
								PathType: "href",
								RelPath:  "./footer.html",
							},
						},
					},
				},
			},
			output: OutputMarkupTree{
				HTML: MarkupItem{
					Typ: "Fragment",
					Children: []MarkupItem{
						{
							Typ:         MarkupItemType[MUElement],
							Name:        "main",
							Start:       0,
							End:         122,
							Line:        1,
							SelfClosing: false,
							Children: []MarkupItem{
								{
									Typ:         MarkupItemType[MUText],
									Data:        "\n\t",
									Start:       6,
									End:         8,
									Line:        1,
									SelfClosing: true,
								},
								{
									Typ:         MarkupItemType[MUElement],
									Name:        "h1",
									Start:       8,
									End:         26,
									Line:        2,
									SelfClosing: false,
									Children: []MarkupItem{
										{
											Typ:         MarkupItemType[MUText],
											Data:        "Test Page",
											Start:       12,
											End:         21,
											Line:        2,
											SelfClosing: true,
										},
									},
								},
								{
									Typ:         MarkupItemType[MUText],
									Data:        "\n\n\t",
									Start:       26,
									End:         29,
									Line:        2,
									SelfClosing: true,
								},
								{
									Typ:         MarkupItemType[MUInlineComponent],
									Name:        "Links",
									Start:       29,
									End:         44,
									Line:        4,
									SelfClosing: true,
								},
								{
									Typ:         MarkupItemType[MUText],
									Data:        "\n\n\t",
									Start:       44,
									End:         47,
									Line:        4,
									SelfClosing: true,
								},
								{
									Typ:         MarkupItemType[MUInlineComponent],
									Name:        "SlotComponent",
									Start:       47,
									End:         114,
									Line:        6,
									SelfClosing: false,
									Children: []MarkupItem{
										{
											Typ:         MarkupItemType[MUText],
											Data:        "\n\t\t",
											Start:       62,
											End:         65,
											Line:        6,
											SelfClosing: true,
										},
										{
											Typ:         MarkupItemType[MUElement],
											Name:        "a",
											Start:       65,
											End:         96,
											Line:        7,
											SelfClosing: false,
											Attributes: []MarkupItem{
												{
													Typ:         MarkupItemType[MUAttribute],
													Name:        "href",
													Start:       68,
													End:         76,
													Line:        7,
													SelfClosing: false,
													Value: []MarkupItem{
														{
															Typ:         MarkupItemType[MUText],
															Data:        "/",
															Start:       74,
															End:         75,
															Line:        7,
															SelfClosing: false,
														},
													},
												},
											},
											Children: []MarkupItem{
												{
													Typ:         MarkupItemType[MUText],
													Data:        "Go To Home Page",
													Start:       77,
													End:         92,
													Line:        7,
													SelfClosing: true,
												},
											},
										},
										{
											Typ:         MarkupItemType[MUText],
											Data:        "\n\t",
											Start:       96,
											End:         98,
											Line:        7,
											SelfClosing: true,
										},
									},
								},
								{
									Typ:         MarkupItemType[MUText],
									Data:        "\n",
									Start:       114,
									End:         115,
									Line:        8,
									SelfClosing: true,
								},
							},
						},
						{
							Typ:         MarkupItemType[MUText],
							Data:        "\n\n",
							Start:       122,
							End:         124,
							Line:        9,
							SelfClosing: true,
						},
						{
							Typ:         MarkupItemType[MUInlineComponent],
							Name:        "FooterComp",
							Start:       124,
							End:         138,
							Line:        11,
							SelfClosing: true,
						},
					},
				},
			},
		},
		{
			input: &TBLexer{
				options: &options.Options{
					CachePath: filepath.Join("../../../", "bin", "delete"),
				},
				templateDataBuf: TemplateDataBuffer{
					markupBlock: *bytes.NewBuffer([]byte("<footer>\n\t<Links />\n\t<Socket />\n</footer>")),
					headBlock: []HeadBlockItem{
						{
							Kind: Kind{
								Name:    "link",
								RelType: "rel",
								Value:   "import",
							},
							Attrs: map[string]string{
								"name": "Links",
							},
							Path: Path{
								PathType: "href",
								RelPath:  "./links.html",
							},
						},
						{
							Kind: Kind{
								Name:    "link",
								RelType: "rel",
								Value:   "import",
							},
							Attrs: map[string]string{
								"name": "Socket",
							},
							Path: Path{
								PathType: "href",
								RelPath:  "./socket.html",
							},
						},
					},
				},
			},
			output: OutputMarkupTree{
				HTML: MarkupItem{
					Typ: "Fragment",
					Children: []MarkupItem{
						{
							Typ:         MarkupItemType[MUElement],
							Name:        "footer",
							Start:       0,
							End:         41,
							Line:        1,
							SelfClosing: false,
							Children: []MarkupItem{
								{
									Typ:         MarkupItemType[MUText],
									Data:        "\n\t",
									Start:       8,
									End:         10,
									Line:        1,
									SelfClosing: true,
								},
								{
									Typ:         MarkupItemType[MUInlineComponent],
									Name:        "Links",
									Start:       10,
									End:         19,
									Line:        2,
									SelfClosing: true,
								},
								{
									Typ:         MarkupItemType[MUText],
									Data:        "\n\t",
									Start:       19,
									End:         21,
									Line:        2,
									SelfClosing: true,
								},
								{
									Typ:         MarkupItemType[MUInlineComponent],
									Name:        "Socket",
									Start:       21,
									End:         31,
									Line:        3,
									SelfClosing: true,
								},
								{
									Typ:         MarkupItemType[MUText],
									Data:        "\n",
									Start:       31,
									End:         32,
									Line:        3,
									SelfClosing: true,
								},
							},
						},
					},
				},
			},
		},
		{
			input: &TBLexer{
				options: &options.Options{
					CachePath: filepath.Join("../../../", "bin", "delete"),
				},
				templateDataBuf: TemplateDataBuffer{
					markupBlock: *bytes.NewBuffer([]byte("<Comp>Hello</Comp>")),
					headBlock: []HeadBlockItem{
						{
							Kind: Kind{
								Name:    "link",
								RelType: "rel",
								Value:   "import",
							},
							Attrs: map[string]string{
								"name": "Comp",
							},
							Path: Path{
								PathType: "href",
								RelPath:  "./comp.html",
							},
						},
					},
				},
			},
			output: OutputMarkupTree{
				HTML: MarkupItem{
					Typ: "Fragment",
					Children: []MarkupItem{
						{
							Typ:         MarkupItemType[MUInlineComponent],
							Name:        "Comp",
							Start:       0,
							End:         18,
							Line:        1,
							SelfClosing: false,
							Children: []MarkupItem{
								{
									Typ:         MarkupItemType[MUText],
									Data:        "Hello",
									Start:       6,
									End:         11,
									Line:        1,
									SelfClosing: true,
								},
							},
						},
					},
				},
			},
		},
	}

	is := is.New(t)

	for _, tt := range tests {
		td := New(tt.input, newArgs{"parser_test", "path", true, TemplateKind[Page]})

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

		// fmt.Printf("\n\n\nEXP: %+v\n\nRES: %+v\n\n\n\n", tt.output.HTML, td.Markup.HTML)
		is.Equal(tt.output.HTML, td.Markup.HTML)
	}
}
