"
---
@ DocumentNode (location: (1:0)-(1:17))
-├── errors: (1 error)
-│ └── @ UnclosedElementError (location: (1:17)-(1:17))
-│ ├── message: "Tag `
` opened at (1:1) was never closed before the end of document."
-│ └── opening_tag: "div" (location: (1:1)-(1:4))
-│
└── children: (1 item)
- └── @ HTMLElementNode (location: (1:0)-(1:17))
+ └── @ HTMLOpenTagNode (location: (1:0)-(1:17))
├── errors: (1 error)
- │ └── @ MissingClosingTagError (location: (1:1)-(1:4))
- │ ├── message: "Opening tag `
` at (1:1) doesn't have a matching closing tag `
`."
+ │ └── @ MissingClosingTagError (location: (1:0)-(1:17))
+ │ ├── message: "Opening tag `
` at (1:1) doesn't have a matching closing tag `
` in the same scope."
│ └── opening_tag: "div" (location: (1:1)-(1:4))
│
- ├── open_tag:
- │ └── @ HTMLOpenTagNode (location: (1:0)-(1:17))
- │ ├── tag_opening: "<" (location: (1:0)-(1:1))
- │ ├── tag_name: "div" (location: (1:1)-(1:4))
- │ ├── tag_closing: ">" (location: (1:16)-(1:17))
- │ ├── children: (1 item)
- │ │ └── @ HTMLAttributeNode (location: (1:5)-(1:16))
- │ │ ├── name:
- │ │ │ └── @ HTMLAttributeNameNode (location: (1:5)-(1:10))
- │ │ │ └── children: (1 item)
- │ │ │ └── @ LiteralNode (location: (1:5)-(1:10))
- │ │ │ └── content: "value"
- │ │ │
- │ │ │
- │ │ ├── equals: "=" (location: (1:10)-(1:11))
- │ │ └── value:
- │ │ └── @ HTMLAttributeValueNode (location: (1:11)-(1:16))
- │ │ ├── open_quote: ∅
- │ │ ├── children: (1 item)
- │ │ │ └── @ LiteralNode (location: (1:11)-(1:16))
- │ │ │ └── content: "hello"
- │ │ │
- │ │ ├── close_quote: ∅
- │ │ └── quoted: false
+ ├── tag_opening: "<" (location: (1:0)-(1:1))
+ ├── tag_name: "div" (location: (1:1)-(1:4))
+ ├── tag_closing: ">" (location: (1:16)-(1:17))
+ ├── children: (1 item)
+ │ └── @ HTMLAttributeNode (location: (1:5)-(1:16))
+ │ ├── name:
+ │ │ └── @ HTMLAttributeNameNode (location: (1:5)-(1:10))
+ │ │ └── children: (1 item)
+ │ │ └── @ LiteralNode (location: (1:5)-(1:10))
+ │ │ └── content: "value"
│ │
│ │
- │ └── is_void: false
+ │ ├── equals: "=" (location: (1:10)-(1:11))
+ │ └── value:
+ │ └── @ HTMLAttributeValueNode (location: (1:11)-(1:16))
+ │ ├── open_quote: ∅
+ │ ├── children: (1 item)
+ │ │ └── @ LiteralNode (location: (1:11)-(1:16))
+ │ │ └── content: "hello"
+ │ │
+ │ ├── close_quote: ∅
+ │ └── quoted: false
│
- ├── tag_name: "div" (location: (1:1)-(1:4))
- ├── body: []
- ├── close_tag: ∅
- ├── is_void: false
- └── source: "HTML"
\ No newline at end of file
+ │
+ └── is_void: false
\ No newline at end of file
diff --git a/test/snapshots/parser/attributes_test/test_0037_attribute_with_backtick_containing_HTML_(invalid)_542130e358dadabeb4a1629bc9bcf4f3.txt b/test/snapshots/parser/attributes_test/test_0037_attribute_with_backtick_containing_HTML_(invalid)_542130e358dadabeb4a1629bc9bcf4f3.txt
index 085ee3be6..1fc311d3e 100644
--- a/test/snapshots/parser/attributes_test/test_0037_attribute_with_backtick_containing_HTML_(invalid)_542130e358dadabeb4a1629bc9bcf4f3.txt
+++ b/test/snapshots/parser/attributes_test/test_0037_attribute_with_backtick_containing_HTML_(invalid)_542130e358dadabeb4a1629bc9bcf4f3.txt
@@ -3,94 +3,83 @@ source: "Parser::AttributesTest#test_0037_attribute with backtick containing HTM
input: "
Hello`>
"
---
@ DocumentNode (location: (1:0)-(1:46))
-├── errors: (1 error)
-│ └── @ UnclosedElementError (location: (1:40)-(1:42))
-│ ├── message: "Tag `
` opened at (1:1) was never closed before the end of document."
-│ └── opening_tag: "div" (location: (1:1)-(1:4))
-│
-└── children: (3 items)
- ├── @ HTMLElementNode (location: (1:0)-(1:38))
- │ ├── errors: (1 error)
- │ │ └── @ TagNamesMismatchError (location: (1:33)-(1:37))
- │ │ ├── message: "Opening tag `
` at (1:1) closed with `` at (1:33)."
- │ │ ├── opening_tag: "div" (location: (1:1)-(1:4))
- │ │ └── closing_tag: "span" (location: (1:33)-(1:37))
- │ │
- │ ├── open_tag:
- │ │ └── @ HTMLOpenTagNode (location: (1:0)-(1:26))
- │ │ ├── errors: (1 error)
- │ │ │ └── @ UnexpectedError (location: (1:20)-(1:21))
- │ │ │ ├── message: "Unexpected Token. Expected: `TOKEN_IDENTIFIER, TOKEN_AT, TOKEN_ERB_START,TOKEN_WHITESPACE, or TOKEN_NEWLINE`, found: `TOKEN_HTML_TAG_START`."
- │ │ │ ├── description: "Unexpected Token"
- │ │ │ ├── expected: "TOKEN_IDENTIFIER, TOKEN_AT, TOKEN_ERB_START,TOKEN_WHITESPACE, or TOKEN_NEWLINE"
- │ │ │ └── found: "TOKEN_HTML_TAG_START"
- │ │ │
- │ │ ├── tag_opening: "<" (location: (1:0)-(1:1))
- │ │ ├── tag_name: "div" (location: (1:1)-(1:4))
- │ │ ├── tag_closing: ">" (location: (1:25)-(1:26))
- │ │ ├── children: (2 items)
- │ │ │ ├── @ HTMLAttributeNode (location: (1:5)-(1:20))
- │ │ │ │ ├── name:
- │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:5)-(1:18))
- │ │ │ │ │ └── children: (1 item)
- │ │ │ │ │ └── @ LiteralNode (location: (1:5)-(1:18))
- │ │ │ │ │ └── content: "data-template"
- │ │ │ │ │
- │ │ │ │ │
- │ │ │ │ ├── equals: "=" (location: (1:18)-(1:19))
- │ │ │ │ └── value:
- │ │ │ │ └── @ HTMLAttributeValueNode (location: (1:19)-(1:20))
- │ │ │ │ ├── errors: (1 error)
- │ │ │ │ │ └── @ UnexpectedError (location: (1:19)-(1:20))
- │ │ │ │ │ ├── message: "Invalid quote character for HTML attribute. Expected: `single quote (') or double quote (\")`, found: `backtick (`)`."
- │ │ │ │ │ ├── description: "Invalid quote character for HTML attribute"
- │ │ │ │ │ ├── expected: "single quote (') or double quote (\")"
- │ │ │ │ │ └── found: "backtick (`)"
- │ │ │ │ │
- │ │ │ │ ├── open_quote: ∅
- │ │ │ │ ├── children: []
- │ │ │ │ ├── close_quote: ∅
- │ │ │ │ └── quoted: false
- │ │ │ │
- │ │ │ │
- │ │ │ └── @ HTMLAttributeNode (location: (1:21)-(1:25))
- │ │ │ ├── name:
- │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:21)-(1:25))
- │ │ │ │ └── children: (1 item)
- │ │ │ │ └── @ LiteralNode (location: (1:21)-(1:25))
- │ │ │ │ └── content: "span"
- │ │ │ │
- │ │ │ │
- │ │ │ ├── equals: ∅
- │ │ │ └── value: ∅
- │ │ │
- │ │ └── is_void: false
- │ │
- │ ├── tag_name: "div" (location: (1:1)-(1:4))
- │ ├── body: (1 item)
- │ │ └── @ HTMLTextNode (location: (1:26)-(1:31))
- │ │ └── content: "Hello"
- │ │
- │ ├── close_tag:
- │ │ └── @ HTMLCloseTagNode (location: (1:31)-(1:38))
- │ │ ├── tag_opening: "" (location: (1:31)-(1:33))
- │ │ ├── tag_name: "span" (location: (1:33)-(1:37))
- │ │ ├── children: []
- │ │ └── tag_closing: ">" (location: (1:37)-(1:38))
- │ │
- │ ├── is_void: false
- │ └── source: "HTML"
- │
- ├── @ HTMLTextNode (location: (1:38)-(1:40))
- │ └── content: "`>"
- │
- └── @ HTMLCloseTagNode (location: (1:40)-(1:46))
- ├── errors: (1 error)
- │ └── @ MissingOpeningTagError (location: (1:40)-(1:46))
- │ ├── message: "Found closing tag `
` at (1:42) without a matching opening tag."
- │ └── closing_tag: "div" (location: (1:42)-(1:45))
+└── children: (1 item)
+ └── @ HTMLElementNode (location: (1:0)-(1:46))
+ ├── open_tag:
+ │ └── @ HTMLOpenTagNode (location: (1:0)-(1:26))
+ │ ├── errors: (1 error)
+ │ │ └── @ UnexpectedError (location: (1:20)-(1:21))
+ │ │ ├── message: "Unexpected Token. Expected: `TOKEN_IDENTIFIER, TOKEN_AT, TOKEN_ERB_START,TOKEN_WHITESPACE, or TOKEN_NEWLINE`, found: `TOKEN_HTML_TAG_START`."
+ │ │ ├── description: "Unexpected Token"
+ │ │ ├── expected: "TOKEN_IDENTIFIER, TOKEN_AT, TOKEN_ERB_START,TOKEN_WHITESPACE, or TOKEN_NEWLINE"
+ │ │ └── found: "TOKEN_HTML_TAG_START"
+ │ │
+ │ ├── tag_opening: "<" (location: (1:0)-(1:1))
+ │ ├── tag_name: "div" (location: (1:1)-(1:4))
+ │ ├── tag_closing: ">" (location: (1:25)-(1:26))
+ │ ├── children: (2 items)
+ │ │ ├── @ HTMLAttributeNode (location: (1:5)-(1:20))
+ │ │ │ ├── name:
+ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:5)-(1:18))
+ │ │ │ │ └── children: (1 item)
+ │ │ │ │ └── @ LiteralNode (location: (1:5)-(1:18))
+ │ │ │ │ └── content: "data-template"
+ │ │ │ │
+ │ │ │ │
+ │ │ │ ├── equals: "=" (location: (1:18)-(1:19))
+ │ │ │ └── value:
+ │ │ │ └── @ HTMLAttributeValueNode (location: (1:19)-(1:20))
+ │ │ │ ├── errors: (1 error)
+ │ │ │ │ └── @ UnexpectedError (location: (1:19)-(1:20))
+ │ │ │ │ ├── message: "Invalid quote character for HTML attribute. Expected: `single quote (') or double quote (\")`, found: `backtick (`)`."
+ │ │ │ │ ├── description: "Invalid quote character for HTML attribute"
+ │ │ │ │ ├── expected: "single quote (') or double quote (\")"
+ │ │ │ │ └── found: "backtick (`)"
+ │ │ │ │
+ │ │ │ ├── open_quote: ∅
+ │ │ │ ├── children: []
+ │ │ │ ├── close_quote: ∅
+ │ │ │ └── quoted: false
+ │ │ │
+ │ │ │
+ │ │ └── @ HTMLAttributeNode (location: (1:21)-(1:25))
+ │ │ ├── name:
+ │ │ │ └── @ HTMLAttributeNameNode (location: (1:21)-(1:25))
+ │ │ │ └── children: (1 item)
+ │ │ │ └── @ LiteralNode (location: (1:21)-(1:25))
+ │ │ │ └── content: "span"
+ │ │ │
+ │ │ │
+ │ │ ├── equals: ∅
+ │ │ └── value: ∅
+ │ │
+ │ └── is_void: false
│
- ├── tag_opening: "" (location: (1:40)-(1:42))
- ├── tag_name: "div" (location: (1:42)-(1:45))
- ├── children: []
- └── tag_closing: ">" (location: (1:45)-(1:46))
\ No newline at end of file
+ ├── tag_name: "div" (location: (1:1)-(1:4))
+ ├── body: (3 items)
+ │ ├── @ HTMLTextNode (location: (1:26)-(1:31))
+ │ │ └── content: "Hello"
+ │ │
+ │ ├── @ HTMLCloseTagNode (location: (1:31)-(1:38))
+ │ │ ├── errors: (1 error)
+ │ │ │ └── @ MissingOpeningTagError (location: (1:31)-(1:38))
+ │ │ │ ├── message: "Found closing tag `` at (1:33) without a matching opening tag in the same scope."
+ │ │ │ └── closing_tag: "span" (location: (1:33)-(1:37))
+ │ │ │
+ │ │ ├── tag_opening: "" (location: (1:31)-(1:33))
+ │ │ ├── tag_name: "span" (location: (1:33)-(1:37))
+ │ │ ├── children: []
+ │ │ └── tag_closing: ">" (location: (1:37)-(1:38))
+ │ │
+ │ └── @ HTMLTextNode (location: (1:38)-(1:40))
+ │ └── content: "`>"
+ │
+ ├── close_tag:
+ │ └── @ HTMLCloseTagNode (location: (1:40)-(1:46))
+ │ ├── tag_opening: "" (location: (1:40)-(1:42))
+ │ ├── tag_name: "div" (location: (1:42)-(1:45))
+ │ ├── children: []
+ │ └── tag_closing: ">" (location: (1:45)-(1:46))
+ │
+ ├── is_void: false
+ └── source: "HTML"
\ No newline at end of file
diff --git a/test/snapshots/parser/case_match_test/test_0001_case_in_69cf275355e6a10adc88e47d5090dd3a.txt b/test/snapshots/parser/case_match_test/test_0001_case_in_69cf275355e6a10adc88e47d5090dd3a.txt
new file mode 100644
index 000000000..2e841c76d
--- /dev/null
+++ b/test/snapshots/parser/case_match_test/test_0001_case_in_69cf275355e6a10adc88e47d5090dd3a.txt
@@ -0,0 +1,131 @@
+---
+source: "Parser::CaseMatchTest#test_0001_case/in"
+input: |2-
+<% case { hash: { nested: '4' } } %>
+
children
+<% in { hash: { nested: } } %>
+
nested
+<% else %>
+
else
+<% end %>
+---
+@ DocumentNode (location: (1:0)-(8:0))
+└── children: (2 items)
+ ├── @ ERBCaseMatchNode (location: (1:0)-(7:9))
+ │ ├── tag_opening: "<%" (location: (1:0)-(1:2))
+ │ ├── content: " case { hash: { nested: '4' } } " (location: (1:2)-(1:34))
+ │ ├── tag_closing: "%>" (location: (1:34)-(1:36))
+ │ ├── children: (3 items)
+ │ │ ├── @ HTMLTextNode (location: (1:36)-(2:2))
+ │ │ │ └── content: "\n "
+ │ │ │
+ │ │ ├── @ HTMLElementNode (location: (2:2)-(2:23))
+ │ │ │ ├── open_tag:
+ │ │ │ │ └── @ HTMLOpenTagNode (location: (2:2)-(2:8))
+ │ │ │ │ ├── tag_opening: "<" (location: (2:2)-(2:3))
+ │ │ │ │ ├── tag_name: "span" (location: (2:3)-(2:7))
+ │ │ │ │ ├── tag_closing: ">" (location: (2:7)-(2:8))
+ │ │ │ │ ├── children: []
+ │ │ │ │ └── is_void: false
+ │ │ │ │
+ │ │ │ ├── tag_name: "span" (location: (2:3)-(2:7))
+ │ │ │ ├── body: (1 item)
+ │ │ │ │ └── @ HTMLTextNode (location: (2:8)-(2:16))
+ │ │ │ │ └── content: "children"
+ │ │ │ │
+ │ │ │ ├── close_tag:
+ │ │ │ │ └── @ HTMLCloseTagNode (location: (2:16)-(2:23))
+ │ │ │ │ ├── tag_opening: "" (location: (2:16)-(2:18))
+ │ │ │ │ ├── tag_name: "span" (location: (2:18)-(2:22))
+ │ │ │ │ ├── children: []
+ │ │ │ │ └── tag_closing: ">" (location: (2:22)-(2:23))
+ │ │ │ │
+ │ │ │ ├── is_void: false
+ │ │ │ └── source: "HTML"
+ │ │ │
+ │ │ └── @ HTMLTextNode (location: (2:23)-(3:0))
+ │ │ └── content: "\n"
+ │ │
+ │ ├── conditions: (1 item)
+ │ │ └── @ ERBInNode (location: (3:0)-(3:30))
+ │ │ ├── tag_opening: "<%" (location: (3:0)-(3:2))
+ │ │ ├── content: " in { hash: { nested: } } " (location: (3:2)-(3:28))
+ │ │ ├── tag_closing: "%>" (location: (3:28)-(3:30))
+ │ │ └── statements: (3 items)
+ │ │ ├── @ HTMLTextNode (location: (3:30)-(4:2))
+ │ │ │ └── content: "\n "
+ │ │ │
+ │ │ ├── @ HTMLElementNode (location: (4:2)-(4:21))
+ │ │ │ ├── open_tag:
+ │ │ │ │ └── @ HTMLOpenTagNode (location: (4:2)-(4:8))
+ │ │ │ │ ├── tag_opening: "<" (location: (4:2)-(4:3))
+ │ │ │ │ ├── tag_name: "span" (location: (4:3)-(4:7))
+ │ │ │ │ ├── tag_closing: ">" (location: (4:7)-(4:8))
+ │ │ │ │ ├── children: []
+ │ │ │ │ └── is_void: false
+ │ │ │ │
+ │ │ │ ├── tag_name: "span" (location: (4:3)-(4:7))
+ │ │ │ ├── body: (1 item)
+ │ │ │ │ └── @ HTMLTextNode (location: (4:8)-(4:14))
+ │ │ │ │ └── content: "nested"
+ │ │ │ │
+ │ │ │ ├── close_tag:
+ │ │ │ │ └── @ HTMLCloseTagNode (location: (4:14)-(4:21))
+ │ │ │ │ ├── tag_opening: "" (location: (4:14)-(4:16))
+ │ │ │ │ ├── tag_name: "span" (location: (4:16)-(4:20))
+ │ │ │ │ ├── children: []
+ │ │ │ │ └── tag_closing: ">" (location: (4:20)-(4:21))
+ │ │ │ │
+ │ │ │ ├── is_void: false
+ │ │ │ └── source: "HTML"
+ │ │ │
+ │ │ └── @ HTMLTextNode (location: (4:21)-(5:0))
+ │ │ └── content: "\n"
+ │ │
+ │ │
+ │ ├── else_clause:
+ │ │ └── @ ERBElseNode (location: (5:0)-(5:10))
+ │ │ ├── tag_opening: "<%" (location: (5:0)-(5:2))
+ │ │ ├── content: " else " (location: (5:2)-(5:8))
+ │ │ ├── tag_closing: "%>" (location: (5:8)-(5:10))
+ │ │ └── statements: (3 items)
+ │ │ ├── @ HTMLTextNode (location: (5:10)-(6:2))
+ │ │ │ └── content: "\n "
+ │ │ │
+ │ │ ├── @ HTMLElementNode (location: (6:2)-(6:19))
+ │ │ │ ├── open_tag:
+ │ │ │ │ └── @ HTMLOpenTagNode (location: (6:2)-(6:8))
+ │ │ │ │ ├── tag_opening: "<" (location: (6:2)-(6:3))
+ │ │ │ │ ├── tag_name: "span" (location: (6:3)-(6:7))
+ │ │ │ │ ├── tag_closing: ">" (location: (6:7)-(6:8))
+ │ │ │ │ ├── children: []
+ │ │ │ │ └── is_void: false
+ │ │ │ │
+ │ │ │ ├── tag_name: "span" (location: (6:3)-(6:7))
+ │ │ │ ├── body: (1 item)
+ │ │ │ │ └── @ HTMLTextNode (location: (6:8)-(6:12))
+ │ │ │ │ └── content: "else"
+ │ │ │ │
+ │ │ │ ├── close_tag:
+ │ │ │ │ └── @ HTMLCloseTagNode (location: (6:12)-(6:19))
+ │ │ │ │ ├── tag_opening: "" (location: (6:12)-(6:14))
+ │ │ │ │ ├── tag_name: "span" (location: (6:14)-(6:18))
+ │ │ │ │ ├── children: []
+ │ │ │ │ └── tag_closing: ">" (location: (6:18)-(6:19))
+ │ │ │ │
+ │ │ │ ├── is_void: false
+ │ │ │ └── source: "HTML"
+ │ │ │
+ │ │ └── @ HTMLTextNode (location: (6:19)-(7:0))
+ │ │ └── content: "\n"
+ │ │
+ │ │
+ │ └── end_node:
+ │ └── @ ERBEndNode (location: (7:0)-(7:9))
+ │ ├── tag_opening: "<%" (location: (7:0)-(7:2))
+ │ ├── content: " end " (location: (7:2)-(7:7))
+ │ └── tag_closing: "%>" (location: (7:7)-(7:9))
+ │
+ │
+ └── @ HTMLTextNode (location: (7:9)-(8:0))
+ └── content: "\n"
\ No newline at end of file
diff --git a/test/snapshots/parser/case_when_test/test_0001_case_when_71d06502a93ad345bf738ba8ace8bf9f.txt b/test/snapshots/parser/case_when_test/test_0001_case_when_71d06502a93ad345bf738ba8ace8bf9f.txt
new file mode 100644
index 000000000..0a855e066
--- /dev/null
+++ b/test/snapshots/parser/case_when_test/test_0001_case_when_71d06502a93ad345bf738ba8ace8bf9f.txt
@@ -0,0 +1,169 @@
+---
+source: "Parser::CaseWhenTest#test_0001_case/when"
+input: |2-
+<% case variable %>
+
Children
+<% when Integer %>
+
Integer
+<% when String %>
+
String
+<% else %>
+
else
+<% end %>
+---
+@ DocumentNode (location: (1:0)-(10:0))
+└── children: (2 items)
+ ├── @ ERBCaseNode (location: (1:0)-(9:9))
+ │ ├── tag_opening: "<%" (location: (1:0)-(1:2))
+ │ ├── content: " case variable " (location: (1:2)-(1:17))
+ │ ├── tag_closing: "%>" (location: (1:17)-(1:19))
+ │ ├── children: (3 items)
+ │ │ ├── @ HTMLTextNode (location: (1:19)-(2:2))
+ │ │ │ └── content: "\n "
+ │ │ │
+ │ │ ├── @ HTMLElementNode (location: (2:2)-(2:19))
+ │ │ │ ├── open_tag:
+ │ │ │ │ └── @ HTMLOpenTagNode (location: (2:2)-(2:6))
+ │ │ │ │ ├── tag_opening: "<" (location: (2:2)-(2:3))
+ │ │ │ │ ├── tag_name: "h1" (location: (2:3)-(2:5))
+ │ │ │ │ ├── tag_closing: ">" (location: (2:5)-(2:6))
+ │ │ │ │ ├── children: []
+ │ │ │ │ └── is_void: false
+ │ │ │ │
+ │ │ │ ├── tag_name: "h1" (location: (2:3)-(2:5))
+ │ │ │ ├── body: (1 item)
+ │ │ │ │ └── @ HTMLTextNode (location: (2:6)-(2:14))
+ │ │ │ │ └── content: "Children"
+ │ │ │ │
+ │ │ │ ├── close_tag:
+ │ │ │ │ └── @ HTMLCloseTagNode (location: (2:14)-(2:19))
+ │ │ │ │ ├── tag_opening: "" (location: (2:14)-(2:16))
+ │ │ │ │ ├── tag_name: "h1" (location: (2:16)-(2:18))
+ │ │ │ │ ├── children: []
+ │ │ │ │ └── tag_closing: ">" (location: (2:18)-(2:19))
+ │ │ │ │
+ │ │ │ ├── is_void: false
+ │ │ │ └── source: "HTML"
+ │ │ │
+ │ │ └── @ HTMLTextNode (location: (2:19)-(3:0))
+ │ │ └── content: "\n"
+ │ │
+ │ ├── conditions: (2 items)
+ │ │ ├── @ ERBWhenNode (location: (3:0)-(3:18))
+ │ │ │ ├── tag_opening: "<%" (location: (3:0)-(3:2))
+ │ │ │ ├── content: " when Integer " (location: (3:2)-(3:16))
+ │ │ │ ├── tag_closing: "%>" (location: (3:16)-(3:18))
+ │ │ │ └── statements: (3 items)
+ │ │ │ ├── @ HTMLTextNode (location: (3:18)-(4:2))
+ │ │ │ │ └── content: "\n "
+ │ │ │ │
+ │ │ │ ├── @ HTMLElementNode (location: (4:2)-(4:18))
+ │ │ │ │ ├── open_tag:
+ │ │ │ │ │ └── @ HTMLOpenTagNode (location: (4:2)-(4:6))
+ │ │ │ │ │ ├── tag_opening: "<" (location: (4:2)-(4:3))
+ │ │ │ │ │ ├── tag_name: "h1" (location: (4:3)-(4:5))
+ │ │ │ │ │ ├── tag_closing: ">" (location: (4:5)-(4:6))
+ │ │ │ │ │ ├── children: []
+ │ │ │ │ │ └── is_void: false
+ │ │ │ │ │
+ │ │ │ │ ├── tag_name: "h1" (location: (4:3)-(4:5))
+ │ │ │ │ ├── body: (1 item)
+ │ │ │ │ │ └── @ HTMLTextNode (location: (4:6)-(4:13))
+ │ │ │ │ │ └── content: "Integer"
+ │ │ │ │ │
+ │ │ │ │ ├── close_tag:
+ │ │ │ │ │ └── @ HTMLCloseTagNode (location: (4:13)-(4:18))
+ │ │ │ │ │ ├── tag_opening: "" (location: (4:13)-(4:15))
+ │ │ │ │ │ ├── tag_name: "h1" (location: (4:15)-(4:17))
+ │ │ │ │ │ ├── children: []
+ │ │ │ │ │ └── tag_closing: ">" (location: (4:17)-(4:18))
+ │ │ │ │ │
+ │ │ │ │ ├── is_void: false
+ │ │ │ │ └── source: "HTML"
+ │ │ │ │
+ │ │ │ └── @ HTMLTextNode (location: (4:18)-(5:0))
+ │ │ │ └── content: "\n"
+ │ │ │
+ │ │ │
+ │ │ └── @ ERBWhenNode (location: (5:0)-(5:17))
+ │ │ ├── tag_opening: "<%" (location: (5:0)-(5:2))
+ │ │ ├── content: " when String " (location: (5:2)-(5:15))
+ │ │ ├── tag_closing: "%>" (location: (5:15)-(5:17))
+ │ │ └── statements: (3 items)
+ │ │ ├── @ HTMLTextNode (location: (5:17)-(6:2))
+ │ │ │ └── content: "\n "
+ │ │ │
+ │ │ ├── @ HTMLElementNode (location: (6:2)-(6:17))
+ │ │ │ ├── open_tag:
+ │ │ │ │ └── @ HTMLOpenTagNode (location: (6:2)-(6:6))
+ │ │ │ │ ├── tag_opening: "<" (location: (6:2)-(6:3))
+ │ │ │ │ ├── tag_name: "h1" (location: (6:3)-(6:5))
+ │ │ │ │ ├── tag_closing: ">" (location: (6:5)-(6:6))
+ │ │ │ │ ├── children: []
+ │ │ │ │ └── is_void: false
+ │ │ │ │
+ │ │ │ ├── tag_name: "h1" (location: (6:3)-(6:5))
+ │ │ │ ├── body: (1 item)
+ │ │ │ │ └── @ HTMLTextNode (location: (6:6)-(6:12))
+ │ │ │ │ └── content: "String"
+ │ │ │ │
+ │ │ │ ├── close_tag:
+ │ │ │ │ └── @ HTMLCloseTagNode (location: (6:12)-(6:17))
+ │ │ │ │ ├── tag_opening: "" (location: (6:12)-(6:14))
+ │ │ │ │ ├── tag_name: "h1" (location: (6:14)-(6:16))
+ │ │ │ │ ├── children: []
+ │ │ │ │ └── tag_closing: ">" (location: (6:16)-(6:17))
+ │ │ │ │
+ │ │ │ ├── is_void: false
+ │ │ │ └── source: "HTML"
+ │ │ │
+ │ │ └── @ HTMLTextNode (location: (6:17)-(7:0))
+ │ │ └── content: "\n"
+ │ │
+ │ │
+ │ ├── else_clause:
+ │ │ └── @ ERBElseNode (location: (7:0)-(7:10))
+ │ │ ├── tag_opening: "<%" (location: (7:0)-(7:2))
+ │ │ ├── content: " else " (location: (7:2)-(7:8))
+ │ │ ├── tag_closing: "%>" (location: (7:8)-(7:10))
+ │ │ └── statements: (3 items)
+ │ │ ├── @ HTMLTextNode (location: (7:10)-(8:2))
+ │ │ │ └── content: "\n "
+ │ │ │
+ │ │ ├── @ HTMLElementNode (location: (8:2)-(8:15))
+ │ │ │ ├── open_tag:
+ │ │ │ │ └── @ HTMLOpenTagNode (location: (8:2)-(8:6))
+ │ │ │ │ ├── tag_opening: "<" (location: (8:2)-(8:3))
+ │ │ │ │ ├── tag_name: "h1" (location: (8:3)-(8:5))
+ │ │ │ │ ├── tag_closing: ">" (location: (8:5)-(8:6))
+ │ │ │ │ ├── children: []
+ │ │ │ │ └── is_void: false
+ │ │ │ │
+ │ │ │ ├── tag_name: "h1" (location: (8:3)-(8:5))
+ │ │ │ ├── body: (1 item)
+ │ │ │ │ └── @ HTMLTextNode (location: (8:6)-(8:10))
+ │ │ │ │ └── content: "else"
+ │ │ │ │
+ │ │ │ ├── close_tag:
+ │ │ │ │ └── @ HTMLCloseTagNode (location: (8:10)-(8:15))
+ │ │ │ │ ├── tag_opening: "" (location: (8:10)-(8:12))
+ │ │ │ │ ├── tag_name: "h1" (location: (8:12)-(8:14))
+ │ │ │ │ ├── children: []
+ │ │ │ │ └── tag_closing: ">" (location: (8:14)-(8:15))
+ │ │ │ │
+ │ │ │ ├── is_void: false
+ │ │ │ └── source: "HTML"
+ │ │ │
+ │ │ └── @ HTMLTextNode (location: (8:15)-(9:0))
+ │ │ └── content: "\n"
+ │ │
+ │ │
+ │ └── end_node:
+ │ └── @ ERBEndNode (location: (9:0)-(9:9))
+ │ ├── tag_opening: "<%" (location: (9:0)-(9:2))
+ │ ├── content: " end " (location: (9:2)-(9:7))
+ │ └── tag_closing: "%>" (location: (9:7)-(9:9))
+ │
+ │
+ └── @ HTMLTextNode (location: (9:9)-(10:0))
+ └── content: "\n"
\ No newline at end of file
diff --git a/test/snapshots/parser/cdata_test/test_0009_CDATA_with_complex_ERB_2c2d90415d057b7acbff8136b9e5e8bf.txt b/test/snapshots/parser/cdata_test/test_0009_CDATA_with_complex_ERB_2c2d90415d057b7acbff8136b9e5e8bf.txt
index fde3a42e2..f58882376 100644
--- a/test/snapshots/parser/cdata_test/test_0009_CDATA_with_complex_ERB_2c2d90415d057b7acbff8136b9e5e8bf.txt
+++ b/test/snapshots/parser/cdata_test/test_0009_CDATA_with_complex_ERB_2c2d90415d057b7acbff8136b9e5e8bf.txt
@@ -11,36 +11,35 @@ input: |2-
└── children: (2 items)
├── @ CDATANode (location: (1:0)-(5:3))
│ ├── tag_opening: "" (location: (2:19)-(2:21))
- │ │ │ ├── parsed: true
- │ │ │ └── valid: false
+ │ │ │ ├── statements: (3 items)
+ │ │ │ │ ├── @ LiteralNode (location: (2:21)-(3:4))
+ │ │ │ │ │ └── content: "\n "
+ │ │ │ │ │
+ │ │ │ │ ├── @ ERBContentNode (location: (3:4)-(3:19))
+ │ │ │ │ │ ├── tag_opening: "<%=" (location: (3:4)-(3:7))
+ │ │ │ │ │ ├── content: " @content " (location: (3:7)-(3:17))
+ │ │ │ │ │ ├── tag_closing: "%>" (location: (3:17)-(3:19))
+ │ │ │ │ │ ├── parsed: true
+ │ │ │ │ │ └── valid: true
+ │ │ │ │ │
+ │ │ │ │ └── @ LiteralNode (location: (3:19)-(4:2))
+ │ │ │ │ └── content: "\n "
+ │ │ │ │
+ │ │ │ ├── subsequent: ∅
+ │ │ │ └── end_node:
+ │ │ │ └── @ ERBEndNode (location: (4:2)-(4:11))
+ │ │ │ ├── tag_opening: "<%" (location: (4:2)-(4:4))
+ │ │ │ ├── content: " end " (location: (4:4)-(4:9))
+ │ │ │ └── tag_closing: "%>" (location: (4:9)-(4:11))
│ │ │
- │ │ ├── @ LiteralNode (location: (2:21)-(3:4))
- │ │ │ └── content: "\n "
- │ │ │
- │ │ ├── @ ERBContentNode (location: (3:4)-(3:19))
- │ │ │ ├── tag_opening: "<%=" (location: (3:4)-(3:7))
- │ │ │ ├── content: " @content " (location: (3:7)-(3:17))
- │ │ │ ├── tag_closing: "%>" (location: (3:17)-(3:19))
- │ │ │ ├── parsed: true
- │ │ │ └── valid: true
- │ │ │
- │ │ ├── @ LiteralNode (location: (3:19)-(4:2))
- │ │ │ └── content: "\n "
- │ │ │
- │ │ ├── @ ERBContentNode (location: (4:2)-(4:11))
- │ │ │ ├── tag_opening: "<%" (location: (4:2)-(4:4))
- │ │ │ ├── content: " end " (location: (4:4)-(4:9))
- │ │ │ ├── tag_closing: "%>" (location: (4:9)-(4:11))
- │ │ │ ├── parsed: true
- │ │ │ └── valid: false
│ │ │
│ │ └── @ LiteralNode (location: (4:11)-(5:0))
│ │ └── content: "\n"
diff --git a/test/snapshots/parser/cdata_test/test_0017_CDATA_with_ERB_loop_e0b9e9e369a74b4d48962fb7540684ff.txt b/test/snapshots/parser/cdata_test/test_0017_CDATA_with_ERB_loop_e0b9e9e369a74b4d48962fb7540684ff.txt
index dacf5ef2d..a45a217e0 100644
--- a/test/snapshots/parser/cdata_test/test_0017_CDATA_with_ERB_loop_e0b9e9e369a74b4d48962fb7540684ff.txt
+++ b/test/snapshots/parser/cdata_test/test_0017_CDATA_with_ERB_loop_e0b9e9e369a74b4d48962fb7540684ff.txt
@@ -11,36 +11,34 @@ input: |2-
└── children: (2 items)
├── @ CDATANode (location: (1:0)-(5:3))
│ ├── tag_opening: "" (location: (2:27)-(2:29))
- │ │ │ ├── parsed: true
- │ │ │ └── valid: false
+ │ │ │ ├── body: (3 items)
+ │ │ │ │ ├── @ LiteralNode (location: (2:29)-(3:10))
+ │ │ │ │ │ └── content: "\n
- "
+ │ │ │ │ │
+ │ │ │ │ ├── @ ERBContentNode (location: (3:10)-(3:26))
+ │ │ │ │ │ ├── tag_opening: "<%=" (location: (3:10)-(3:13))
+ │ │ │ │ │ ├── content: " item.name " (location: (3:13)-(3:24))
+ │ │ │ │ │ ├── tag_closing: "%>" (location: (3:24)-(3:26))
+ │ │ │ │ │ ├── parsed: true
+ │ │ │ │ │ └── valid: true
+ │ │ │ │ │
+ │ │ │ │ └── @ LiteralNode (location: (3:26)-(4:2))
+ │ │ │ │ └── content: "
\n "
+ │ │ │ │
+ │ │ │ └── end_node:
+ │ │ │ └── @ ERBEndNode (location: (4:2)-(4:11))
+ │ │ │ ├── tag_opening: "<%" (location: (4:2)-(4:4))
+ │ │ │ ├── content: " end " (location: (4:4)-(4:9))
+ │ │ │ └── tag_closing: "%>" (location: (4:9)-(4:11))
│ │ │
- │ │ ├── @ LiteralNode (location: (2:29)-(3:10))
- │ │ │ └── content: "\n
- "
- │ │ │
- │ │ ├── @ ERBContentNode (location: (3:10)-(3:26))
- │ │ │ ├── tag_opening: "<%=" (location: (3:10)-(3:13))
- │ │ │ ├── content: " item.name " (location: (3:13)-(3:24))
- │ │ │ ├── tag_closing: "%>" (location: (3:24)-(3:26))
- │ │ │ ├── parsed: true
- │ │ │ └── valid: true
- │ │ │
- │ │ ├── @ LiteralNode (location: (3:26)-(4:2))
- │ │ │ └── content: "
\n "
- │ │ │
- │ │ ├── @ ERBContentNode (location: (4:2)-(4:11))
- │ │ │ ├── tag_opening: "<%" (location: (4:2)-(4:4))
- │ │ │ ├── content: " end " (location: (4:4)-(4:9))
- │ │ │ ├── tag_closing: "%>" (location: (4:9)-(4:11))
- │ │ │ ├── parsed: true
- │ │ │ └── valid: false
│ │ │
│ │ └── @ LiteralNode (location: (4:11)-(5:0))
│ │ └── content: "\n"
diff --git a/test/snapshots/parser/comments_test/test_0005_HTML_comment_with_if_04813d5ad89aa775065eb87d881ab931.txt b/test/snapshots/parser/comments_test/test_0005_HTML_comment_with_if_04813d5ad89aa775065eb87d881ab931.txt
new file mode 100644
index 000000000..7e6a98fb5
--- /dev/null
+++ b/test/snapshots/parser/comments_test/test_0005_HTML_comment_with_if_04813d5ad89aa775065eb87d881ab931.txt
@@ -0,0 +1,50 @@
+---
+source: "Parser::CommentsTest#test_0005_HTML comment with if"
+input: |2-
+
+---
+@ DocumentNode (location: (1:0)-(6:0))
+└── children: (2 items)
+ ├── @ HTMLCommentNode (location: (1:0)-(5:3))
+ │ ├── comment_start: "" (location: (5:0)-(5:3))
+ │
+ └── @ HTMLTextNode (location: (5:3)-(6:0))
+ └── content: "\n"
\ No newline at end of file
diff --git a/test/snapshots/parser/erb_context_mismatch_test/test_0001_out_of_order_closing_tags_across_ERB_blocks_186de8708f7329b37a560b950c6814bc.txt b/test/snapshots/parser/erb_context_mismatch_test/test_0001_out_of_order_closing_tags_across_ERB_blocks_186de8708f7329b37a560b950c6814bc.txt
new file mode 100644
index 000000000..ffcf2d0d0
--- /dev/null
+++ b/test/snapshots/parser/erb_context_mismatch_test/test_0001_out_of_order_closing_tags_across_ERB_blocks_186de8708f7329b37a560b950c6814bc.txt
@@ -0,0 +1,175 @@
+---
+source: "Parser::ERBContextMismatchTest#test_0001_out of order closing tags across ERB blocks"
+input: |2-
+
+
+
+ <%= render CardComponent.new do |card| %>
+
+
+ <% end %>
+
+
+---
+@ DocumentNode (location: (1:0)-(10:0))
+└── children: (4 items)
+ ├── @ HTMLOpenTagNode (location: (1:0)-(1:22))
+ │ ├── errors: (1 error)
+ │ │ └── @ MissingClosingTagError (location: (1:0)-(1:22))
+ │ │ ├── message: "Opening tag `
` at (1:1) doesn't have a matching closing tag `
` in the same scope."
+ │ │ └── opening_tag: "div" (location: (1:1)-(1:4))
+ │ │
+ │ ├── tag_opening: "<" (location: (1:0)-(1:1))
+ │ ├── tag_name: "div" (location: (1:1)-(1:4))
+ │ ├── tag_closing: ">" (location: (1:21)-(1:22))
+ │ ├── children: (1 item)
+ │ │ └── @ HTMLAttributeNode (location: (1:5)-(1:21))
+ │ │ ├── name:
+ │ │ │ └── @ HTMLAttributeNameNode (location: (1:5)-(1:10))
+ │ │ │ └── children: (1 item)
+ │ │ │ └── @ LiteralNode (location: (1:5)-(1:10))
+ │ │ │ └── content: "class"
+ │ │ │
+ │ │ │
+ │ │ ├── equals: "=" (location: (1:10)-(1:11))
+ │ │ └── value:
+ │ │ └── @ HTMLAttributeValueNode (location: (1:11)-(1:21))
+ │ │ ├── open_quote: """ (location: (1:11)-(1:12))
+ │ │ ├── children: (1 item)
+ │ │ │ └── @ LiteralNode (location: (1:12)-(1:20))
+ │ │ │ └── content: "h-screen"
+ │ │ │
+ │ │ ├── close_quote: """ (location: (1:20)-(1:21))
+ │ │ └── quoted: true
+ │ │
+ │ │
+ │ └── is_void: false
+ │
+ ├── @ HTMLTextNode (location: (1:22)-(2:2))
+ │ └── content: "\n "
+ │
+ ├── @ HTMLElementNode (location: (2:2)-(9:6))
+ │ ├── open_tag:
+ │ │ └── @ HTMLOpenTagNode (location: (2:2)-(2:30))
+ │ │ ├── tag_opening: "<" (location: (2:2)-(2:3))
+ │ │ ├── tag_name: "div" (location: (2:3)-(2:6))
+ │ │ ├── tag_closing: ">" (location: (2:29)-(2:30))
+ │ │ ├── children: (1 item)
+ │ │ │ └── @ HTMLAttributeNode (location: (2:7)-(2:29))
+ │ │ │ ├── name:
+ │ │ │ │ └── @ HTMLAttributeNameNode (location: (2:7)-(2:12))
+ │ │ │ │ └── children: (1 item)
+ │ │ │ │ └── @ LiteralNode (location: (2:7)-(2:12))
+ │ │ │ │ └── content: "class"
+ │ │ │ │
+ │ │ │ │
+ │ │ │ ├── equals: "=" (location: (2:12)-(2:13))
+ │ │ │ └── value:
+ │ │ │ └── @ HTMLAttributeValueNode (location: (2:13)-(2:29))
+ │ │ │ ├── open_quote: """ (location: (2:13)-(2:14))
+ │ │ │ ├── children: (1 item)
+ │ │ │ │ └── @ LiteralNode (location: (2:14)-(2:28))
+ │ │ │ │ └── content: "page-container"
+ │ │ │ │
+ │ │ │ ├── close_quote: """ (location: (2:28)-(2:29))
+ │ │ │ └── quoted: true
+ │ │ │
+ │ │ │
+ │ │ └── is_void: false
+ │ │
+ │ ├── tag_name: "div" (location: (2:3)-(2:6))
+ │ ├── body: (3 items)
+ │ │ ├── @ HTMLTextNode (location: (2:30)-(3:4))
+ │ │ │ └── content: "\n "
+ │ │ │
+ │ │ ├── @ HTMLElementNode (location: (3:4)-(8:8))
+ │ │ │ ├── open_tag:
+ │ │ │ │ └── @ HTMLOpenTagNode (location: (3:4)-(3:34))
+ │ │ │ │ ├── tag_opening: "<" (location: (3:4)-(3:5))
+ │ │ │ │ ├── tag_name: "div" (location: (3:5)-(3:8))
+ │ │ │ │ ├── tag_closing: ">" (location: (3:33)-(3:34))
+ │ │ │ │ ├── children: (1 item)
+ │ │ │ │ │ └── @ HTMLAttributeNode (location: (3:9)-(3:33))
+ │ │ │ │ │ ├── name:
+ │ │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (3:9)-(3:14))
+ │ │ │ │ │ │ └── children: (1 item)
+ │ │ │ │ │ │ └── @ LiteralNode (location: (3:9)-(3:14))
+ │ │ │ │ │ │ └── content: "class"
+ │ │ │ │ │ │
+ │ │ │ │ │ │
+ │ │ │ │ │ ├── equals: "=" (location: (3:14)-(3:15))
+ │ │ │ │ │ └── value:
+ │ │ │ │ │ └── @ HTMLAttributeValueNode (location: (3:15)-(3:33))
+ │ │ │ │ │ ├── open_quote: """ (location: (3:15)-(3:16))
+ │ │ │ │ │ ├── children: (1 item)
+ │ │ │ │ │ │ └── @ LiteralNode (location: (3:16)-(3:32))
+ │ │ │ │ │ │ └── content: "max-w-lg mx-auto"
+ │ │ │ │ │ │
+ │ │ │ │ │ ├── close_quote: """ (location: (3:32)-(3:33))
+ │ │ │ │ │ └── quoted: true
+ │ │ │ │ │
+ │ │ │ │ │
+ │ │ │ │ └── is_void: false
+ │ │ │ │
+ │ │ │ ├── tag_name: "div" (location: (3:5)-(3:8))
+ │ │ │ ├── body: (3 items)
+ │ │ │ │ ├── @ HTMLTextNode (location: (3:34)-(4:6))
+ │ │ │ │ │ └── content: "\n "
+ │ │ │ │ │
+ │ │ │ │ ├── @ ERBBlockNode (location: (4:6)-(7:13))
+ │ │ │ │ │ ├── tag_opening: "<%=" (location: (4:6)-(4:9))
+ │ │ │ │ │ ├── content: " render CardComponent.new do |card| " (location: (4:9)-(4:45))
+ │ │ │ │ │ ├── tag_closing: "%>" (location: (4:45)-(4:47))
+ │ │ │ │ │ ├── body: (3 items)
+ │ │ │ │ │ │ ├── @ HTMLTextNode (location: (4:47)-(5:4))
+ │ │ │ │ │ │ │ └── content: "\n "
+ │ │ │ │ │ │ │
+ │ │ │ │ │ │ ├── @ HTMLCloseTagNode (location: (5:4)-(5:10))
+ │ │ │ │ │ │ │ ├── errors: (1 error)
+ │ │ │ │ │ │ │ │ └── @ MissingOpeningTagError (location: (5:4)-(5:10))
+ │ │ │ │ │ │ │ │ ├── message: "Found closing tag `
` at (5:6) without a matching opening tag in the same scope."
+ │ │ │ │ │ │ │ │ └── closing_tag: "div" (location: (5:6)-(5:9))
+ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ ├── tag_opening: "" (location: (5:4)-(5:6))
+ │ │ │ │ │ │ │ ├── tag_name: "div" (location: (5:6)-(5:9))
+ │ │ │ │ │ │ │ ├── children: []
+ │ │ │ │ │ │ │ └── tag_closing: ">" (location: (5:9)-(5:10))
+ │ │ │ │ │ │ │
+ │ │ │ │ │ │ └── @ HTMLTextNode (location: (5:10)-(7:4))
+ │ │ │ │ │ │ └── content: "\n\n "
+ │ │ │ │ │ │
+ │ │ │ │ │ └── end_node:
+ │ │ │ │ │ └── @ ERBEndNode (location: (7:4)-(7:13))
+ │ │ │ │ │ ├── tag_opening: "<%" (location: (7:4)-(7:6))
+ │ │ │ │ │ ├── content: " end " (location: (7:6)-(7:11))
+ │ │ │ │ │ └── tag_closing: "%>" (location: (7:11)-(7:13))
+ │ │ │ │ │
+ │ │ │ │ │
+ │ │ │ │ └── @ HTMLTextNode (location: (7:13)-(8:2))
+ │ │ │ │ └── content: "\n "
+ │ │ │ │
+ │ │ │ ├── close_tag:
+ │ │ │ │ └── @ HTMLCloseTagNode (location: (8:2)-(8:8))
+ │ │ │ │ ├── tag_opening: "" (location: (8:2)-(8:4))
+ │ │ │ │ ├── tag_name: "div" (location: (8:4)-(8:7))
+ │ │ │ │ ├── children: []
+ │ │ │ │ └── tag_closing: ">" (location: (8:7)-(8:8))
+ │ │ │ │
+ │ │ │ ├── is_void: false
+ │ │ │ └── source: "HTML"
+ │ │ │
+ │ │ └── @ HTMLTextNode (location: (8:8)-(9:0))
+ │ │ └── content: "\n"
+ │ │
+ │ ├── close_tag:
+ │ │ └── @ HTMLCloseTagNode (location: (9:0)-(9:6))
+ │ │ ├── tag_opening: "" (location: (9:0)-(9:2))
+ │ │ ├── tag_name: "div" (location: (9:2)-(9:5))
+ │ │ ├── children: []
+ │ │ └── tag_closing: ">" (location: (9:5)-(9:6))
+ │ │
+ │ ├── is_void: false
+ │ └── source: "HTML"
+ │
+ └── @ HTMLTextNode (location: (9:6)-(10:0))
+ └── content: "\n"
\ No newline at end of file
diff --git a/test/snapshots/parser/erb_context_mismatch_test/test_0002_conditionally_opening_tag_then_closing_unconditionally_6d7fbfb1a933a2f8aba9be55b52c0012.txt b/test/snapshots/parser/erb_context_mismatch_test/test_0002_conditionally_opening_tag_then_closing_unconditionally_6d7fbfb1a933a2f8aba9be55b52c0012.txt
new file mode 100644
index 000000000..4c4dc4597
--- /dev/null
+++ b/test/snapshots/parser/erb_context_mismatch_test/test_0002_conditionally_opening_tag_then_closing_unconditionally_6d7fbfb1a933a2f8aba9be55b52c0012.txt
@@ -0,0 +1,124 @@
+---
+source: "Parser::ERBContextMismatchTest#test_0002_conditionally opening tag then closing unconditionally"
+input: |2-
+<% if some_condition %>
+
+<% else %>
+
+<% end %>
+ Content
+
+---
+@ DocumentNode (location: (1:0)-(8:0))
+└── children: (4 items)
+ ├── @ ERBIfNode (location: (1:0)-(5:9))
+ │ ├── tag_opening: "<%" (location: (1:0)-(1:2))
+ │ ├── content: " if some_condition " (location: (1:2)-(1:21))
+ │ ├── tag_closing: "%>" (location: (1:21)-(1:23))
+ │ ├── statements: (3 items)
+ │ │ ├── @ HTMLTextNode (location: (1:23)-(2:2))
+ │ │ │ └── content: "\n "
+ │ │ │
+ │ │ ├── @ HTMLOpenTagNode (location: (2:2)-(2:17))
+ │ │ │ ├── errors: (1 error)
+ │ │ │ │ └── @ MissingClosingTagError (location: (2:2)-(2:17))
+ │ │ │ │ ├── message: "Opening tag `
` at (2:3) doesn't have a matching closing tag `
` in the same scope."
+ │ │ │ │ └── opening_tag: "div" (location: (2:3)-(2:6))
+ │ │ │ │
+ │ │ │ ├── tag_opening: "<" (location: (2:2)-(2:3))
+ │ │ │ ├── tag_name: "div" (location: (2:3)-(2:6))
+ │ │ │ ├── tag_closing: ">" (location: (2:16)-(2:17))
+ │ │ │ ├── children: (1 item)
+ │ │ │ │ └── @ HTMLAttributeNode (location: (2:7)-(2:16))
+ │ │ │ │ ├── name:
+ │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (2:7)-(2:12))
+ │ │ │ │ │ └── children: (1 item)
+ │ │ │ │ │ └── @ LiteralNode (location: (2:7)-(2:12))
+ │ │ │ │ │ └── content: "class"
+ │ │ │ │ │
+ │ │ │ │ │
+ │ │ │ │ ├── equals: "=" (location: (2:12)-(2:13))
+ │ │ │ │ └── value:
+ │ │ │ │ └── @ HTMLAttributeValueNode (location: (2:13)-(2:16))
+ │ │ │ │ ├── open_quote: """ (location: (2:13)-(2:14))
+ │ │ │ │ ├── children: (1 item)
+ │ │ │ │ │ └── @ LiteralNode (location: (2:14)-(2:15))
+ │ │ │ │ │ └── content: "a"
+ │ │ │ │ │
+ │ │ │ │ ├── close_quote: """ (location: (2:15)-(2:16))
+ │ │ │ │ └── quoted: true
+ │ │ │ │
+ │ │ │ │
+ │ │ │ └── is_void: false
+ │ │ │
+ │ │ └── @ HTMLTextNode (location: (2:17)-(3:0))
+ │ │ └── content: "\n"
+ │ │
+ │ ├── subsequent:
+ │ │ └── @ ERBElseNode (location: (3:0)-(5:0))
+ │ │ ├── tag_opening: "<%" (location: (3:0)-(3:2))
+ │ │ ├── content: " else " (location: (3:2)-(3:8))
+ │ │ ├── tag_closing: "%>" (location: (3:8)-(3:10))
+ │ │ └── statements: (3 items)
+ │ │ ├── @ HTMLTextNode (location: (3:10)-(4:2))
+ │ │ │ └── content: "\n "
+ │ │ │
+ │ │ ├── @ HTMLOpenTagNode (location: (4:2)-(4:17))
+ │ │ │ ├── errors: (1 error)
+ │ │ │ │ └── @ MissingClosingTagError (location: (4:2)-(4:17))
+ │ │ │ │ ├── message: "Opening tag `
` at (4:3) doesn't have a matching closing tag `
` in the same scope."
+ │ │ │ │ └── opening_tag: "div" (location: (4:3)-(4:6))
+ │ │ │ │
+ │ │ │ ├── tag_opening: "<" (location: (4:2)-(4:3))
+ │ │ │ ├── tag_name: "div" (location: (4:3)-(4:6))
+ │ │ │ ├── tag_closing: ">" (location: (4:16)-(4:17))
+ │ │ │ ├── children: (1 item)
+ │ │ │ │ └── @ HTMLAttributeNode (location: (4:7)-(4:16))
+ │ │ │ │ ├── name:
+ │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (4:7)-(4:12))
+ │ │ │ │ │ └── children: (1 item)
+ │ │ │ │ │ └── @ LiteralNode (location: (4:7)-(4:12))
+ │ │ │ │ │ └── content: "class"
+ │ │ │ │ │
+ │ │ │ │ │
+ │ │ │ │ ├── equals: "=" (location: (4:12)-(4:13))
+ │ │ │ │ └── value:
+ │ │ │ │ └── @ HTMLAttributeValueNode (location: (4:13)-(4:16))
+ │ │ │ │ ├── open_quote: """ (location: (4:13)-(4:14))
+ │ │ │ │ ├── children: (1 item)
+ │ │ │ │ │ └── @ LiteralNode (location: (4:14)-(4:15))
+ │ │ │ │ │ └── content: "b"
+ │ │ │ │ │
+ │ │ │ │ ├── close_quote: """ (location: (4:15)-(4:16))
+ │ │ │ │ └── quoted: true
+ │ │ │ │
+ │ │ │ │
+ │ │ │ └── is_void: false
+ │ │ │
+ │ │ └── @ HTMLTextNode (location: (4:17)-(5:0))
+ │ │ └── content: "\n"
+ │ │
+ │ │
+ │ └── end_node:
+ │ └── @ ERBEndNode (location: (5:0)-(5:9))
+ │ ├── tag_opening: "<%" (location: (5:0)-(5:2))
+ │ ├── content: " end " (location: (5:2)-(5:7))
+ │ └── tag_closing: "%>" (location: (5:7)-(5:9))
+ │
+ │
+ ├── @ HTMLTextNode (location: (5:9)-(7:0))
+ │ └── content: "\n Content\n"
+ │
+ ├── @ HTMLCloseTagNode (location: (7:0)-(7:6))
+ │ ├── errors: (1 error)
+ │ │ └── @ MissingOpeningTagError (location: (7:0)-(7:6))
+ │ │ ├── message: "Found closing tag `
` at (7:2) without a matching opening tag in the same scope."
+ │ │ └── closing_tag: "div" (location: (7:2)-(7:5))
+ │ │
+ │ ├── tag_opening: "" (location: (7:0)-(7:2))
+ │ ├── tag_name: "div" (location: (7:2)-(7:5))
+ │ ├── children: []
+ │ └── tag_closing: ">" (location: (7:5)-(7:6))
+ │
+ └── @ HTMLTextNode (location: (7:6)-(8:0))
+ └── content: "\n"
\ No newline at end of file
diff --git a/test/snapshots/parser/erb_context_mismatch_test/test_0003_opening_and_closing_tag_in_different_if_blocks_a6d5461489ddfa85081a5449445cef14.txt b/test/snapshots/parser/erb_context_mismatch_test/test_0003_opening_and_closing_tag_in_different_if_blocks_a6d5461489ddfa85081a5449445cef14.txt
new file mode 100644
index 000000000..1fa5826a8
--- /dev/null
+++ b/test/snapshots/parser/erb_context_mismatch_test/test_0003_opening_and_closing_tag_in_different_if_blocks_a6d5461489ddfa85081a5449445cef14.txt
@@ -0,0 +1,108 @@
+---
+source: "Parser::ERBContextMismatchTest#test_0003_opening and closing tag in different if blocks"
+input: |2-
+<% if wrap_in_dialog? %>
+
+<% end %>
+
+Stuff
+
+<% if wrap_in_dialog? %>
+
+<% end %>
+---
+@ DocumentNode (location: (1:0)-(10:0))
+└── children: (6 items)
+ ├── @ ERBIfNode (location: (1:0)-(3:9))
+ │ ├── tag_opening: "<%" (location: (1:0)-(1:2))
+ │ ├── content: " if wrap_in_dialog? " (location: (1:2)-(1:22))
+ │ ├── tag_closing: "%>" (location: (1:22)-(1:24))
+ │ ├── statements: (3 items)
+ │ │ ├── @ HTMLTextNode (location: (1:24)-(2:2))
+ │ │ │ └── content: "\n "
+ │ │ │
+ │ │ ├── @ HTMLOpenTagNode (location: (2:2)-(2:10))
+ │ │ │ ├── errors: (1 error)
+ │ │ │ │ └── @ MissingClosingTagError (location: (2:2)-(2:10))
+ │ │ │ │ ├── message: "Opening tag `
` at (2:3) doesn't have a matching closing tag ` ` in the same scope."
+ │ │ │ │ └── opening_tag: "dialog" (location: (2:3)-(2:9))
+ │ │ │ │
+ │ │ │ ├── tag_opening: "<" (location: (2:2)-(2:3))
+ │ │ │ ├── tag_name: "dialog" (location: (2:3)-(2:9))
+ │ │ │ ├── tag_closing: ">" (location: (2:9)-(2:10))
+ │ │ │ ├── children: []
+ │ │ │ └── is_void: false
+ │ │ │
+ │ │ └── @ HTMLTextNode (location: (2:10)-(3:0))
+ │ │ └── content: "\n"
+ │ │
+ │ ├── subsequent: ∅
+ │ └── end_node:
+ │ └── @ ERBEndNode (location: (3:0)-(3:9))
+ │ ├── tag_opening: "<%" (location: (3:0)-(3:2))
+ │ ├── content: " end " (location: (3:2)-(3:7))
+ │ └── tag_closing: "%>" (location: (3:7)-(3:9))
+ │
+ │
+ ├── @ HTMLTextNode (location: (3:9)-(5:0))
+ │ └── content: "\n\n"
+ │
+ ├── @ HTMLElementNode (location: (5:0)-(5:16))
+ │ ├── open_tag:
+ │ │ └── @ HTMLOpenTagNode (location: (5:0)-(5:5))
+ │ │ ├── tag_opening: "<" (location: (5:0)-(5:1))
+ │ │ ├── tag_name: "div" (location: (5:1)-(5:4))
+ │ │ ├── tag_closing: ">" (location: (5:4)-(5:5))
+ │ │ ├── children: []
+ │ │ └── is_void: false
+ │ │
+ │ ├── tag_name: "div" (location: (5:1)-(5:4))
+ │ ├── body: (1 item)
+ │ │ └── @ HTMLTextNode (location: (5:5)-(5:10))
+ │ │ └── content: "Stuff"
+ │ │
+ │ ├── close_tag:
+ │ │ └── @ HTMLCloseTagNode (location: (5:10)-(5:16))
+ │ │ ├── tag_opening: "" (location: (5:10)-(5:12))
+ │ │ ├── tag_name: "div" (location: (5:12)-(5:15))
+ │ │ ├── children: []
+ │ │ └── tag_closing: ">" (location: (5:15)-(5:16))
+ │ │
+ │ ├── is_void: false
+ │ └── source: "HTML"
+ │
+ ├── @ HTMLTextNode (location: (5:16)-(7:0))
+ │ └── content: "\n\n"
+ │
+ ├── @ ERBIfNode (location: (7:0)-(9:9))
+ │ ├── tag_opening: "<%" (location: (7:0)-(7:2))
+ │ ├── content: " if wrap_in_dialog? " (location: (7:2)-(7:22))
+ │ ├── tag_closing: "%>" (location: (7:22)-(7:24))
+ │ ├── statements: (3 items)
+ │ │ ├── @ HTMLTextNode (location: (7:24)-(8:2))
+ │ │ │ └── content: "\n "
+ │ │ │
+ │ │ ├── @ HTMLCloseTagNode (location: (8:2)-(8:11))
+ │ │ │ ├── errors: (1 error)
+ │ │ │ │ └── @ MissingOpeningTagError (location: (8:2)-(8:11))
+ │ │ │ │ ├── message: "Found closing tag `` at (8:4) without a matching opening tag in the same scope."
+ │ │ │ │ └── closing_tag: "dialog" (location: (8:4)-(8:10))
+ │ │ │ │
+ │ │ │ ├── tag_opening: "" (location: (8:2)-(8:4))
+ │ │ │ ├── tag_name: "dialog" (location: (8:4)-(8:10))
+ │ │ │ ├── children: []
+ │ │ │ └── tag_closing: ">" (location: (8:10)-(8:11))
+ │ │ │
+ │ │ └── @ HTMLTextNode (location: (8:11)-(9:0))
+ │ │ └── content: "\n"
+ │ │
+ │ ├── subsequent: ∅
+ │ └── end_node:
+ │ └── @ ERBEndNode (location: (9:0)-(9:9))
+ │ ├── tag_opening: "<%" (location: (9:0)-(9:2))
+ │ ├── content: " end " (location: (9:2)-(9:7))
+ │ └── tag_closing: "%>" (location: (9:7)-(9:9))
+ │
+ │
+ └── @ HTMLTextNode (location: (9:9)-(10:0))
+ └── content: "\n"
\ No newline at end of file
diff --git a/test/snapshots/parser/erb_context_mismatch_test/test_0004_tag_opened_in_elsif_closed_outside_conditional_ff6b90e6b68b015927ad4554dc97fd8e.txt b/test/snapshots/parser/erb_context_mismatch_test/test_0004_tag_opened_in_elsif_closed_outside_conditional_ff6b90e6b68b015927ad4554dc97fd8e.txt
new file mode 100644
index 000000000..9d5d3703d
--- /dev/null
+++ b/test/snapshots/parser/erb_context_mismatch_test/test_0004_tag_opened_in_elsif_closed_outside_conditional_ff6b90e6b68b015927ad4554dc97fd8e.txt
@@ -0,0 +1,333 @@
+---
+source: "Parser::ERBContextMismatchTest#test_0004_tag opened in elsif closed outside conditional"
+input: |2-
+
+
+ <% if magic == :foo %>
+
+ foo
+ <% elsif magic == :bar %>
+
+ bar
+ <% else %>
+
+ DEFAULT
+ <% end %>
+
+
+
+---
+@ DocumentNode (location: (1:0)-(16:0))
+└── children: (2 items)
+ ├── @ HTMLElementNode (location: (1:0)-(15:6))
+ │ ├── open_tag:
+ │ │ └── @ HTMLOpenTagNode (location: (1:0)-(1:5))
+ │ │ ├── tag_opening: "<" (location: (1:0)-(1:1))
+ │ │ ├── tag_name: "nav" (location: (1:1)-(1:4))
+ │ │ ├── tag_closing: ">" (location: (1:4)-(1:5))
+ │ │ ├── children: []
+ │ │ └── is_void: false
+ │ │
+ │ ├── tag_name: "nav" (location: (1:1)-(1:4))
+ │ ├── body: (3 items)
+ │ │ ├── @ HTMLTextNode (location: (1:5)-(2:2))
+ │ │ │ └── content: "\n "
+ │ │ │
+ │ │ ├── @ HTMLElementNode (location: (2:2)-(14:7))
+ │ │ │ ├── open_tag:
+ │ │ │ │ └── @ HTMLOpenTagNode (location: (2:2)-(2:6))
+ │ │ │ │ ├── tag_opening: "<" (location: (2:2)-(2:3))
+ │ │ │ │ ├── tag_name: "ul" (location: (2:3)-(2:5))
+ │ │ │ │ ├── tag_closing: ">" (location: (2:5)-(2:6))
+ │ │ │ │ ├── children: []
+ │ │ │ │ └── is_void: false
+ │ │ │ │
+ │ │ │ ├── tag_name: "ul" (location: (2:3)-(2:5))
+ │ │ │ ├── body: (5 items)
+ │ │ │ │ ├── @ HTMLTextNode (location: (2:6)-(3:4))
+ │ │ │ │ │ └── content: "\n "
+ │ │ │ │ │
+ │ │ │ │ ├── @ ERBIfNode (location: (3:4)-(12:13))
+ │ │ │ │ │ ├── tag_opening: "<%" (location: (3:4)-(3:6))
+ │ │ │ │ │ ├── content: " if magic == :foo " (location: (3:6)-(3:24))
+ │ │ │ │ │ ├── tag_closing: "%>" (location: (3:24)-(3:26))
+ │ │ │ │ │ ├── statements: (5 items)
+ │ │ │ │ │ │ ├── @ HTMLTextNode (location: (3:26)-(4:6))
+ │ │ │ │ │ │ │ └── content: "\n "
+ │ │ │ │ │ │ │
+ │ │ │ │ │ │ ├── @ HTMLOpenTagNode (location: (4:6)-(4:22))
+ │ │ │ │ │ │ │ ├── errors: (1 error)
+ │ │ │ │ │ │ │ │ └── @ MissingClosingTagError (location: (4:6)-(4:22))
+ │ │ │ │ │ │ │ │ ├── message: "Opening tag `
` at (4:7) doesn't have a matching closing tag ` ` in the same scope."
+ │ │ │ │ │ │ │ │ └── opening_tag: "li" (location: (4:7)-(4:9))
+ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ ├── tag_opening: "<" (location: (4:6)-(4:7))
+ │ │ │ │ │ │ │ ├── tag_name: "li" (location: (4:7)-(4:9))
+ │ │ │ │ │ │ │ ├── tag_closing: ">" (location: (4:21)-(4:22))
+ │ │ │ │ │ │ │ ├── children: (1 item)
+ │ │ │ │ │ │ │ │ └── @ HTMLAttributeNode (location: (4:10)-(4:21))
+ │ │ │ │ │ │ │ │ ├── name:
+ │ │ │ │ │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (4:10)-(4:15))
+ │ │ │ │ │ │ │ │ │ └── children: (1 item)
+ │ │ │ │ │ │ │ │ │ └── @ LiteralNode (location: (4:10)-(4:15))
+ │ │ │ │ │ │ │ │ │ └── content: "class"
+ │ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │ ├── equals: "=" (location: (4:15)-(4:16))
+ │ │ │ │ │ │ │ │ └── value:
+ │ │ │ │ │ │ │ │ └── @ HTMLAttributeValueNode (location: (4:16)-(4:21))
+ │ │ │ │ │ │ │ │ ├── open_quote: """ (location: (4:16)-(4:17))
+ │ │ │ │ │ │ │ │ ├── children: (1 item)
+ │ │ │ │ │ │ │ │ │ └── @ LiteralNode (location: (4:17)-(4:20))
+ │ │ │ │ │ │ │ │ │ └── content: "foo"
+ │ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │ ├── close_quote: """ (location: (4:20)-(4:21))
+ │ │ │ │ │ │ │ │ └── quoted: true
+ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ └── is_void: false
+ │ │ │ │ │ │ │
+ │ │ │ │ │ │ ├── @ HTMLTextNode (location: (4:22)-(5:8))
+ │ │ │ │ │ │ │ └── content: "\n "
+ │ │ │ │ │ │ │
+ │ │ │ │ │ │ ├── @ HTMLElementNode (location: (5:8)-(5:29))
+ │ │ │ │ │ │ │ ├── open_tag:
+ │ │ │ │ │ │ │ │ └── @ HTMLOpenTagNode (location: (5:8)-(5:22))
+ │ │ │ │ │ │ │ │ ├── tag_opening: "<" (location: (5:8)-(5:9))
+ │ │ │ │ │ │ │ │ ├── tag_name: "a" (location: (5:9)-(5:10))
+ │ │ │ │ │ │ │ │ ├── tag_closing: ">" (location: (5:21)-(5:22))
+ │ │ │ │ │ │ │ │ ├── children: (1 item)
+ │ │ │ │ │ │ │ │ │ └── @ HTMLAttributeNode (location: (5:11)-(5:21))
+ │ │ │ │ │ │ │ │ │ ├── name:
+ │ │ │ │ │ │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (5:11)-(5:15))
+ │ │ │ │ │ │ │ │ │ │ └── children: (1 item)
+ │ │ │ │ │ │ │ │ │ │ └── @ LiteralNode (location: (5:11)-(5:15))
+ │ │ │ │ │ │ │ │ │ │ └── content: "href"
+ │ │ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │ │ ├── equals: "=" (location: (5:15)-(5:16))
+ │ │ │ │ │ │ │ │ │ └── value:
+ │ │ │ │ │ │ │ │ │ └── @ HTMLAttributeValueNode (location: (5:16)-(5:21))
+ │ │ │ │ │ │ │ │ │ ├── open_quote: """ (location: (5:16)-(5:17))
+ │ │ │ │ │ │ │ │ │ ├── children: (1 item)
+ │ │ │ │ │ │ │ │ │ │ └── @ LiteralNode (location: (5:17)-(5:20))
+ │ │ │ │ │ │ │ │ │ │ └── content: "foo"
+ │ │ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │ │ ├── close_quote: """ (location: (5:20)-(5:21))
+ │ │ │ │ │ │ │ │ │ └── quoted: true
+ │ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │ └── is_void: false
+ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ ├── tag_name: "a" (location: (5:9)-(5:10))
+ │ │ │ │ │ │ │ ├── body: (1 item)
+ │ │ │ │ │ │ │ │ └── @ HTMLTextNode (location: (5:22)-(5:25))
+ │ │ │ │ │ │ │ │ └── content: "foo"
+ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ ├── close_tag:
+ │ │ │ │ │ │ │ │ └── @ HTMLCloseTagNode (location: (5:25)-(5:29))
+ │ │ │ │ │ │ │ │ ├── tag_opening: "" (location: (5:25)-(5:27))
+ │ │ │ │ │ │ │ │ ├── tag_name: "a" (location: (5:27)-(5:28))
+ │ │ │ │ │ │ │ │ ├── children: []
+ │ │ │ │ │ │ │ │ └── tag_closing: ">" (location: (5:28)-(5:29))
+ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ ├── is_void: false
+ │ │ │ │ │ │ │ └── source: "HTML"
+ │ │ │ │ │ │ │
+ │ │ │ │ │ │ └── @ HTMLTextNode (location: (5:29)-(6:4))
+ │ │ │ │ │ │ └── content: "\n "
+ │ │ │ │ │ │
+ │ │ │ │ │ ├── subsequent:
+ │ │ │ │ │ │ └── @ ERBIfNode (location: (6:4)-(9:4))
+ │ │ │ │ │ │ ├── tag_opening: "<%" (location: (6:4)-(6:6))
+ │ │ │ │ │ │ ├── content: " elsif magic == :bar " (location: (6:6)-(6:27))
+ │ │ │ │ │ │ ├── tag_closing: "%>" (location: (6:27)-(6:29))
+ │ │ │ │ │ │ ├── statements: (5 items)
+ │ │ │ │ │ │ │ ├── @ HTMLTextNode (location: (6:29)-(7:6))
+ │ │ │ │ │ │ │ │ └── content: "\n "
+ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ ├── @ HTMLOpenTagNode (location: (7:6)-(7:22))
+ │ │ │ │ │ │ │ │ ├── errors: (1 error)
+ │ │ │ │ │ │ │ │ │ └── @ MissingClosingTagError (location: (7:6)-(7:22))
+ │ │ │ │ │ │ │ │ │ ├── message: "Opening tag `
` at (7:7) doesn't have a matching closing tag ` ` in the same scope."
+ │ │ │ │ │ │ │ │ │ └── opening_tag: "li" (location: (7:7)-(7:9))
+ │ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │ ├── tag_opening: "<" (location: (7:6)-(7:7))
+ │ │ │ │ │ │ │ │ ├── tag_name: "li" (location: (7:7)-(7:9))
+ │ │ │ │ │ │ │ │ ├── tag_closing: ">" (location: (7:21)-(7:22))
+ │ │ │ │ │ │ │ │ ├── children: (1 item)
+ │ │ │ │ │ │ │ │ │ └── @ HTMLAttributeNode (location: (7:10)-(7:21))
+ │ │ │ │ │ │ │ │ │ ├── name:
+ │ │ │ │ │ │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (7:10)-(7:15))
+ │ │ │ │ │ │ │ │ │ │ └── children: (1 item)
+ │ │ │ │ │ │ │ │ │ │ └── @ LiteralNode (location: (7:10)-(7:15))
+ │ │ │ │ │ │ │ │ │ │ └── content: "class"
+ │ │ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │ │ ├── equals: "=" (location: (7:15)-(7:16))
+ │ │ │ │ │ │ │ │ │ └── value:
+ │ │ │ │ │ │ │ │ │ └── @ HTMLAttributeValueNode (location: (7:16)-(7:21))
+ │ │ │ │ │ │ │ │ │ ├── open_quote: """ (location: (7:16)-(7:17))
+ │ │ │ │ │ │ │ │ │ ├── children: (1 item)
+ │ │ │ │ │ │ │ │ │ │ └── @ LiteralNode (location: (7:17)-(7:20))
+ │ │ │ │ │ │ │ │ │ │ └── content: "bar"
+ │ │ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │ │ ├── close_quote: """ (location: (7:20)-(7:21))
+ │ │ │ │ │ │ │ │ │ └── quoted: true
+ │ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │ └── is_void: false
+ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ ├── @ HTMLTextNode (location: (7:22)-(8:8))
+ │ │ │ │ │ │ │ │ └── content: "\n "
+ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ ├── @ HTMLElementNode (location: (8:8)-(8:29))
+ │ │ │ │ │ │ │ │ ├── open_tag:
+ │ │ │ │ │ │ │ │ │ └── @ HTMLOpenTagNode (location: (8:8)-(8:22))
+ │ │ │ │ │ │ │ │ │ ├── tag_opening: "<" (location: (8:8)-(8:9))
+ │ │ │ │ │ │ │ │ │ ├── tag_name: "a" (location: (8:9)-(8:10))
+ │ │ │ │ │ │ │ │ │ ├── tag_closing: ">" (location: (8:21)-(8:22))
+ │ │ │ │ │ │ │ │ │ ├── children: (1 item)
+ │ │ │ │ │ │ │ │ │ │ └── @ HTMLAttributeNode (location: (8:11)-(8:21))
+ │ │ │ │ │ │ │ │ │ │ ├── name:
+ │ │ │ │ │ │ │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (8:11)-(8:15))
+ │ │ │ │ │ │ │ │ │ │ │ └── children: (1 item)
+ │ │ │ │ │ │ │ │ │ │ │ └── @ LiteralNode (location: (8:11)-(8:15))
+ │ │ │ │ │ │ │ │ │ │ │ └── content: "href"
+ │ │ │ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │ │ │ ├── equals: "=" (location: (8:15)-(8:16))
+ │ │ │ │ │ │ │ │ │ │ └── value:
+ │ │ │ │ │ │ │ │ │ │ └── @ HTMLAttributeValueNode (location: (8:16)-(8:21))
+ │ │ │ │ │ │ │ │ │ │ ├── open_quote: """ (location: (8:16)-(8:17))
+ │ │ │ │ │ │ │ │ │ │ ├── children: (1 item)
+ │ │ │ │ │ │ │ │ │ │ │ └── @ LiteralNode (location: (8:17)-(8:20))
+ │ │ │ │ │ │ │ │ │ │ │ └── content: "bar"
+ │ │ │ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │ │ │ ├── close_quote: """ (location: (8:20)-(8:21))
+ │ │ │ │ │ │ │ │ │ │ └── quoted: true
+ │ │ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │ │ └── is_void: false
+ │ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │ ├── tag_name: "a" (location: (8:9)-(8:10))
+ │ │ │ │ │ │ │ │ ├── body: (1 item)
+ │ │ │ │ │ │ │ │ │ └── @ HTMLTextNode (location: (8:22)-(8:25))
+ │ │ │ │ │ │ │ │ │ └── content: "bar"
+ │ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │ ├── close_tag:
+ │ │ │ │ │ │ │ │ │ └── @ HTMLCloseTagNode (location: (8:25)-(8:29))
+ │ │ │ │ │ │ │ │ │ ├── tag_opening: "" (location: (8:25)-(8:27))
+ │ │ │ │ │ │ │ │ │ ├── tag_name: "a" (location: (8:27)-(8:28))
+ │ │ │ │ │ │ │ │ │ ├── children: []
+ │ │ │ │ │ │ │ │ │ └── tag_closing: ">" (location: (8:28)-(8:29))
+ │ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │ ├── is_void: false
+ │ │ │ │ │ │ │ │ └── source: "HTML"
+ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ └── @ HTMLTextNode (location: (8:29)-(9:4))
+ │ │ │ │ │ │ │ └── content: "\n "
+ │ │ │ │ │ │ │
+ │ │ │ │ │ │ ├── subsequent:
+ │ │ │ │ │ │ │ └── @ ERBElseNode (location: (9:4)-(12:4))
+ │ │ │ │ │ │ │ ├── tag_opening: "<%" (location: (9:4)-(9:6))
+ │ │ │ │ │ │ │ ├── content: " else " (location: (9:6)-(9:12))
+ │ │ │ │ │ │ │ ├── tag_closing: "%>" (location: (9:12)-(9:14))
+ │ │ │ │ │ │ │ └── statements: (5 items)
+ │ │ │ │ │ │ │ ├── @ HTMLTextNode (location: (9:14)-(10:6))
+ │ │ │ │ │ │ │ │ └── content: "\n "
+ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ ├── @ HTMLOpenTagNode (location: (10:6)-(10:10))
+ │ │ │ │ │ │ │ │ ├── errors: (1 error)
+ │ │ │ │ │ │ │ │ │ └── @ MissingClosingTagError (location: (10:6)-(10:10))
+ │ │ │ │ │ │ │ │ │ ├── message: "Opening tag `
` at (10:7) doesn't have a matching closing tag ` ` in the same scope."
+ │ │ │ │ │ │ │ │ │ └── opening_tag: "li" (location: (10:7)-(10:9))
+ │ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │ ├── tag_opening: "<" (location: (10:6)-(10:7))
+ │ │ │ │ │ │ │ │ ├── tag_name: "li" (location: (10:7)-(10:9))
+ │ │ │ │ │ │ │ │ ├── tag_closing: ">" (location: (10:9)-(10:10))
+ │ │ │ │ │ │ │ │ ├── children: []
+ │ │ │ │ │ │ │ │ └── is_void: false
+ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ ├── @ HTMLTextNode (location: (10:10)-(11:8))
+ │ │ │ │ │ │ │ │ └── content: "\n "
+ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ ├── @ HTMLElementNode (location: (11:8)-(11:28))
+ │ │ │ │ │ │ │ │ ├── open_tag:
+ │ │ │ │ │ │ │ │ │ └── @ HTMLOpenTagNode (location: (11:8)-(11:14))
+ │ │ │ │ │ │ │ │ │ ├── tag_opening: "<" (location: (11:8)-(11:9))
+ │ │ │ │ │ │ │ │ │ ├── tag_name: "span" (location: (11:9)-(11:13))
+ │ │ │ │ │ │ │ │ │ ├── tag_closing: ">" (location: (11:13)-(11:14))
+ │ │ │ │ │ │ │ │ │ ├── children: []
+ │ │ │ │ │ │ │ │ │ └── is_void: false
+ │ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │ ├── tag_name: "span" (location: (11:9)-(11:13))
+ │ │ │ │ │ │ │ │ ├── body: (1 item)
+ │ │ │ │ │ │ │ │ │ └── @ HTMLTextNode (location: (11:14)-(11:21))
+ │ │ │ │ │ │ │ │ │ └── content: "DEFAULT"
+ │ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │ ├── close_tag:
+ │ │ │ │ │ │ │ │ │ └── @ HTMLCloseTagNode (location: (11:21)-(11:28))
+ │ │ │ │ │ │ │ │ │ ├── tag_opening: "" (location: (11:21)-(11:23))
+ │ │ │ │ │ │ │ │ │ ├── tag_name: "span" (location: (11:23)-(11:27))
+ │ │ │ │ │ │ │ │ │ ├── children: []
+ │ │ │ │ │ │ │ │ │ └── tag_closing: ">" (location: (11:27)-(11:28))
+ │ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │ ├── is_void: false
+ │ │ │ │ │ │ │ │ └── source: "HTML"
+ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ └── @ HTMLTextNode (location: (11:28)-(12:4))
+ │ │ │ │ │ │ │ └── content: "\n "
+ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │
+ │ │ │ │ │ │ └── end_node: ∅
+ │ │ │ │ │ │
+ │ │ │ │ │ └── end_node:
+ │ │ │ │ │ └── @ ERBEndNode (location: (12:4)-(12:13))
+ │ │ │ │ │ ├── tag_opening: "<%" (location: (12:4)-(12:6))
+ │ │ │ │ │ ├── content: " end " (location: (12:6)-(12:11))
+ │ │ │ │ │ └── tag_closing: "%>" (location: (12:11)-(12:13))
+ │ │ │ │ │
+ │ │ │ │ │
+ │ │ │ │ ├── @ HTMLTextNode (location: (12:13)-(13:4))
+ │ │ │ │ │ └── content: "\n "
+ │ │ │ │ │
+ │ │ │ │ ├── @ HTMLCloseTagNode (location: (13:4)-(13:9))
+ │ │ │ │ │ ├── errors: (1 error)
+ │ │ │ │ │ │ └── @ MissingOpeningTagError (location: (13:4)-(13:9))
+ │ │ │ │ │ │ ├── message: "Found closing tag `` at (13:6) without a matching opening tag in the same scope."
+ │ │ │ │ │ │ └── closing_tag: "li" (location: (13:6)-(13:8))
+ │ │ │ │ │ │
+ │ │ │ │ │ ├── tag_opening: "" (location: (13:4)-(13:6))
+ │ │ │ │ │ ├── tag_name: "li" (location: (13:6)-(13:8))
+ │ │ │ │ │ ├── children: []
+ │ │ │ │ │ └── tag_closing: ">" (location: (13:8)-(13:9))
+ │ │ │ │ │
+ │ │ │ │ └── @ HTMLTextNode (location: (13:9)-(14:2))
+ │ │ │ │ └── content: "\n "
+ │ │ │ │
+ │ │ │ ├── close_tag:
+ │ │ │ │ └── @ HTMLCloseTagNode (location: (14:2)-(14:7))
+ │ │ │ │ ├── tag_opening: "" (location: (14:2)-(14:4))
+ │ │ │ │ ├── tag_name: "ul" (location: (14:4)-(14:6))
+ │ │ │ │ ├── children: []
+ │ │ │ │ └── tag_closing: ">" (location: (14:6)-(14:7))
+ │ │ │ │
+ │ │ │ ├── is_void: false
+ │ │ │ └── source: "HTML"
+ │ │ │
+ │ │ └── @ HTMLTextNode (location: (14:7)-(15:0))
+ │ │ └── content: "\n"
+ │ │
+ │ ├── close_tag:
+ │ │ └── @ HTMLCloseTagNode (location: (15:0)-(15:6))
+ │ │ ├── tag_opening: "" (location: (15:0)-(15:2))
+ │ │ ├── tag_name: "nav" (location: (15:2)-(15:5))
+ │ │ ├── children: []
+ │ │ └── tag_closing: ">" (location: (15:5)-(15:6))
+ │ │
+ │ ├── is_void: false
+ │ └── source: "HTML"
+ │
+ └── @ HTMLTextNode (location: (15:6)-(16:0))
+ └── content: "\n"
\ No newline at end of file
diff --git a/test/snapshots/parser/erb_context_mismatch_test/test_0005_element_opened_in_block_must_be_closed_within_block_264d7b62538d8f8e318bce1a37dee984.txt b/test/snapshots/parser/erb_context_mismatch_test/test_0005_element_opened_in_block_must_be_closed_within_block_264d7b62538d8f8e318bce1a37dee984.txt
new file mode 100644
index 000000000..87b21de63
--- /dev/null
+++ b/test/snapshots/parser/erb_context_mismatch_test/test_0005_element_opened_in_block_must_be_closed_within_block_264d7b62538d8f8e318bce1a37dee984.txt
@@ -0,0 +1,57 @@
+---
+source: "Parser::ERBContextMismatchTest#test_0005_element opened in block must be closed within block"
+input: |2-
+<% if true %>
+
123
+<% end %>
+
+---
+@ DocumentNode (location: (1:0)-(5:0))
+└── children: (4 items)
+ ├── @ ERBIfNode (location: (1:0)-(3:9))
+ │ ├── tag_opening: "<%" (location: (1:0)-(1:2))
+ │ ├── content: " if true " (location: (1:2)-(1:11))
+ │ ├── tag_closing: "%>" (location: (1:11)-(1:13))
+ │ ├── statements: (3 items)
+ │ │ ├── @ HTMLTextNode (location: (1:13)-(2:2))
+ │ │ │ └── content: "\n "
+ │ │ │
+ │ │ ├── @ HTMLOpenTagNode (location: (2:2)-(2:6))
+ │ │ │ ├── errors: (1 error)
+ │ │ │ │ └── @ MissingClosingTagError (location: (2:2)-(2:6))
+ │ │ │ │ ├── message: "Opening tag `
` at (2:3) doesn't have a matching closing tag ` ` in the same scope."
+ │ │ │ │ └── opening_tag: "h1" (location: (2:3)-(2:5))
+ │ │ │ │
+ │ │ │ ├── tag_opening: "<" (location: (2:2)-(2:3))
+ │ │ │ ├── tag_name: "h1" (location: (2:3)-(2:5))
+ │ │ │ ├── tag_closing: ">" (location: (2:5)-(2:6))
+ │ │ │ ├── children: []
+ │ │ │ └── is_void: false
+ │ │ │
+ │ │ └── @ HTMLTextNode (location: (2:6)-(3:0))
+ │ │ └── content: "123\n"
+ │ │
+ │ ├── subsequent: ∅
+ │ └── end_node:
+ │ └── @ ERBEndNode (location: (3:0)-(3:9))
+ │ ├── tag_opening: "<%" (location: (3:0)-(3:2))
+ │ ├── content: " end " (location: (3:2)-(3:7))
+ │ └── tag_closing: "%>" (location: (3:7)-(3:9))
+ │
+ │
+ ├── @ HTMLTextNode (location: (3:9)-(4:0))
+ │ └── content: "\n"
+ │
+ ├── @ HTMLCloseTagNode (location: (4:0)-(4:5))
+ │ ├── errors: (1 error)
+ │ │ └── @ MissingOpeningTagError (location: (4:0)-(4:5))
+ │ │ ├── message: "Found closing tag `` at (4:2) without a matching opening tag in the same scope."
+ │ │ └── closing_tag: "h1" (location: (4:2)-(4:4))
+ │ │
+ │ ├── tag_opening: "" (location: (4:0)-(4:2))
+ │ ├── tag_name: "h1" (location: (4:2)-(4:4))
+ │ ├── children: []
+ │ └── tag_closing: ">" (location: (4:4)-(4:5))
+ │
+ └── @ HTMLTextNode (location: (4:5)-(5:0))
+ └── content: "\n"
\ No newline at end of file
diff --git a/test/snapshots/parser/erb_context_mismatch_test/test_0006_opening_in_one_context_and_closing_in_another_context_23760079615eb0a149447d79f51005bb.txt b/test/snapshots/parser/erb_context_mismatch_test/test_0006_opening_in_one_context_and_closing_in_another_context_23760079615eb0a149447d79f51005bb.txt
new file mode 100644
index 000000000..931b2adb7
--- /dev/null
+++ b/test/snapshots/parser/erb_context_mismatch_test/test_0006_opening_in_one_context_and_closing_in_another_context_23760079615eb0a149447d79f51005bb.txt
@@ -0,0 +1,81 @@
+---
+source: "Parser::ERBContextMismatchTest#test_0006_opening in one context and closing in another context"
+input: |2-
+<% if true %>
+
+<% end %>
+
+ Content
+
+<% if true %>
+
+<% end %>
+---
+@ DocumentNode (location: (1:0)-(10:0))
+└── children: (4 items)
+ ├── @ ERBIfNode (location: (1:0)-(3:9))
+ │ ├── tag_opening: "<%" (location: (1:0)-(1:2))
+ │ ├── content: " if true " (location: (1:2)-(1:11))
+ │ ├── tag_closing: "%>" (location: (1:11)-(1:13))
+ │ ├── statements: (3 items)
+ │ │ ├── @ HTMLTextNode (location: (1:13)-(2:2))
+ │ │ │ └── content: "\n "
+ │ │ │
+ │ │ ├── @ HTMLOpenTagNode (location: (2:2)-(2:6))
+ │ │ │ ├── errors: (1 error)
+ │ │ │ │ └── @ MissingClosingTagError (location: (2:2)-(2:6))
+ │ │ │ │ ├── message: "Opening tag `
` at (2:3) doesn't have a matching closing tag ` ` in the same scope."
+ │ │ │ │ └── opening_tag: "h1" (location: (2:3)-(2:5))
+ │ │ │ │
+ │ │ │ ├── tag_opening: "<" (location: (2:2)-(2:3))
+ │ │ │ ├── tag_name: "h1" (location: (2:3)-(2:5))
+ │ │ │ ├── tag_closing: ">" (location: (2:5)-(2:6))
+ │ │ │ ├── children: []
+ │ │ │ └── is_void: false
+ │ │ │
+ │ │ └── @ HTMLTextNode (location: (2:6)-(3:0))
+ │ │ └── content: "\n"
+ │ │
+ │ ├── subsequent: ∅
+ │ └── end_node:
+ │ └── @ ERBEndNode (location: (3:0)-(3:9))
+ │ ├── tag_opening: "<%" (location: (3:0)-(3:2))
+ │ ├── content: " end " (location: (3:2)-(3:7))
+ │ └── tag_closing: "%>" (location: (3:7)-(3:9))
+ │
+ │
+ ├── @ HTMLTextNode (location: (3:9)-(7:0))
+ │ └── content: "\n\n Content\n\n"
+ │
+ ├── @ ERBIfNode (location: (7:0)-(9:9))
+ │ ├── tag_opening: "<%" (location: (7:0)-(7:2))
+ │ ├── content: " if true " (location: (7:2)-(7:11))
+ │ ├── tag_closing: "%>" (location: (7:11)-(7:13))
+ │ ├── statements: (3 items)
+ │ │ ├── @ HTMLTextNode (location: (7:13)-(8:2))
+ │ │ │ └── content: "\n "
+ │ │ │
+ │ │ ├── @ HTMLCloseTagNode (location: (8:2)-(8:7))
+ │ │ │ ├── errors: (1 error)
+ │ │ │ │ └── @ MissingOpeningTagError (location: (8:2)-(8:7))
+ │ │ │ │ ├── message: "Found closing tag `` at (8:4) without a matching opening tag in the same scope."
+ │ │ │ │ └── closing_tag: "h1" (location: (8:4)-(8:6))
+ │ │ │ │
+ │ │ │ ├── tag_opening: "" (location: (8:2)-(8:4))
+ │ │ │ ├── tag_name: "h1" (location: (8:4)-(8:6))
+ │ │ │ ├── children: []
+ │ │ │ └── tag_closing: ">" (location: (8:6)-(8:7))
+ │ │ │
+ │ │ └── @ HTMLTextNode (location: (8:7)-(9:0))
+ │ │ └── content: "\n"
+ │ │
+ │ ├── subsequent: ∅
+ │ └── end_node:
+ │ └── @ ERBEndNode (location: (9:0)-(9:9))
+ │ ├── tag_opening: "<%" (location: (9:0)-(9:2))
+ │ ├── content: " end " (location: (9:2)-(9:7))
+ │ └── tag_closing: "%>" (location: (9:7)-(9:9))
+ │
+ │
+ └── @ HTMLTextNode (location: (9:9)-(10:0))
+ └── content: "\n"
\ No newline at end of file
diff --git a/test/snapshots/parser/erb_context_mismatch_test/test_0007_stray_closing_tag_without_opening_7435ca180811536625a8df051573f55d.txt b/test/snapshots/parser/erb_context_mismatch_test/test_0007_stray_closing_tag_without_opening_7435ca180811536625a8df051573f55d.txt
new file mode 100644
index 000000000..4407f1233
--- /dev/null
+++ b/test/snapshots/parser/erb_context_mismatch_test/test_0007_stray_closing_tag_without_opening_7435ca180811536625a8df051573f55d.txt
@@ -0,0 +1,50 @@
+---
+source: "Parser::ERBContextMismatchTest#test_0007_stray closing tag without opening"
+input: |2-
+
+ content
+
+
+---
+@ DocumentNode (location: (1:0)-(5:0))
+└── children: (4 items)
+ ├── @ HTMLElementNode (location: (1:0)-(3:6))
+ │ ├── open_tag:
+ │ │ └── @ HTMLOpenTagNode (location: (1:0)-(1:5))
+ │ │ ├── tag_opening: "<" (location: (1:0)-(1:1))
+ │ │ ├── tag_name: "div" (location: (1:1)-(1:4))
+ │ │ ├── tag_closing: ">" (location: (1:4)-(1:5))
+ │ │ ├── children: []
+ │ │ └── is_void: false
+ │ │
+ │ ├── tag_name: "div" (location: (1:1)-(1:4))
+ │ ├── body: (1 item)
+ │ │ └── @ HTMLTextNode (location: (1:5)-(3:0))
+ │ │ └── content: "\n content\n"
+ │ │
+ │ ├── close_tag:
+ │ │ └── @ HTMLCloseTagNode (location: (3:0)-(3:6))
+ │ │ ├── tag_opening: "" (location: (3:0)-(3:2))
+ │ │ ├── tag_name: "div" (location: (3:2)-(3:5))
+ │ │ ├── children: []
+ │ │ └── tag_closing: ">" (location: (3:5)-(3:6))
+ │ │
+ │ ├── is_void: false
+ │ └── source: "HTML"
+ │
+ ├── @ HTMLTextNode (location: (3:6)-(4:0))
+ │ └── content: "\n"
+ │
+ ├── @ HTMLCloseTagNode (location: (4:0)-(4:7))
+ │ ├── errors: (1 error)
+ │ │ └── @ MissingOpeningTagError (location: (4:0)-(4:7))
+ │ │ ├── message: "Found closing tag `` at (4:2) without a matching opening tag in the same scope."
+ │ │ └── closing_tag: "span" (location: (4:2)-(4:6))
+ │ │
+ │ ├── tag_opening: "" (location: (4:0)-(4:2))
+ │ ├── tag_name: "span" (location: (4:2)-(4:6))
+ │ ├── children: []
+ │ └── tag_closing: ">" (location: (4:6)-(4:7))
+ │
+ └── @ HTMLTextNode (location: (4:7)-(5:0))
+ └── content: "\n"
\ No newline at end of file
diff --git a/test/snapshots/parser/erb_context_mismatch_test/test_0008_unclosed_tag_without_closing_1ccadf7f0ed2141a178d6f7c5736dc6c.txt b/test/snapshots/parser/erb_context_mismatch_test/test_0008_unclosed_tag_without_closing_1ccadf7f0ed2141a178d6f7c5736dc6c.txt
new file mode 100644
index 000000000..949914dc2
--- /dev/null
+++ b/test/snapshots/parser/erb_context_mismatch_test/test_0008_unclosed_tag_without_closing_1ccadf7f0ed2141a178d6f7c5736dc6c.txt
@@ -0,0 +1,50 @@
+---
+source: "Parser::ERBContextMismatchTest#test_0008_unclosed tag without closing"
+input: |2-
+
+ content
+
+---
+@ DocumentNode (location: (1:0)-(4:0))
+└── children: (2 items)
+ ├── @ HTMLElementNode (location: (1:0)-(3:6))
+ │ ├── open_tag:
+ │ │ └── @ HTMLOpenTagNode (location: (1:0)-(1:5))
+ │ │ ├── tag_opening: "<" (location: (1:0)-(1:1))
+ │ │ ├── tag_name: "div" (location: (1:1)-(1:4))
+ │ │ ├── tag_closing: ">" (location: (1:4)-(1:5))
+ │ │ ├── children: []
+ │ │ └── is_void: false
+ │ │
+ │ ├── tag_name: "div" (location: (1:1)-(1:4))
+ │ ├── body: (3 items)
+ │ │ ├── @ HTMLTextNode (location: (1:5)-(2:2))
+ │ │ │ └── content: "\n "
+ │ │ │
+ │ │ ├── @ HTMLOpenTagNode (location: (2:2)-(2:8))
+ │ │ │ ├── errors: (1 error)
+ │ │ │ │ └── @ MissingClosingTagError (location: (2:2)-(2:8))
+ │ │ │ │ ├── message: "Opening tag `
` at (2:3) doesn't have a matching closing tag ` ` in the same scope."
+ │ │ │ │ └── opening_tag: "span" (location: (2:3)-(2:7))
+ │ │ │ │
+ │ │ │ ├── tag_opening: "<" (location: (2:2)-(2:3))
+ │ │ │ ├── tag_name: "span" (location: (2:3)-(2:7))
+ │ │ │ ├── tag_closing: ">" (location: (2:7)-(2:8))
+ │ │ │ ├── children: []
+ │ │ │ └── is_void: false
+ │ │ │
+ │ │ └── @ HTMLTextNode (location: (2:8)-(3:0))
+ │ │ └── content: "content\n"
+ │ │
+ │ ├── close_tag:
+ │ │ └── @ HTMLCloseTagNode (location: (3:0)-(3:6))
+ │ │ ├── tag_opening: "" (location: (3:0)-(3:2))
+ │ │ ├── tag_name: "div" (location: (3:2)-(3:5))
+ │ │ ├── children: []
+ │ │ └── tag_closing: ">" (location: (3:5)-(3:6))
+ │ │
+ │ ├── is_void: false
+ │ └── source: "HTML"
+ │
+ └── @ HTMLTextNode (location: (3:6)-(4:0))
+ └── content: "\n"
\ No newline at end of file
diff --git a/test/snapshots/parser/erb_test/test_0036_unterminated_erb_missing_closing_%gt_1e22264334529582735f76812bfeec73.txt b/test/snapshots/parser/erb_test/test_0036_unterminated_erb_missing_closing_%gt_1e22264334529582735f76812bfeec73.txt
index 0fd8613a5..84868c148 100644
--- a/test/snapshots/parser/erb_test/test_0036_unterminated_erb_missing_closing_%gt_1e22264334529582735f76812bfeec73.txt
+++ b/test/snapshots/parser/erb_test/test_0036_unterminated_erb_missing_closing_%gt_1e22264334529582735f76812bfeec73.txt
@@ -5,16 +5,20 @@ input: "<% if true"
@ DocumentNode (location: (1:0)-(1:10))
└── children: (1 item)
└── @ ERBIfNode (location: (1:0)-(1:10))
- ├── errors: (2 errors)
+ ├── errors: (3 errors)
│ ├── @ UnexpectedTokenError (location: (1:2)-(1:10))
│ │ ├── message: "Found `TOKEN_ERROR` when expecting `TOKEN_ERB_CONTENT` at (1:2)."
│ │ ├── expected_type: "TOKEN_ERB_CONTENT"
│ │ └── found: " if true" (location: (1:2)-(1:10))
│ │
- │ └── @ UnexpectedTokenError (location: (1:10)-(1:10))
- │ ├── message: "Found `TOKEN_EOF` when expecting `TOKEN_ERB_END` at (1:10)."
- │ ├── expected_type: "TOKEN_ERB_END"
- │ └── found: "" (location: (1:10)-(1:10))
+ │ ├── @ UnexpectedTokenError (location: (1:10)-(1:10))
+ │ │ ├── message: "Found `TOKEN_EOF` when expecting `TOKEN_ERB_END` at (1:10)."
+ │ │ ├── expected_type: "TOKEN_ERB_END"
+ │ │ └── found: "" (location: (1:10)-(1:10))
+ │ │
+ │ └── @ MissingERBEndTagError (location: (1:0)-(1:10))
+ │ ├── message: "`<% if %>` started here but never closed with an end tag. The end tag may be in a different scope."
+ │ └── keyword: "`<% if %>`"
│
├── tag_opening: "<%" (location: (1:0)-(1:2))
├── content: " if true" (location: (1:2)-(1:10))
diff --git a/test/snapshots/parser/erb_test/test_0037_unterminated_erb_missing_closing_gt_2707e9fbfa1307c14d5d6deaf40bd0af.txt b/test/snapshots/parser/erb_test/test_0037_unterminated_erb_missing_closing_gt_2707e9fbfa1307c14d5d6deaf40bd0af.txt
index 650c387f4..743f8d77b 100644
--- a/test/snapshots/parser/erb_test/test_0037_unterminated_erb_missing_closing_gt_2707e9fbfa1307c14d5d6deaf40bd0af.txt
+++ b/test/snapshots/parser/erb_test/test_0037_unterminated_erb_missing_closing_gt_2707e9fbfa1307c14d5d6deaf40bd0af.txt
@@ -5,16 +5,20 @@ input: "<% if true %"
@ DocumentNode (location: (1:0)-(1:12))
└── children: (1 item)
└── @ ERBIfNode (location: (1:0)-(1:12))
- ├── errors: (2 errors)
+ ├── errors: (3 errors)
│ ├── @ UnexpectedTokenError (location: (1:2)-(1:12))
│ │ ├── message: "Found `TOKEN_ERROR` when expecting `TOKEN_ERB_CONTENT` at (1:2)."
│ │ ├── expected_type: "TOKEN_ERB_CONTENT"
│ │ └── found: " if true %" (location: (1:2)-(1:12))
│ │
- │ └── @ UnexpectedTokenError (location: (1:12)-(1:12))
- │ ├── message: "Found `TOKEN_EOF` when expecting `TOKEN_ERB_END` at (1:12)."
- │ ├── expected_type: "TOKEN_ERB_END"
- │ └── found: "" (location: (1:12)-(1:12))
+ │ ├── @ UnexpectedTokenError (location: (1:12)-(1:12))
+ │ │ ├── message: "Found `TOKEN_EOF` when expecting `TOKEN_ERB_END` at (1:12)."
+ │ │ ├── expected_type: "TOKEN_ERB_END"
+ │ │ └── found: "" (location: (1:12)-(1:12))
+ │ │
+ │ └── @ MissingERBEndTagError (location: (1:0)-(1:12))
+ │ ├── message: "`<% if %>` started here but never closed with an end tag. The end tag may be in a different scope."
+ │ └── keyword: "`<% if %>`"
│
├── tag_opening: "<%" (location: (1:0)-(1:2))
├── content: " if true %" (location: (1:2)-(1:12))
diff --git a/test/snapshots/parser/erb_test/test_0039_TODO_d7de40920545c14e5afcda3a2e9f0eb9.txt b/test/snapshots/parser/erb_test/test_0039_TODO_d7de40920545c14e5afcda3a2e9f0eb9.txt
new file mode 100644
index 000000000..59a382d5f
--- /dev/null
+++ b/test/snapshots/parser/erb_test/test_0039_TODO_d7de40920545c14e5afcda3a2e9f0eb9.txt
@@ -0,0 +1,19 @@
+---
+source: "Parser::ERBTest#test_0039_TODO"
+input: "<%= 1 + %>"
+---
+@ DocumentNode (location: (1:0)-(1:10))
+├── errors: (1 error)
+│ └── @ RubyParseError (location: (1:9)-(1:10))
+│ ├── message: "expect_expression_after_operator: unexpected ';'; expected an expression after the operator"
+│ ├── error_message: "unexpected ';'; expected an expression after the operator"
+│ ├── diagnostic_id: "expect_expression_after_operator"
+│ └── level: "syntax"
+│
+└── children: (1 item)
+ └── @ ERBContentNode (location: (1:0)-(1:10))
+ ├── tag_opening: "<%=" (location: (1:0)-(1:3))
+ ├── content: " 1 + " (location: (1:3)-(1:8))
+ ├── tag_closing: "%>" (location: (1:8)-(1:10))
+ ├── parsed: true
+ └── valid: false
\ No newline at end of file
diff --git a/test/snapshots/parser/script_style_test/test_0006_script_tag_with_ERB-like_content_in_string_b1ffbf793264421bcbb1b9d6087f10b2.txt b/test/snapshots/parser/script_style_test/test_0006_script_tag_with_ERB-like_content_in_string_b1ffbf793264421bcbb1b9d6087f10b2.txt
index c797d575c..a52aabb72 100644
--- a/test/snapshots/parser/script_style_test/test_0006_script_tag_with_ERB-like_content_in_string_b1ffbf793264421bcbb1b9d6087f10b2.txt
+++ b/test/snapshots/parser/script_style_test/test_0006_script_tag_with_ERB-like_content_in_string_b1ffbf793264421bcbb1b9d6087f10b2.txt
@@ -3,16 +3,11 @@ source: "Parser::ScriptStyleTest#test_0006_script tag with ERB-like content in s
input: ""
---
@ DocumentNode (location: (1:0)-(1:35))
-├── errors: (1 error)
-│ └── @ UnclosedElementError (location: (1:35)-(1:35))
-│ ├── message: "Tag ``."
+ │ ├── message: "Opening tag `` in the same scope."
│ └── opening_tag: "script" (location: (1:1)-(1:7))
│
├── open_tag:
diff --git a/test/snapshots/parser/script_style_test/test_0007_script_tag_with_incomplete_ERB-like_content_c3dcacbbac9dfaafc8298a1e8b6df38b.txt b/test/snapshots/parser/script_style_test/test_0007_script_tag_with_incomplete_ERB-like_content_c3dcacbbac9dfaafc8298a1e8b6df38b.txt
index 2aafc5857..9704b89a3 100644
--- a/test/snapshots/parser/script_style_test/test_0007_script_tag_with_incomplete_ERB-like_content_c3dcacbbac9dfaafc8298a1e8b6df38b.txt
+++ b/test/snapshots/parser/script_style_test/test_0007_script_tag_with_incomplete_ERB-like_content_c3dcacbbac9dfaafc8298a1e8b6df38b.txt
@@ -3,16 +3,11 @@ source: "Parser::ScriptStyleTest#test_0007_script tag with incomplete ERB-like c
input: ""
---
@ DocumentNode (location: (1:0)-(1:47))
-├── errors: (1 error)
-│ └── @ UnclosedElementError (location: (1:47)-(1:47))
-│ ├── message: "Tag ``."
+ │ ├── message: "Opening tag `` in the same scope."
│ └── opening_tag: "script" (location: (1:1)-(1:7))
│
├── open_tag:
diff --git a/test/snapshots/parser/script_style_test/test_0008_script_tag_with_closing_script_tag_in_string_4d120bcac86583501954aa7c7d1b54f8.txt b/test/snapshots/parser/script_style_test/test_0008_script_tag_with_closing_script_tag_in_string_4d120bcac86583501954aa7c7d1b54f8.txt
index 5c992cc1d..35f2abc64 100644
--- a/test/snapshots/parser/script_style_test/test_0008_script_tag_with_closing_script_tag_in_string_4d120bcac86583501954aa7c7d1b54f8.txt
+++ b/test/snapshots/parser/script_style_test/test_0008_script_tag_with_closing_script_tag_in_string_4d120bcac86583501954aa7c7d1b54f8.txt
@@ -34,7 +34,7 @@ input: "\";"
└── @ HTMLCloseTagNode (location: (1:28)-(1:37))
├── errors: (1 error)
│ └── @ MissingOpeningTagError (location: (1:28)-(1:37))
- │ ├── message: "Found closing tag `` at (1:30) without a matching opening tag."
+ │ ├── message: "Found closing tag `` at (1:30) without a matching opening tag in the same scope."
│ └── closing_tag: "script" (location: (1:30)-(1:36))
│
├── tag_opening: "" (location: (1:28)-(1:30))
diff --git a/test/snapshots/parser/script_style_test/test_0028_script_tag_with_incomplete_ERB_tag_at_end_1ccec9a4a170634bddb31f9c22d0fbc5.txt b/test/snapshots/parser/script_style_test/test_0028_script_tag_with_incomplete_ERB_tag_at_end_1ccec9a4a170634bddb31f9c22d0fbc5.txt
index 36281be41..29facca25 100644
--- a/test/snapshots/parser/script_style_test/test_0028_script_tag_with_incomplete_ERB_tag_at_end_1ccec9a4a170634bddb31f9c22d0fbc5.txt
+++ b/test/snapshots/parser/script_style_test/test_0028_script_tag_with_incomplete_ERB_tag_at_end_1ccec9a4a170634bddb31f9c22d0fbc5.txt
@@ -3,16 +3,11 @@ source: "Parser::ScriptStyleTest#test_0028_script tag with incomplete ERB tag at
input: ""
---
@ DocumentNode (location: (1:0)-(1:40))
-├── errors: (1 error)
-│ └── @ UnclosedElementError (location: (1:40)-(1:40))
-│ ├── message: "Tag ``."
+ │ ├── message: "Opening tag `` in the same scope."
│ └── opening_tag: "script" (location: (1:1)-(1:7))
│
├── open_tag:
diff --git a/test/snapshots/parser/script_style_test/test_0032_script_tag_with_single_quote_strings_containing_closing_tags_ffab60cb04f4e44e1ee7ed24d4ac9563.txt b/test/snapshots/parser/script_style_test/test_0032_script_tag_with_single_quote_strings_containing_closing_tags_ffab60cb04f4e44e1ee7ed24d4ac9563.txt
index 77f819478..4626409df 100644
--- a/test/snapshots/parser/script_style_test/test_0032_script_tag_with_single_quote_strings_containing_closing_tags_ffab60cb04f4e44e1ee7ed24d4ac9563.txt
+++ b/test/snapshots/parser/script_style_test/test_0032_script_tag_with_single_quote_strings_containing_closing_tags_ffab60cb04f4e44e1ee7ed24d4ac9563.txt
@@ -34,7 +34,7 @@ input: "'; var s2 = '';"
├── @ HTMLCloseTagNode (location: (1:40)-(1:48))
│ ├── errors: (1 error)
│ │ └── @ MissingOpeningTagError (location: (1:40)-(1:48))
- │ │ ├── message: "Found closing tag `` at (1:42) without a matching opening tag."
+ │ │ ├── message: "Found closing tag `` at (1:42) without a matching opening tag in the same scope."
│ │ └── closing_tag: "style" (location: (1:42)-(1:47))
│ │
│ ├── tag_opening: "" (location: (1:40)-(1:42))
@@ -48,7 +48,7 @@ input: "'; var s2 = '';"
└── @ HTMLCloseTagNode (location: (1:50)-(1:59))
├── errors: (1 error)
│ └── @ MissingOpeningTagError (location: (1:50)-(1:59))
- │ ├── message: "Found closing tag `` at (1:52) without a matching opening tag."
+ │ ├── message: "Found closing tag `` at (1:52) without a matching opening tag in the same scope."
│ └── closing_tag: "script" (location: (1:52)-(1:58))
│
├── tag_opening: "" (location: (1:50)-(1:52))
diff --git a/test/snapshots/parser/script_style_test/test_0033_script_tag_with_double_quote_strings_containing_closing_tags_34e16086c329d845a1defbf80502a3a7.txt b/test/snapshots/parser/script_style_test/test_0033_script_tag_with_double_quote_strings_containing_closing_tags_34e16086c329d845a1defbf80502a3a7.txt
index bb7ac9ded..00ce1ed2d 100644
--- a/test/snapshots/parser/script_style_test/test_0033_script_tag_with_double_quote_strings_containing_closing_tags_34e16086c329d845a1defbf80502a3a7.txt
+++ b/test/snapshots/parser/script_style_test/test_0033_script_tag_with_double_quote_strings_containing_closing_tags_34e16086c329d845a1defbf80502a3a7.txt
@@ -34,7 +34,7 @@ input: "\"; var s2 = \"\";"
├── @ HTMLCloseTagNode (location: (1:40)-(1:48))
│ ├── errors: (1 error)
│ │ └── @ MissingOpeningTagError (location: (1:40)-(1:48))
- │ │ ├── message: "Found closing tag `` at (1:42) without a matching opening tag."
+ │ │ ├── message: "Found closing tag `` at (1:42) without a matching opening tag in the same scope."
│ │ └── closing_tag: "style" (location: (1:42)-(1:47))
│ │
│ ├── tag_opening: "" (location: (1:40)-(1:42))
@@ -48,7 +48,7 @@ input: "\"; var s2 = \"\";"
└── @ HTMLCloseTagNode (location: (1:50)-(1:59))
├── errors: (1 error)
│ └── @ MissingOpeningTagError (location: (1:50)-(1:59))
- │ ├── message: "Found closing tag `` at (1:52) without a matching opening tag."
+ │ ├── message: "Found closing tag `` at (1:52) without a matching opening tag in the same scope."
│ └── closing_tag: "script" (location: (1:52)-(1:58))
│
├── tag_opening: "" (location: (1:50)-(1:52))
diff --git a/test/snapshots/parser/script_style_test/test_0034_script_tag_with_template_literals_containing_closing_tags_6bcbe820b5902dfe97a869593621bebf.txt b/test/snapshots/parser/script_style_test/test_0034_script_tag_with_template_literals_containing_closing_tags_6bcbe820b5902dfe97a869593621bebf.txt
index 67a2e90d8..310e80823 100644
--- a/test/snapshots/parser/script_style_test/test_0034_script_tag_with_template_literals_containing_closing_tags_6bcbe820b5902dfe97a869593621bebf.txt
+++ b/test/snapshots/parser/script_style_test/test_0034_script_tag_with_template_literals_containing_closing_tags_6bcbe820b5902dfe97a869593621bebf.txt
@@ -34,7 +34,7 @@ input: "`;"
└── @ HTMLCloseTagNode (location: (1:35)-(1:44))
├── errors: (1 error)
│ └── @ MissingOpeningTagError (location: (1:35)-(1:44))
- │ ├── message: "Found closing tag `` at (1:37) without a matching opening tag."
+ │ ├── message: "Found closing tag `` at (1:37) without a matching opening tag in the same scope."
│ └── closing_tag: "script" (location: (1:37)-(1:43))
│
├── tag_opening: "" (location: (1:35)-(1:37))
diff --git a/test/snapshots/parser/script_style_test/test_0035_script_tag_with_escaped_quotes_in_strings_3217a5ed01ac8ce6c44f9e106f9b4017.txt b/test/snapshots/parser/script_style_test/test_0035_script_tag_with_escaped_quotes_in_strings_3217a5ed01ac8ce6c44f9e106f9b4017.txt
index 82f59f286..187781eb7 100644
--- a/test/snapshots/parser/script_style_test/test_0035_script_tag_with_escaped_quotes_in_strings_3217a5ed01ac8ce6c44f9e106f9b4017.txt
+++ b/test/snapshots/parser/script_style_test/test_0035_script_tag_with_escaped_quotes_in_strings_3217a5ed01ac8ce6c44f9e106f9b4017.txt
@@ -34,7 +34,7 @@ input: "\\\" yesterday\";"
└── @ HTMLCloseTagNode (location: (1:50)-(1:59))
├── errors: (1 error)
│ └── @ MissingOpeningTagError (location: (1:50)-(1:59))
- │ ├── message: "Found closing tag `` at (1:52) without a matching opening tag."
+ │ ├── message: "Found closing tag `` at (1:52) without a matching opening tag in the same scope."
│ └── closing_tag: "script" (location: (1:52)-(1:58))
│
├── tag_opening: "" (location: (1:50)-(1:52))
diff --git a/test/snapshots/parser/script_style_test/test_0036_style_tag_with_quotes_containing_HTML-like_content_e270b9ac006614d91dd6f0ac8fa94fa0.txt b/test/snapshots/parser/script_style_test/test_0036_style_tag_with_quotes_containing_HTML-like_content_e270b9ac006614d91dd6f0ac8fa94fa0.txt
index e6e5bd025..c44f94134 100644
--- a/test/snapshots/parser/script_style_test/test_0036_style_tag_with_quotes_containing_HTML-like_content_e270b9ac006614d91dd6f0ac8fa94fa0.txt
+++ b/test/snapshots/parser/script_style_test/test_0036_style_tag_with_quotes_containing_HTML-like_content_e270b9ac006614d91dd6f0ac8fa94fa0.txt
@@ -34,7 +34,7 @@ input: "\"; }"
└── @ HTMLCloseTagNode (location: (1:45)-(1:53))
├── errors: (1 error)
│ └── @ MissingOpeningTagError (location: (1:45)-(1:53))
- │ ├── message: "Found closing tag `` at (1:47) without a matching opening tag."
+ │ ├── message: "Found closing tag `` at (1:47) without a matching opening tag in the same scope."
│ └── closing_tag: "style" (location: (1:47)-(1:52))
│
├── tag_opening: "" (location: (1:45)-(1:47))
diff --git a/test/snapshots/parser/script_style_test/test_0037_script_tag_with_mixed_quote_types_and_closing_tags_13c557e6f9f1cb452509b1e1750ede1d.txt b/test/snapshots/parser/script_style_test/test_0037_script_tag_with_mixed_quote_types_and_closing_tags_13c557e6f9f1cb452509b1e1750ede1d.txt
index 27468dcee..e4de22e0e 100644
--- a/test/snapshots/parser/script_style_test/test_0037_script_tag_with_mixed_quote_types_and_closing_tags_13c557e6f9f1cb452509b1e1750ede1d.txt
+++ b/test/snapshots/parser/script_style_test/test_0037_script_tag_with_mixed_quote_types_and_closing_tags_13c557e6f9f1cb452509b1e1750ede1d.txt
@@ -39,7 +39,7 @@ input: |2-
├── @ HTMLCloseTagNode (location: (3:16)-(3:25))
│ ├── errors: (1 error)
│ │ └── @ MissingOpeningTagError (location: (3:16)-(3:25))
- │ │ ├── message: "Found closing tag `` at (3:18) without a matching opening tag."
+ │ │ ├── message: "Found closing tag `` at (3:18) without a matching opening tag in the same scope."
│ │ └── closing_tag: "script" (location: (3:18)-(3:24))
│ │
│ ├── tag_opening: "" (location: (3:16)-(3:18))
@@ -53,7 +53,7 @@ input: |2-
├── @ HTMLCloseTagNode (location: (5:0)-(5:9))
│ ├── errors: (1 error)
│ │ └── @ MissingOpeningTagError (location: (5:0)-(5:9))
- │ │ ├── message: "Found closing tag `` at (5:2) without a matching opening tag."
+ │ │ ├── message: "Found closing tag `` at (5:2) without a matching opening tag in the same scope."
│ │ └── closing_tag: "script" (location: (5:2)-(5:8))
│ │
│ ├── tag_opening: "" (location: (5:0)-(5:2))
diff --git a/test/snapshots/parser/script_style_test/test_0046_script_tag_with_closing_tag_in_single-line_comment_6cfabe5d024715f9a1a359ead2336bde.txt b/test/snapshots/parser/script_style_test/test_0046_script_tag_with_closing_tag_in_single-line_comment_6cfabe5d024715f9a1a359ead2336bde.txt
index 13b78a52f..a38383a15 100644
--- a/test/snapshots/parser/script_style_test/test_0046_script_tag_with_closing_tag_in_single-line_comment_6cfabe5d024715f9a1a359ead2336bde.txt
+++ b/test/snapshots/parser/script_style_test/test_0046_script_tag_with_closing_tag_in_single-line_comment_6cfabe5d024715f9a1a359ead2336bde.txt
@@ -37,7 +37,7 @@ input: |2-
├── @ HTMLCloseTagNode (location: (3:0)-(3:9))
│ ├── errors: (1 error)
│ │ └── @ MissingOpeningTagError (location: (3:0)-(3:9))
- │ │ ├── message: "Found closing tag `` at (3:2) without a matching opening tag."
+ │ │ ├── message: "Found closing tag `` at (3:2) without a matching opening tag in the same scope."
│ │ └── closing_tag: "script" (location: (3:2)-(3:8))
│ │
│ ├── tag_opening: "" (location: (3:0)-(3:2))
diff --git a/test/snapshots/parser/script_style_test/test_0047_script_tag_with_closing_tag_in_multi-line_comment_f31fa6a4dd0f181740b8650c7c0eadba.txt b/test/snapshots/parser/script_style_test/test_0047_script_tag_with_closing_tag_in_multi-line_comment_f31fa6a4dd0f181740b8650c7c0eadba.txt
index 3f73a0114..9e64f2594 100644
--- a/test/snapshots/parser/script_style_test/test_0047_script_tag_with_closing_tag_in_multi-line_comment_f31fa6a4dd0f181740b8650c7c0eadba.txt
+++ b/test/snapshots/parser/script_style_test/test_0047_script_tag_with_closing_tag_in_multi-line_comment_f31fa6a4dd0f181740b8650c7c0eadba.txt
@@ -37,7 +37,7 @@ input: |2-
├── @ HTMLCloseTagNode (location: (3:0)-(3:9))
│ ├── errors: (1 error)
│ │ └── @ MissingOpeningTagError (location: (3:0)-(3:9))
- │ │ ├── message: "Found closing tag `` at (3:2) without a matching opening tag."
+ │ │ ├── message: "Found closing tag `` at (3:2) without a matching opening tag in the same scope."
│ │ └── closing_tag: "script" (location: (3:2)-(3:8))
│ │
│ ├── tag_opening: "" (location: (3:0)-(3:2))
diff --git a/test/snapshots/parser/script_style_test/test_0048_script_tag_with_closing_tag_in_complex_multi-line_comment_740adce7cfe9c265534de5ed0019592a.txt b/test/snapshots/parser/script_style_test/test_0048_script_tag_with_closing_tag_in_complex_multi-line_comment_740adce7cfe9c265534de5ed0019592a.txt
index aac61b698..2e1522c5f 100644
--- a/test/snapshots/parser/script_style_test/test_0048_script_tag_with_closing_tag_in_complex_multi-line_comment_740adce7cfe9c265534de5ed0019592a.txt
+++ b/test/snapshots/parser/script_style_test/test_0048_script_tag_with_closing_tag_in_complex_multi-line_comment_740adce7cfe9c265534de5ed0019592a.txt
@@ -41,7 +41,7 @@ input: |2-
├── @ HTMLCloseTagNode (location: (4:27)-(4:35))
│ ├── errors: (1 error)
│ │ └── @ MissingOpeningTagError (location: (4:27)-(4:35))
- │ │ ├── message: "Found closing tag `` at (4:29) without a matching opening tag."
+ │ │ ├── message: "Found closing tag `` at (4:29) without a matching opening tag in the same scope."
│ │ └── closing_tag: "style" (location: (4:29)-(4:34))
│ │
│ ├── tag_opening: "" (location: (4:27)-(4:29))
@@ -55,7 +55,7 @@ input: |2-
├── @ HTMLCloseTagNode (location: (7:0)-(7:9))
│ ├── errors: (1 error)
│ │ └── @ MissingOpeningTagError (location: (7:0)-(7:9))
- │ │ ├── message: "Found closing tag `` at (7:2) without a matching opening tag."
+ │ │ ├── message: "Found closing tag `` at (7:2) without a matching opening tag in the same scope."
│ │ └── closing_tag: "script" (location: (7:2)-(7:8))
│ │
│ ├── tag_opening: "" (location: (7:0)-(7:2))
diff --git a/test/snapshots/parser/script_style_test/test_0049_script_tag_with_mixed_comments_and_strings_dd4ddc45ba4f6eac82de8f8d0c4f8430.txt b/test/snapshots/parser/script_style_test/test_0049_script_tag_with_mixed_comments_and_strings_dd4ddc45ba4f6eac82de8f8d0c4f8430.txt
index 8ae9a8846..7b693c7d8 100644
--- a/test/snapshots/parser/script_style_test/test_0049_script_tag_with_mixed_comments_and_strings_dd4ddc45ba4f6eac82de8f8d0c4f8430.txt
+++ b/test/snapshots/parser/script_style_test/test_0049_script_tag_with_mixed_comments_and_strings_dd4ddc45ba4f6eac82de8f8d0c4f8430.txt
@@ -41,7 +41,7 @@ input: |2-
├── @ HTMLCloseTagNode (location: (3:25)-(3:34))
│ ├── errors: (1 error)
│ │ └── @ MissingOpeningTagError (location: (3:25)-(3:34))
- │ │ ├── message: "Found closing tag `` at (3:27) without a matching opening tag."
+ │ │ ├── message: "Found closing tag `` at (3:27) without a matching opening tag in the same scope."
│ │ └── closing_tag: "script" (location: (3:27)-(3:33))
│ │
│ ├── tag_opening: "" (location: (3:25)-(3:27))
@@ -55,7 +55,7 @@ input: |2-
├── @ HTMLCloseTagNode (location: (5:10)-(5:19))
│ ├── errors: (1 error)
│ │ └── @ MissingOpeningTagError (location: (5:10)-(5:19))
- │ │ ├── message: "Found closing tag `` at (5:12) without a matching opening tag."
+ │ │ ├── message: "Found closing tag `` at (5:12) without a matching opening tag in the same scope."
│ │ └── closing_tag: "script" (location: (5:12)-(5:18))
│ │
│ ├── tag_opening: "" (location: (5:10)-(5:12))
@@ -69,7 +69,7 @@ input: |2-
├── @ HTMLCloseTagNode (location: (6:30)-(6:39))
│ ├── errors: (1 error)
│ │ └── @ MissingOpeningTagError (location: (6:30)-(6:39))
- │ │ ├── message: "Found closing tag `` at (6:32) without a matching opening tag."
+ │ │ ├── message: "Found closing tag `` at (6:32) without a matching opening tag in the same scope."
│ │ └── closing_tag: "script" (location: (6:32)-(6:38))
│ │
│ ├── tag_opening: "" (location: (6:30)-(6:32))
@@ -83,7 +83,7 @@ input: |2-
├── @ HTMLCloseTagNode (location: (7:0)-(7:9))
│ ├── errors: (1 error)
│ │ └── @ MissingOpeningTagError (location: (7:0)-(7:9))
- │ │ ├── message: "Found closing tag `` at (7:2) without a matching opening tag."
+ │ │ ├── message: "Found closing tag `` at (7:2) without a matching opening tag in the same scope."
│ │ └── closing_tag: "script" (location: (7:2)-(7:8))
│ │
│ ├── tag_opening: "" (location: (7:0)-(7:2))
diff --git a/test/snapshots/parser/script_style_test/test_0052_script_tag_with_complex_multi-line_comment_containing_closing_tag_baba657d4b37767ec99d327b6dec635a.txt b/test/snapshots/parser/script_style_test/test_0052_script_tag_with_complex_multi-line_comment_containing_closing_tag_baba657d4b37767ec99d327b6dec635a.txt
index ff329c2d3..4542de22a 100644
--- a/test/snapshots/parser/script_style_test/test_0052_script_tag_with_complex_multi-line_comment_containing_closing_tag_baba657d4b37767ec99d327b6dec635a.txt
+++ b/test/snapshots/parser/script_style_test/test_0052_script_tag_with_complex_multi-line_comment_containing_closing_tag_baba657d4b37767ec99d327b6dec635a.txt
@@ -39,7 +39,7 @@ input: |2-
├── @ HTMLCloseTagNode (location: (5:0)-(5:9))
│ ├── errors: (1 error)
│ │ └── @ MissingOpeningTagError (location: (5:0)-(5:9))
- │ │ ├── message: "Found closing tag `` at (5:2) without a matching opening tag."
+ │ │ ├── message: "Found closing tag `` at (5:2) without a matching opening tag in the same scope."
│ │ └── closing_tag: "script" (location: (5:2)-(5:8))
│ │
│ ├── tag_opening: "" (location: (5:0)-(5:2))
diff --git a/test/snapshots/parser/script_style_test/test_0053_script_tag_with_template_literal_containing_closing_tag_(multiline)_372da24666282e3c531de3c5a8de44ca.txt b/test/snapshots/parser/script_style_test/test_0053_script_tag_with_template_literal_containing_closing_tag_(multiline)_372da24666282e3c531de3c5a8de44ca.txt
index 943b5f798..c57e4df34 100644
--- a/test/snapshots/parser/script_style_test/test_0053_script_tag_with_template_literal_containing_closing_tag_(multiline)_372da24666282e3c531de3c5a8de44ca.txt
+++ b/test/snapshots/parser/script_style_test/test_0053_script_tag_with_template_literal_containing_closing_tag_(multiline)_372da24666282e3c531de3c5a8de44ca.txt
@@ -37,7 +37,7 @@ input: |2-
├── @ HTMLCloseTagNode (location: (3:0)-(3:9))
│ ├── errors: (1 error)
│ │ └── @ MissingOpeningTagError (location: (3:0)-(3:9))
- │ │ ├── message: "Found closing tag `` at (3:2) without a matching opening tag."
+ │ │ ├── message: "Found closing tag `` at (3:2) without a matching opening tag in the same scope."
│ │ └── closing_tag: "script" (location: (3:2)-(3:8))
│ │
│ ├── tag_opening: "" (location: (3:0)-(3:2))
diff --git a/test/snapshots/parser/svg_test/test_0005_HTML_void_can_be_non-void_within_svg_1072d4c2f81d845d5c1f0fd86e40e23b.txt b/test/snapshots/parser/svg_test/test_0005_HTML_void_can_be_non-void_within_svg_1072d4c2f81d845d5c1f0fd86e40e23b.txt
index c223d4c0b..e928ab734 100644
--- a/test/snapshots/parser/svg_test/test_0005_HTML_void_can_be_non-void_within_svg_1072d4c2f81d845d5c1f0fd86e40e23b.txt
+++ b/test/snapshots/parser/svg_test/test_0005_HTML_void_can_be_non-void_within_svg_1072d4c2f81d845d5c1f0fd86e40e23b.txt
@@ -17,11 +17,11 @@ input: |2-
│ │ └── is_void: false
│ │
│ ├── tag_name: "svg" (location: (1:1)-(1:4))
- │ ├── body: (3 items)
+ │ ├── body: (4 items)
│ │ ├── @ HTMLTextNode (location: (1:5)-(2:2))
│ │ │ └── content: "\n "
│ │ │
- │ │ ├── @ HTMLElementNode (location: (2:2)-(2:11))
+ │ │ ├── @ HTMLElementNode (location: (2:2)-(2:6))
│ │ │ ├── open_tag:
│ │ │ │ └── @ HTMLOpenTagNode (location: (2:2)-(2:6))
│ │ │ │ ├── tag_opening: "<" (location: (2:2)-(2:3))
@@ -32,15 +32,22 @@ input: |2-
│ │ │ │
│ │ │ ├── tag_name: "br" (location: (2:3)-(2:5))
│ │ │ ├── body: []
- │ │ │ ├── close_tag:
- │ │ │ │ └── @ HTMLCloseTagNode (location: (2:6)-(2:11))
- │ │ │ │ ├── tag_opening: "" (location: (2:6)-(2:8))
+ │ │ │ ├── close_tag: ∅
+ │ │ │ ├── is_void: true
+ │ │ │ └── source: "HTML"
+ │ │ │
+ │ │ ├── @ HTMLCloseTagNode (location: (2:6)-(2:11))
+ │ │ │ ├── errors: (1 error)
+ │ │ │ │ └── @ VoidElementClosingTagError (location: (2:6)-(2:11))
+ │ │ │ │ ├── message: "`br` is a void element and should not be used as a closing tag. Use `
` or `
` instead of ``."
│ │ │ │ ├── tag_name: "br" (location: (2:8)-(2:10))
- │ │ │ │ ├── children: []
- │ │ │ │ └── tag_closing: ">" (location: (2:10)-(2:11))
+ │ │ │ │ ├── expected: "
"
+ │ │ │ │ └── found: ""
│ │ │ │
- │ │ │ ├── is_void: false
- │ │ │ └── source: "HTML"
+ │ │ │ ├── tag_opening: "" (location: (2:6)-(2:8))
+ │ │ │ ├── tag_name: "br" (location: (2:8)-(2:10))
+ │ │ │ ├── children: []
+ │ │ │ └── tag_closing: ">" (location: (2:10)-(2:11))
│ │ │
│ │ └── @ HTMLTextNode (location: (2:11)-(3:0))
│ │ └── content: "\n"
diff --git a/test/snapshots/parser/svg_test/test_0006_svg_unclosed_element_reports_an_error_e086a53256a215470da47ef3ee745599.txt b/test/snapshots/parser/svg_test/test_0006_svg_unclosed_element_reports_an_error_e086a53256a215470da47ef3ee745599.txt
index 1e729020c..319e4883b 100644
--- a/test/snapshots/parser/svg_test/test_0006_svg_unclosed_element_reports_an_error_e086a53256a215470da47ef3ee745599.txt
+++ b/test/snapshots/parser/svg_test/test_0006_svg_unclosed_element_reports_an_error_e086a53256a215470da47ef3ee745599.txt
@@ -6,68 +6,45 @@ input: |2-
---
@ DocumentNode (location: (1:0)-(4:0))
-├── errors: (2 errors)
-│ ├── @ UnclosedElementError (location: (4:0)-(4:0))
-│ │ ├── message: "Tag `
` opened at (2:3) was never closed before the end of document."
-│ │ └── opening_tag: "g" (location: (2:3)-(2:4))
-│ │
-│ └── @ UnclosedElementError (location: (4:0)-(4:0))
-│ ├── message: "Tag `` opened at (1:1) was never closed before the end of document."
-│ └── opening_tag: "svg" (location: (1:1)-(1:4))
-│
-└── children: (1 item)
- └── @ HTMLElementNode (location: (1:0)-(1:5))
- ├── errors: (1 error)
- │ └── @ MissingClosingTagError (location: (1:1)-(1:4))
- │ ├── message: "Opening tag `` at (1:1) doesn't have a matching closing tag ` `."
- │ └── opening_tag: "svg" (location: (1:1)-(1:4))
- │
- ├── open_tag:
- │ └── @ HTMLOpenTagNode (location: (1:0)-(1:5))
- │ ├── tag_opening: "<" (location: (1:0)-(1:1))
- │ ├── tag_name: "svg" (location: (1:1)-(1:4))
- │ ├── tag_closing: ">" (location: (1:4)-(1:5))
- │ ├── children: []
- │ └── is_void: false
- │
- ├── tag_name: "svg" (location: (1:1)-(1:4))
- ├── body: (3 items)
- │ ├── @ HTMLTextNode (location: (1:5)-(2:2))
- │ │ └── content: "\n "
- │ │
- │ ├── @ HTMLElementNode (location: (2:2)-(3:6))
- │ │ ├── errors: (1 error)
- │ │ │ └── @ TagNamesMismatchError (location: (3:2)-(3:5))
- │ │ │ ├── message: "Opening tag `` at (2:3) closed with ` ` at (3:2)."
- │ │ │ ├── opening_tag: "g" (location: (2:3)-(2:4))
- │ │ │ └── closing_tag: "svg" (location: (3:2)-(3:5))
- │ │ │
- │ │ ├── open_tag:
- │ │ │ └── @ HTMLOpenTagNode (location: (2:2)-(2:5))
- │ │ │ ├── tag_opening: "<" (location: (2:2)-(2:3))
- │ │ │ ├── tag_name: "g" (location: (2:3)-(2:4))
- │ │ │ ├── tag_closing: ">" (location: (2:4)-(2:5))
- │ │ │ ├── children: []
- │ │ │ └── is_void: false
- │ │ │
- │ │ ├── tag_name: "g" (location: (2:3)-(2:4))
- │ │ ├── body: (1 item)
- │ │ │ └── @ HTMLTextNode (location: (2:5)-(3:0))
- │ │ │ └── content: "\n"
- │ │ │
- │ │ ├── close_tag:
- │ │ │ └── @ HTMLCloseTagNode (location: (3:0)-(3:6))
- │ │ │ ├── tag_opening: "" (location: (3:0)-(3:2))
- │ │ │ ├── tag_name: "svg" (location: (3:2)-(3:5))
- │ │ │ ├── children: []
- │ │ │ └── tag_closing: ">" (location: (3:5)-(3:6))
- │ │ │
- │ │ ├── is_void: false
- │ │ └── source: "HTML"
- │ │
- │ └── @ HTMLTextNode (location: (3:6)-(4:0))
- │ └── content: "\n"
- │
- ├── close_tag: ∅
- ├── is_void: false
- └── source: "HTML"
\ No newline at end of file
+└── children: (2 items)
+ ├── @ HTMLElementNode (location: (1:0)-(3:6))
+ │ ├── open_tag:
+ │ │ └── @ HTMLOpenTagNode (location: (1:0)-(1:5))
+ │ │ ├── tag_opening: "<" (location: (1:0)-(1:1))
+ │ │ ├── tag_name: "svg" (location: (1:1)-(1:4))
+ │ │ ├── tag_closing: ">" (location: (1:4)-(1:5))
+ │ │ ├── children: []
+ │ │ └── is_void: false
+ │ │
+ │ ├── tag_name: "svg" (location: (1:1)-(1:4))
+ │ ├── body: (3 items)
+ │ │ ├── @ HTMLTextNode (location: (1:5)-(2:2))
+ │ │ │ └── content: "\n "
+ │ │ │
+ │ │ ├── @ HTMLOpenTagNode (location: (2:2)-(2:5))
+ │ │ │ ├── errors: (1 error)
+ │ │ │ │ └── @ MissingClosingTagError (location: (2:2)-(2:5))
+ │ │ │ │ ├── message: "Opening tag `` at (2:3) doesn't have a matching closing tag ` ` in the same scope."
+ │ │ │ │ └── opening_tag: "g" (location: (2:3)-(2:4))
+ │ │ │ │
+ │ │ │ ├── tag_opening: "<" (location: (2:2)-(2:3))
+ │ │ │ ├── tag_name: "g" (location: (2:3)-(2:4))
+ │ │ │ ├── tag_closing: ">" (location: (2:4)-(2:5))
+ │ │ │ ├── children: []
+ │ │ │ └── is_void: false
+ │ │ │
+ │ │ └── @ HTMLTextNode (location: (2:5)-(3:0))
+ │ │ └── content: "\n"
+ │ │
+ │ ├── close_tag:
+ │ │ └── @ HTMLCloseTagNode (location: (3:0)-(3:6))
+ │ │ ├── tag_opening: "" (location: (3:0)-(3:2))
+ │ │ ├── tag_name: "svg" (location: (3:2)-(3:5))
+ │ │ ├── children: []
+ │ │ └── tag_closing: ">" (location: (3:5)-(3:6))
+ │ │
+ │ ├── is_void: false
+ │ └── source: "HTML"
+ │
+ └── @ HTMLTextNode (location: (3:6)-(4:0))
+ └── content: "\n"
\ No newline at end of file
diff --git a/test/snapshots/parser/tags_test/test_0008_closing_tag_without_an_opening_tag_for_a_non-void_element_0a3a0b592b9c285e050805307cee87c2.txt b/test/snapshots/parser/tags_test/test_0008_closing_tag_without_an_opening_tag_for_a_non-void_element_0a3a0b592b9c285e050805307cee87c2.txt
index b48bb0f9f..3128430ff 100644
--- a/test/snapshots/parser/tags_test/test_0008_closing_tag_without_an_opening_tag_for_a_non-void_element_0a3a0b592b9c285e050805307cee87c2.txt
+++ b/test/snapshots/parser/tags_test/test_0008_closing_tag_without_an_opening_tag_for_a_non-void_element_0a3a0b592b9c285e050805307cee87c2.txt
@@ -7,7 +7,7 @@ input: " "
└── @ HTMLCloseTagNode (location: (1:0)-(1:6))
├── errors: (1 error)
│ └── @ MissingOpeningTagError (location: (1:0)-(1:6))
- │ ├── message: "Found closing tag `